linked table manager and user permissions

  • Thread starter Thread starter tw
  • Start date Start date
T

tw

I have a need to set up an ini file, which I have done to link tables when
necessary to a different back end data source. I'm having trouble when a
user that does not have full permission logs in the system hangs on linking
the first table and I must close access. Is there a way to hard code
permission to link the tables then revert back to the logged in users
permission levels? Fortunately this is for a future need item, and I have
the system set up so that if the ini file is not present, it will use the
current links. This will soon be necessary however, and I need to resolve
this issue.
 
Show us the code that is causing Access to hang. (And show exactly
where in that code, you say it is hanging.)

TC
 
Here are the code segments...

From the form that calls the procedure...
"frmSplash"
==================
option compare database
option explicit
==================
Private Sub Form_Load()
On Error Resume Next
'Popluate module level variables when form loads.
strVerClient = Nz(DLookup("[VersionNumber]", "[tblVersionClient]", ""))
strVerServer = Nz(DLookup("[VersionNumber]", "[tblVersionServer]", ""))
Me.lblClientVersion.Caption = "Disco Version: " & strVerClient
Me.Repaint
Me.TimerInterval = 1000
If IsUserInGroup("ADMINS", CurrentUser()) Then
If Month(Now()) = 1 And DAY(Now()) <= 14 Then Me.lblArchive.Visible
= True
End If
End Sub
=================
Private Sub Form_timer()
'Sub CheckVersion()
On Error Resume Next
Dim strMSG As String
Dim strPath As String
Dim strUpdateTool As String
Dim strWRKGRP As String

