[AccessD] relinking

Heenan, Lambert Lambert.Heenan at chartisinsurance.com
Fri Aug 28 14:59:14 CDT 2009


Jim,

FWIW here is the code I use.  Note that I have commented out the function fGetMDBName as it uses a class module to display a file selection dialog. Replace with your own favorite routine.

This routine makes use of a table, that is local to the front end, called "USYS_LinkedTables_tbl". It has the following structure...

ID: Autonumber
strTableName: Text (255) ' full name of each linked table
strBackEndPath: Text (255) ' full path to production version of the back end(s), including mdb file name
strBackEndPath: Text (255) ' full path to development versions of the back end(s), including mdb file name

So to re-link to the production data (which may include any number of different back-ends) call the function like this...

strResult = fRefreshLinks("Production")

HTH

Lambert

'Code Starts
'======================================

Option Compare Database
Option Explicit

Function fRefreshLinks(strLinkTarget As String) As String

      ' returns an empty string on success or a string with error messages

      Dim collTbls As Collection          ' a collection of table names and connection strings, some tagged as non-access
      Dim i As Integer                    ' loop counter
      Dim strDBPath As String       '
      Dim strTbl As String
      Dim dbCurr As DAO.Database
      Dim dbLink As DAO.Database
      Dim tdfLocal As TableDef
      Dim strTableAlias As String
      Dim varRet As Variant
      Dim strNewPath As String
      Dim strCriteria As String
      Dim rsLinks As DAO.Recordset
      Dim db As DAO.Database
      Dim bLiveData As Boolean
      Dim strReturnValue As String
      Const cERR_USERCANCEL = vbObjectError + 1
      Const cERR_NOREMOTETABLE = vbObjectError + 2
      Const cERR_TABLE_LINK_NOTFOUND = vbObjectError + 3

10        On Local Error GoTo fRefreshLinks_Err


          'First get all linked tables in a collection
20        Set collTbls = fGetLinkedTables
30        Set db = CurrentDb
40        Set rsLinks = db.OpenRecordset("USYS_LinkedTables_tbl")
          'now link all of them
50        Set dbCurr = CurrentDb
60        If strLinkTarget = "Production" Then
70            bLiveData = True
80        Else
90            bLiveData = False
100       End If

110       For i = collTbls.Count To 1 Step -1
120           strDBPath = fParsePath(collTbls(i))
130           strTbl = fParseTable(collTbls(i))
140           strTableAlias = Nz(Field(collTbls(i), "@", 3), "")

150           varRet = SysCmd(acSysCmdSetStatus, "Now linking '" & strTbl & "'....")
160           If strTableAlias > "" Then
170               strCriteria = "strTableName='" & strTableAlias & "'"
180           Else
190               strCriteria = "strTableName='" & strTbl & "'"
200           End If
210           With rsLinks
220               .FindFirst strCriteria
230               If Not .NoMatch Then
240                   strNewPath = IIf(bLiveData, !strBackEndPath, !strDevBackEndPath)    ' get our path, Live or Dev data
250               Else
260                   strNewPath = vbNullString
270                   Err.Raise cERR_TABLE_LINK_NOTFOUND
280               End If
290           End With
300           If Left$(strDBPath, 4) = "ODBC" Then
                  'ODBC Tables
                  'ODBC Tables not being handled by this code
310           Else
320               If strNewPath <> vbNullString Then
                      'Try this first
330                   strDBPath = strNewPath
340               Else
350                   If Len(Dir(strDBPath)) = 0 Then
                          'File Doesn't Exist, call GetOpenFileName
360                       strDBPath = fGetMDBName("'" & strDBPath & "' not found.")
370                       If strDBPath = vbNullString Then
                              'user pressed cancel
380                           Err.Raise cERR_USERCANCEL
390                       End If
400                   End If
410               End If

420               Set dbLink = DBEngine(0).OpenDatabase(strDBPath)

                  'check to see if the table is present in dbLink
430               strTbl = fParseTable(collTbls(i))
440               If fIsRemoteTable(dbLink, strTbl) Then

                      'everything's ok, reconnect
450                   If strTableAlias > "" Then
460                       Set tdfLocal = dbCurr.TableDefs(strTableAlias)
470                   Else
480                       Set tdfLocal = dbCurr.TableDefs(strTbl)
490                   End If
500                   With tdfLocal
510                       .Connect = ";Database=" & strDBPath
520                       .RefreshLink
530                       collTbls.Remove (.Name)
540                   End With
550               Else
560                   Err.Raise cERR_NOREMOTETABLE
570               End If
580           End If
590       Next
600       Set db = Nothing
610       Set rsLinks = Nothing

620       If Not strReturnValue > "" Then
630           strReturnValue = "All Access tables were successfully reconnected."
640       End If
fRefreshLinks_End:
650       varRet = SysCmd(acSysCmdClearStatus)
660       Set collTbls = Nothing
670       Set tdfLocal = Nothing
680       Set dbLink = Nothing
690       Set dbCurr = Nothing
700       fRefreshLinks = strReturnValue
710       Exit Function
fRefreshLinks_Err:
720       fRefreshLinks = False
730       Select Case Err
          Case 3059:

740       Case cERR_USERCANCEL:
750           strReturnValue = strReturnValue & "No Database was specified, couldn't link tables." & vbCrLf
760           Resume fRefreshLinks_End
770       Case cERR_NOREMOTETABLE:
780           strReturnValue = strReturnValue & "Table '" & strTbl & "' was not found in the Database " & dbLink.Name & vbCrLf
790           Resume Next
800       Case cERR_TABLE_LINK_NOTFOUND
810           strReturnValue = strReturnValue & "Link to " & strTbl & " not found in master table USYS_LinkedTables_tbl." & vbCrLf
820           Resume Next
830       Case Else:
840           strReturnValue = strReturnValue & "Error Information..." & vbCrLf & vbCrLf _
                               & "Function: fRefreshLinks" & vbCrLf _
                               & "Description: " & Err.Description & vbCrLf _
                               & "Error #: " & Format$(Err.Number) & vbCrLf & "ERL=" & Erl & vbCrLf
850           Resume Next
860       End Select
End Function

Function fIsRemoteTable(dbRemote As DAO.Database, strTbl As String) As Boolean
Dim tdf As TableDef
10  On Error Resume Next
20  Set tdf = dbRemote.TableDefs(strTbl)
30  fIsRemoteTable = (Err = 0)
40  Set tdf = Nothing
End Function

Function fGetMDBName(strIn As String) As String
'Calls GetOpenFileName dialog
'Dim fDlg As New clsCommonDialogs
'10  With fDlg
'20      .AddFilterItem "Access Database(*.mdb;*.mda;*.mde;*.mdw) ", "*.mdb; *.mda; *.mde; *.mdw"
'30      .AddFilterItem "All Files (*.*)", "*.*"
'40      fGetMDBName = Nz(.GetOpenFile(, strIn), "")
'50  End With

End Function

Function fGetLinkedTables() As Collection
'Returns all linked tables
Dim collTables As New Collection
Dim tdf As TableDef, db As DAO.Database
10  Set db = CurrentDb
20  db.TableDefs.Refresh
30  For Each tdf In db.TableDefs
40      With tdf
50          If Len(.Connect) > 0 Then
60              If Left$(.Connect, 4) = "ODBC" Then
                    '    collTables.Add Item:=.Name & ";" & .Connect, KEY:=.Name
                    'ODBC Reconnect handled separately
70              Else
80                  If .Name <> .SourceTableName Then
90                      collTables.Add Item:=.SourceTableName & .Connect & "@ALIAS@" & .Name, Key:=.Name
100                 Else
110                     collTables.Add Item:=.Name & .Connect, Key:=.Name
120                 End If
130             End If
140         End If
150     End With
160 Next
170 Set fGetLinkedTables = collTables
180 Set collTables = Nothing
190 Set tdf = Nothing
200 Set db = Nothing
End Function

Function fParsePath(strIn As String) As String
Dim strTmp As String
10  If Left$(strIn, 4) <> "ODBC" Then
20      strTmp = Right(strIn, Len(strIn) _
                              - (InStr(1, strIn, "Database=") + 8))
30      If InStr(strTmp, "@") > 0 Then
40          strTmp = Field(strTmp, "@", 1)
50      End If
60      fParsePath = strTmp
70  Else
80      fParsePath = strIn
90  End If
End Function

Function fParseTable(strIn As String) As String
10  fParseTable = Left$(strIn, InStr(1, strIn, ";") - 1)
End Function
'***************** Code End ***************



Function Field(ByVal strSource As String, strSep As String, intN As Integer) As Variant
'Purpose:
'   Returns the Nth element in a delimited list.
'   Input: strSource - the list to search
'             strSep - the delimiter of the list - can be more than one character
'             intN - the ordinal value of the element to be returned
'
' Null is returned if either string parameter is null, or intN <=0 or
' If the separator string is not found
'
'Str = Field("Chuck*Roberts","*",1) would return "Chuck".
Dim strResult As String
Dim strSearch As String
Dim i As Long
Dim lSep As Long

    lSep = 0: i = 0
    If IsNull(strSource) Or strSource = "" Or IsNull(strSep) Or strSep = "" Or intN <= 0 Then
        strResult = ""
    Else
        strSearch = strSource
        While i < intN
            lSep = InStr(strSearch, strSep)
            If lSep > 0 Then    ' we found the delimiter string
                i = i + 1    ' count occurance
                If i = intN Then    ' this is the one we want
                    strResult = Left$(strSearch, lSep - 1)
                End If
                ' strip off i'th field
                strSearch = Right(strSearch, Len(strSearch) - (lSep + Len(strSep) - 1))
            Else    ' did not find our separator string, so return the remainer of the string if the count is ok
                If i = intN - 1 Then    '  we have seen N-1 separator strings, so this is the field we want
                    ' at the end of the search string
                    i = i + 1    ' to terminate the While loop
                    strResult = strSearch
                Else    ' there were less than N-1 fields in the input to return Null
                    strResult = ""
                    i = intN
                End If
            End If
        Wend
    End If
    If strResult = "" Then
        Field = Null
    Else
        Field = strResult
    End If
End Function

' Code ends
'================================================




More information about the AccessD mailing list