Const q As String * 1 = """"

'if versions match, then proceed with opening of main form.
If strVerClient = strVerServer Then
initProc
'if not, then offer the user the option to download the latest version
Else
strMSG = "You do not have the correct version." & vbCrLf & vbCrLf &
_
"Woul you like to download the latest client?"
If MsgBox(strMSG, vbExclamation + vbOKCancel, "Update") = vbOK Then
strPath = "\\myserver\myprogrampath\Resources\update.mdb"
strWRKGRP = "\\myserver\myprogrampath\DiscoSecure.mdw"
strPath = q & strPath & q & " /WRKGRP " & q & strWRKGRP & q
strUpdateTool = "MSaccess.exe " & strPath

' ... then quit this client so it may be overwritten.
Shell strUpdateTool, vbNormalFocus
DoCmd.Quit
Else
'Don't load new version run current version
initProc
End If
End If
End Sub
==========
Sub initProc()
Me.TimerInterval = 0
Me.lblLoadingMenu.Visible = True
iniRead
Me.lblLoadingMenu.FontSize = 14
Me.lblLoadingMenu.FontWeight = 400
Me.lblLoadingMenu.Caption = "Loading Menus... Please Wait..."
Me.Repaint
DoCmd.OpenForm "frmSwitchboardLoader"
End Sub

======================================
This is the initRead and LinkTables code from same module...
==========
option compare database
option explicit
=========
Sub iniRead()
'read ini file to get initialization data
'call ini procedures to use data read
Dim strData As String
Dim f, ts, s, fs
Dim FoundAt As Integer
Dim iniFile As String

iniFile = CurrentProject.Path & "\Disco.ini"

Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(iniFile) Then
Set f = fs.GetFile(iniFile)
Set ts = f.OpenAsTextStream(1, 0) 'open for reading, ascii
Do While Not ts.atendofstream
ReadLine:
s = ts.ReadLine
If Left(s, 1) = "'" Then
If ts.atendofstream Then
Exit Do
Else
GoTo ReadLine 'skip the rest of this loop and read the
next line this is a comment
End If
End If

'LinkTables
FoundAt = InStr(1, s, "DATASOURCE:")
If FoundAt > 0 Then
strData = Mid(s, FoundAt + 11)
LinkTables (strData)
End If

'Other ini stuff may be added later
Loop
ts.Close
End If

End Sub
=======================
Sub LinkTables(pPath As String)
'connects data to back end table and refreshes links
Dim tdfTable As TableDef
Forms!frmSplash.lblLoadingMenu.FontSize = 8
Forms!frmSplash.lblLoadingMenu.FontWeight = 700
For Each tdfTable In CurrentDb.TableDefs
If Len(tdfTable.Connect) > 1 Then
'inform the user which table is being connected
Forms!frmSplash.lblLoadingMenu.Caption = _
"Connecting to Disco Data on " & pPath & vbCrLf &
tdfTable.Name
Forms!frmSplash.Repaint

tdfTable.Connect = ";DATABASE=" & pPath
tdfTable.RefreshLink
End If
Next
End Sub
==================================
Problem described here...

When I am connected as myself (member of Admin group) all this code works
fine, links all tables, opens switchboard form when finished (switchboard
form closes the splash screen)

When I am connected as one of the users with limited access the splash
screen opens, the timer event fires and initProc is called, initRead is
called, LinkTables is called. Instead of looping through all of the
tabledefs
here For Each tdfTable In CurrentDb.TableDefs
....
it makes the first iteration then exits the loop.
Instead of returning to the initRead to return to initProc to return to the
timer event, it returns to the timer event and stops there. Now I see why
it's doing that because of an error it's getting and it's going to resume
next. I'm going to take out the resume next line and see if it will tell me
what the error is. I'll post back with the details if necessary after I see
what the error is.
 
instead of removing the resume next, I modified the code to goto an error
lable to show error then resume next, and I also added error lables to goto
in the event of errors in the initRead, and LinkTables so that the resume
next will stay within the procedures.

The error occurring is as I suspected. The user logged in when the tables
are trying to link is a permissions error. I do need to temporarily give
administrative permission to relink all the tables, then revert back to the
users level of permission. How do I do that? I through the link that Paul
Overway provided in his post, but was confused as to how it would solve my
problem.


tw said:
Here are the code segments...

From the form that calls the procedure...
"frmSplash"
==================
option compare database
option explicit
==================
Private Sub Form_Load()
On Error Resume Next
'Popluate module level variables when form loads.
strVerClient = Nz(DLookup("[VersionNumber]", "[tblVersionClient]", ""))
strVerServer = Nz(DLookup("[VersionNumber]", "[tblVersionServer]", ""))
Me.lblClientVersion.Caption = "Disco Version: " & strVerClient
Me.Repaint
Me.TimerInterval = 1000
If IsUserInGroup("ADMINS", CurrentUser()) Then
If Month(Now()) = 1 And DAY(Now()) <= 14 Then Me.lblArchive.Visible
= True
End If
End Sub
=================
Private Sub Form_timer()
'Sub CheckVersion()
On Error Resume Next
Dim strMSG As String
Dim strPath As String
Dim strUpdateTool As String
Dim strWRKGRP As String

Const q As String * 1 = """"

'if versions match, then proceed with opening of main form.
If strVerClient = strVerServer Then
initProc
'if not, then offer the user the option to download the latest version
Else
strMSG = "You do not have the correct version." & vbCrLf & vbCrLf &
_
"Woul you like to download the latest client?"
If MsgBox(strMSG, vbExclamation + vbOKCancel, "Update") = vbOK Then
strPath = "\\myserver\myprogrampath\Resources\update.mdb"
strWRKGRP = "\\myserver\myprogrampath\DiscoSecure.mdw"
strPath = q & strPath & q & " /WRKGRP " & q & strWRKGRP & q
strUpdateTool = "MSaccess.exe " & strPath

' ... then quit this client so it may be overwritten.
Shell strUpdateTool, vbNormalFocus
DoCmd.Quit
Else
'Don't load new version run current version
initProc
End If
End If
End Sub
==========
Sub initProc()
Me.TimerInterval = 0
Me.lblLoadingMenu.Visible = True
iniRead
Me.lblLoadingMenu.FontSize = 14
Me.lblLoadingMenu.FontWeight = 400
Me.lblLoadingMenu.Caption = "Loading Menus... Please Wait..."
Me.Repaint
DoCmd.OpenForm "frmSwitchboardLoader"
End Sub

======================================
This is the initRead and LinkTables code from same module...
==========
option compare database
option explicit
=========
Sub iniRead()
'read ini file to get initialization data
'call ini procedures to use data read
Dim strData As String
Dim f, ts, s, fs
Dim FoundAt As Integer
Dim iniFile As String

iniFile = CurrentProject.Path & "\Disco.ini"

Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(iniFile) Then
Set f = fs.GetFile(iniFile)
Set ts = f.OpenAsTextStream(1, 0) 'open for reading, ascii
Do While Not ts.atendofstream
ReadLine:
s = ts.ReadLine
If Left(s, 1) = "'" Then
If ts.atendofstream Then
Exit Do
Else
GoTo ReadLine 'skip the rest of this loop and read the
next line this is a comment
End If
End If

'LinkTables
FoundAt = InStr(1, s, "DATASOURCE:")
If FoundAt > 0 Then
strData = Mid(s, FoundAt + 11)
LinkTables (strData)
End If

'Other ini stuff may be added later
Loop
ts.Close
End If

End Sub
=======================
Sub LinkTables(pPath As String)
'connects data to back end table and refreshes links
Dim tdfTable As TableDef
Forms!frmSplash.lblLoadingMenu.FontSize = 8
Forms!frmSplash.lblLoadingMenu.FontWeight = 700
For Each tdfTable In CurrentDb.TableDefs
If Len(tdfTable.Connect) > 1 Then
'inform the user which table is being connected
Forms!frmSplash.lblLoadingMenu.Caption = _
"Connecting to Disco Data on " & pPath & vbCrLf &
tdfTable.Name
Forms!frmSplash.Repaint

tdfTable.Connect = ";DATABASE=" & pPath
tdfTable.RefreshLink
End If
Next
End Sub
==================================
Problem described here...

When I am connected as myself (member of Admin group) all this code works
fine, links all tables, opens switchboard form when finished (switchboard
form closes the splash screen)

When I am connected as one of the users with limited access the splash
screen opens, the timer event fires and initProc is called, initRead is
called, LinkTables is called. Instead of looping through all of the
tabledefs
here For Each tdfTable In CurrentDb.TableDefs
...
it makes the first iteration then exits the loop.
Instead of returning to the initRead to return to initProc to return to
the timer event, it returns to the timer event and stops there. Now I see
why it's doing that because of an error it's getting and it's going to
resume next. I'm going to take out the resume next line and see if it
will tell me what the error is. I'll post back with the details if
necessary after I see what the error is.


TC said:
Show us the code that is causing Access to hang. (And show exactly
where in that code, you say it is hanging.)

TC
 
By default, Access creates its own DBEngine object and workspace based on
whatever workgroup file and user credentials were provided when it
opens...and then you're basically stuck with those objects and permissions
throughout the session. You are using CurrentDb to read
tabledefs....CurrentDB is derived from the default DBEngine/Workspace....so,
you're stuck with the users permissions you logged in with.

PrivDBEngine allows you to create a new workspace under a different user.
This isn't in the Access documentation, but is documented elsewhere, which
is why I referred you to the link. You'd have to hard code the admin user
and password below...so, hopefully you're distributing an MDE.

Example

'Watch for line wrap...

Dim dbe as New PrivDbEngine
Dim wrk as Workspace
Dim db as database


dbe.SystemDB = "path to workgroup file here"
Set wrk = dbe.CreateWorkspace("SecureWor­kspace","user name here",
"password here")
dbe.Workspaces.Append wrk


Set db = wrk.OpenDatabase(currentdb.nam­e)


'ok....relink tables or do whatever now using objects derived from db as
set above


You could also do this in script or a separate process (EXE, MDE)...and then
have the other process open your app normally after the tables are relinked.
I only mention this because it appears you're running update.mdb to install
updates. The updater could also relink the tables.

--
Paul Overway
Logico Solutions
http://www.logico-solutions.com



tw said:
instead of removing the resume next, I modified the code to goto an error
lable to show error then resume next, and I also added error lables to
goto in the event of errors in the initRead, and LinkTables so that the
resume next will stay within the procedures.

The error occurring is as I suspected. The user logged in when the tables
are trying to link is a permissions error. I do need to temporarily give
administrative permission to relink all the tables, then revert back to
the users level of permission. How do I do that? I through the link that
Paul Overway provided in his post, but was confused as to how it would
solve my problem.


tw said:
Here are the code segments...

From the form that calls the procedure...
"frmSplash"
==================
option compare database
option explicit
==================
Private Sub Form_Load()
On Error Resume Next
'Popluate module level variables when form loads.
strVerClient = Nz(DLookup("[VersionNumber]", "[tblVersionClient]",
""))
strVerServer = Nz(DLookup("[VersionNumber]", "[tblVersionServer]",
""))
Me.lblClientVersion.Caption = "Disco Version: " & strVerClient
Me.Repaint
Me.TimerInterval = 1000
If IsUserInGroup("ADMINS", CurrentUser()) Then
If Month(Now()) = 1 And DAY(Now()) <= 14 Then
Me.lblArchive.Visible = True
End If
End Sub
=================
Private Sub Form_timer()
'Sub CheckVersion()
On Error Resume Next
Dim strMSG As String
Dim strPath As String
Dim strUpdateTool As String
Dim strWRKGRP As String

Const q As String * 1 = """"

'if versions match, then proceed with opening of main form.
If strVerClient = strVerServer Then
initProc
'if not, then offer the user the option to download the latest version
Else
strMSG = "You do not have the correct version." & vbCrLf & vbCrLf
& _
"Woul you like to download the latest client?"
If MsgBox(strMSG, vbExclamation + vbOKCancel, "Update") = vbOK
Then
strPath = "\\myserver\myprogrampath\Resources\update.mdb"
strWRKGRP = "\\myserver\myprogrampath\DiscoSecure.mdw"
strPath = q & strPath & q & " /WRKGRP " & q & strWRKGRP & q
strUpdateTool = "MSaccess.exe " & strPath

' ... then quit this client so it may be overwritten.
Shell strUpdateTool, vbNormalFocus
DoCmd.Quit
Else
'Don't load new version run current version
initProc
End If
End If
End Sub
==========
Sub initProc()
Me.TimerInterval = 0
Me.lblLoadingMenu.Visible = True
iniRead
Me.lblLoadingMenu.FontSize = 14
Me.lblLoadingMenu.FontWeight = 400
Me.lblLoadingMenu.Caption = "Loading Menus... Please Wait..."
Me.Repaint
DoCmd.OpenForm "frmSwitchboardLoader"
End Sub

======================================
This is the initRead and LinkTables code from same module...
==========
option compare database
option explicit
=========
Sub iniRead()
'read ini file to get initialization data
'call ini procedures to use data read
Dim strData As String
Dim f, ts, s, fs
Dim FoundAt As Integer
Dim iniFile As String

iniFile = CurrentProject.Path & "\Disco.ini"

Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(iniFile) Then
Set f = fs.GetFile(iniFile)
Set ts = f.OpenAsTextStream(1, 0) 'open for reading, ascii
Do While Not ts.atendofstream
ReadLine:
s = ts.ReadLine
If Left(s, 1) = "'" Then
If ts.atendofstream Then
Exit Do
Else
GoTo ReadLine 'skip the rest of this loop and read the
next line this is a comment
End If
End If

'LinkTables
FoundAt = InStr(1, s, "DATASOURCE:")
If FoundAt > 0 Then
strData = Mid(s, FoundAt + 11)
LinkTables (strData)
End If

'Other ini stuff may be added later
Loop
ts.Close
End If

End Sub
=======================
Sub LinkTables(pPath As String)
'connects data to back end table and refreshes links
Dim tdfTable As TableDef
Forms!frmSplash.lblLoadingMenu.FontSize = 8
Forms!frmSplash.lblLoadingMenu.FontWeight = 700
For Each tdfTable In CurrentDb.TableDefs
If Len(tdfTable.Connect) > 1 Then
'inform the user which table is being connected
Forms!frmSplash.lblLoadingMenu.Caption = _
"Connecting to Disco Data on " & pPath & vbCrLf &
tdfTable.Name
Forms!frmSplash.Repaint

tdfTable.Connect = ";DATABASE=" & pPath
tdfTable.RefreshLink
End If
Next
End Sub
==================================
Problem described here...

When I am connected as myself (member of Admin group) all this code works
fine, links all tables, opens switchboard form when finished (switchboard
form closes the splash screen)

When I am connected as one of the users with limited access the splash
screen opens, the timer event fires and initProc is called, initRead is
called, LinkTables is called. Instead of looping through all of the
tabledefs
here For Each tdfTable In CurrentDb.TableDefs
...
it makes the first iteration then exits the loop.
Instead of returning to the initRead to return to initProc to return to
the timer event, it returns to the timer event and stops there. Now I
see why it's doing that because of an error it's getting and it's going
to resume next. I'm going to take out the resume next line and see if it
will tell me what the error is. I'll post back with the details if
necessary after I see what the error is.


TC said:
Show us the code that is causing Access to hang. (And show exactly
where in that code, you say it is hanging.)

TC
 
got it... thanks

Paul Overway said:
By default, Access creates its own DBEngine object and workspace based on
whatever workgroup file and user credentials were provided when it
opens...and then you're basically stuck with those objects and permissions
throughout the session. You are using CurrentDb to read
tabledefs....CurrentDB is derived from the default
DBEngine/Workspace....so, you're stuck with the users permissions you
logged in with.

PrivDBEngine allows you to create a new workspace under a different user.
This isn't in the Access documentation, but is documented elsewhere, which
is why I referred you to the link. You'd have to hard code the admin user
and password below...so, hopefully you're distributing an MDE.

Example

'Watch for line wrap...

Dim dbe as New PrivDbEngine
Dim wrk as Workspace
Dim db as database


dbe.SystemDB = "path to workgroup file here"
Set wrk = dbe.CreateWorkspace("SecureWor­kspace","user name here",
"password here")
dbe.Workspaces.Append wrk


Set db = wrk.OpenDatabase(currentdb.nam­e)


'ok....relink tables or do whatever now using objects derived from db
as set above


You could also do this in script or a separate process (EXE, MDE)...and
then have the other process open your app normally after the tables are
relinked. I only mention this because it appears you're running update.mdb
to install updates. The updater could also relink the tables.

--
Paul Overway
Logico Solutions
http://www.logico-solutions.com



tw said:
instead of removing the resume next, I modified the code to goto an error
lable to show error then resume next, and I also added error lables to
goto in the event of errors in the initRead, and LinkTables so that the
resume next will stay within the procedures.

The error occurring is as I suspected. The user logged in when the
tables are trying to link is a permissions error. I do need to
temporarily give administrative permission to relink all the tables, then
revert back to the users level of permission. How do I do that? I
through the link that Paul Overway provided in his post, but was confused
as to how it would solve my problem.


tw said:
Here are the code segments...

From the form that calls the procedure...
"frmSplash"
==================
option compare database
option explicit
==================
Private Sub Form_Load()
On Error Resume Next
'Popluate module level variables when form loads.
strVerClient = Nz(DLookup("[VersionNumber]", "[tblVersionClient]",
""))
strVerServer = Nz(DLookup("[VersionNumber]", "[tblVersionServer]",
""))
Me.lblClientVersion.Caption = "Disco Version: " & strVerClient
Me.Repaint
Me.TimerInterval = 1000
If IsUserInGroup("ADMINS", CurrentUser()) Then
If Month(Now()) = 1 And DAY(Now()) <= 14 Then
Me.lblArchive.Visible = True
End If
End Sub
=================
Private Sub Form_timer()
'Sub CheckVersion()
On Error Resume Next
Dim strMSG As String
Dim strPath As String
Dim strUpdateTool As String
Dim strWRKGRP As String

Const q As String * 1 = """"

'if versions match, then proceed with opening of main form.
If strVerClient = strVerServer Then
initProc
'if not, then offer the user the option to download the latest
version
Else
strMSG = "You do not have the correct version." & vbCrLf & vbCrLf
& _
"Woul you like to download the latest client?"
If MsgBox(strMSG, vbExclamation + vbOKCancel, "Update") = vbOK
Then
strPath = "\\myserver\myprogrampath\Resources\update.mdb"
strWRKGRP = "\\myserver\myprogrampath\DiscoSecure.mdw"
strPath = q & strPath & q & " /WRKGRP " & q & strWRKGRP & q
strUpdateTool = "MSaccess.exe " & strPath

' ... then quit this client so it may be overwritten.
Shell strUpdateTool, vbNormalFocus
DoCmd.Quit
Else
'Don't load new version run current version
initProc
End If
End If
End Sub
==========
Sub initProc()
Me.TimerInterval = 0
Me.lblLoadingMenu.Visible = True
iniRead
Me.lblLoadingMenu.FontSize = 14
Me.lblLoadingMenu.FontWeight = 400
Me.lblLoadingMenu.Caption = "Loading Menus... Please Wait..."
Me.Repaint
DoCmd.OpenForm "frmSwitchboardLoader"
End Sub

======================================
This is the initRead and LinkTables code from same module...
==========
option compare database
option explicit
=========
Sub iniRead()
'read ini file to get initialization data
'call ini procedures to use data read
Dim strData As String
Dim f, ts, s, fs
Dim FoundAt As Integer
Dim iniFile As String

iniFile = CurrentProject.Path & "\Disco.ini"

Set fs = CreateObject("Scripting.FileSystemObject")
If fs.FileExists(iniFile) Then
Set f = fs.GetFile(iniFile)
Set ts = f.OpenAsTextStream(1, 0) 'open for reading, ascii
Do While Not ts.atendofstream
ReadLine:
s = ts.ReadLine
If Left(s, 1) = "'" Then
If ts.atendofstream Then
Exit Do
Else
GoTo ReadLine 'skip the rest of this loop and read
the next line this is a comment
End If
End If

'LinkTables
FoundAt = InStr(1, s, "DATASOURCE:")
If FoundAt > 0 Then
strData = Mid(s, FoundAt + 11)
LinkTables (strData)
End If

'Other ini stuff may be added later
Loop
ts.Close
End If

End Sub
=======================
Sub LinkTables(pPath As String)
'connects data to back end table and refreshes links
Dim tdfTable As TableDef
Forms!frmSplash.lblLoadingMenu.FontSize = 8
Forms!frmSplash.lblLoadingMenu.FontWeight = 700
For Each tdfTable In CurrentDb.TableDefs
If Len(tdfTable.Connect) > 1 Then
'inform the user which table is being connected
Forms!frmSplash.lblLoadingMenu.Caption = _
"Connecting to Disco Data on " & pPath & vbCrLf &
tdfTable.Name
Forms!frmSplash.Repaint

tdfTable.Connect = ";DATABASE=" & pPath
tdfTable.RefreshLink
End If
Next
End Sub
==================================
Problem described here...

When I am connected as myself (member of Admin group) all this code
works fine, links all tables, opens switchboard form when finished
(switchboard form closes the splash screen)

When I am connected as one of the users with limited access the splash
screen opens, the timer event fires and initProc is called, initRead is
called, LinkTables is called. Instead of looping through all of the
tabledefs
here For Each tdfTable In CurrentDb.TableDefs
...
it makes the first iteration then exits the loop.
Instead of returning to the initRead to return to initProc to return to
the timer event, it returns to the timer event and stops there. Now I
see why it's doing that because of an error it's getting and it's going
to resume next. I'm going to take out the resume next line and see if
it will tell me what the error is. I'll post back with the details if
necessary after I see what the error is.


Show us the code that is causing Access to hang. (And show exactly
where in that code, you say it is hanging.)

TC
 
Ok, well done. Sorry I didn't answer before. I only get on the web
once, or rarely twice, per day.

Cheers,
TC
 
Back
Top