Expert guide

Relink Microsoft Access Tables with VBA

Never send users to the Linked Table Manager again

Short answer: at startup, test one linked table; if it fails or points to the wrong place, loop through CurrentDb.TableDefs, set each linked table's Connect property to the correct back end (";DATABASE=\\server\path\BE.accdb" for Access, an ODBC string for SQL Server) and call RefreshLink. Store the target in a local settings table so you can switch between development and production. If the back end cannot be found, let an administrator browse to it. We build this into every front end through Access VBA development.

Broken links are one of the most common support calls for split Access databases: IT moves the file server, a new PC has a different drive mapping, or a developer forgets to point the front end back at production after testing. Each time, someone opens the Linked Table Manager on every PC. A short VBA routine makes the front end fix itself.

How Links Are Stored

Back endConnect property looks like
Access file;DATABASE=\\fileserver\Data\Ops_BE.accdb
Access file with passwordMS Access;PWD=secret;DATABASE=\\fileserver\Data\Ops_BE.accdb
SQL Server (DSN-less)ODBC;DRIVER={ODBC Driver 18 for SQL Server};SERVER=sql01;DATABASE=Ops;Trusted_Connection=Yes;
SQL Server via DSNODBC;DSN=OpsDSN;DATABASE=Ops;

Relinking to an Access Back End

Public Function RelinkAccessTables(ByVal backEndPath As String) As Boolean
    Dim db As DAO.Database, td As DAO.TableDef
    Dim newConnect As String, failed As String

    If Dir(backEndPath) = "" Then
        MsgBox "Back end not found: " & backEndPath, vbExclamation
        Exit Function
    End If

    newConnect = ";DATABASE=" & backEndPath
    Set db = CurrentDb
    For Each td In db.TableDefs
        ' Only Access-linked tables (skip local and ODBC tables)
        If Len(td.Connect) > 0 And InStr(1, td.Connect, "DATABASE=", vbTextCompare) > 0 _
           And Left$(td.Connect, 5) <> "ODBC;" Then
            If td.Connect <> newConnect Then
                td.Connect = newConnect
                On Error Resume Next
                td.RefreshLink
                If Err.Number <> 0 Then failed = failed & td.Name & " (" & Err.Description & ")" & vbCrLf
                On Error GoTo 0
            End If
        End If
    Next td

    If Len(failed) > 0 Then
        MsgBox "Could not relink:" & vbCrLf & failed, vbExclamation
    Else
        RelinkAccessTables = True
    End If
End Function

Checking Links at Startup

Public Function EnsureLinks() As Boolean
    Dim target As String
    target = Nz(DLookup("BackEndPath", "tblLocalSettings"), "")   ' local table in the FE

    On Error Resume Next
    Dim n As Long: n = DCount("*", "tblCustomers")                  ' any small linked table
    If Err.Number = 0 And InStr(1, CurrentDb.TableDefs("tblCustomers").Connect, _
                                target, vbTextCompare) > 0 Then
        EnsureLinks = True: Exit Function
    End If
    On Error GoTo 0

    If Len(target) = 0 Or Dir(target) = "" Then target = BrowseForBackEnd()
    If Len(target) = 0 Then Exit Function
    If RelinkAccessTables(target) Then
        CurrentDb.Execute "UPDATE tblLocalSettings SET BackEndPath='" & _
                          Replace(target, "'", "''") & "'", dbFailOnError
        EnsureLinks = True
    End If
End Function

Private Function BrowseForBackEnd() As String
    With Application.FileDialog(3)                  ' msoFileDialogFilePicker
        .Title = "Locate the database back end"
        .Filters.Clear
        .Filters.Add "Access database", "*.accdb; *.mdb"
        If .Show Then BrowseForBackEnd = .SelectedItems(1)
    End With
End Function

Call EnsureLinks from an AutoExec macro (RunCode) or the startup form's Open event, before any form that uses linked tables opens. Checking one small table is fast; relinking only happens when needed.

Relinking to SQL Server (DSN-less)

Public Sub RelinkSqlTables(ByVal server As String, ByVal database As String)
    Dim td As DAO.TableDef, cn As String
    cn = "ODBC;DRIVER={ODBC Driver 18 for SQL Server};SERVER=" & server & _
         ";DATABASE=" & database & ";Trusted_Connection=Yes;Encrypt=Yes;"
    For Each td In CurrentDb.TableDefs
        If Left$(td.Connect, 5) = "ODBC;" Then
            td.Connect = cn
            td.RefreshLink
        End If
    Next td
End Sub

RefreshLink keeps the table's SourceTableName (for example dbo.Customers). If the server schema changed, such as new columns, RefreshLink also updates the local definition. For ODBC errors during relinking, see ODBC--call failed.

Development, Test and Production

  • Keep the target path or server in tblLocalSettings, with an Environment field (DEV, TEST, PROD).

  • Show the environment in the title bar or a coloured banner so nobody edits production thinking it is test.

  • Before creating the release .accde, run the relink to PROD in a build step.

  • Never let a front end silently fall back to a local copy of the back end.

Common Problems

ProblemFix
Relink works for you but not usersYou used a mapped drive; use the UNC path
Error 3044 'not a valid path'Path is wrong or user lacks folder permission
Some tables fail to relinkTable renamed or removed in the back end
Relink is slowMany tables over a slow link; relink only when the Connect string differs
SQL relink prompts for loginMissing credentials or Trusted_Connection; check driver name

Relinking is part of a well-run split database; see how to split an Access database, including automatic front-end updates.

FAQ

Relinking Access tables FAQ

Access and SQL Server back ends

Loop through CurrentDb.TableDefs, and for each table with a non-empty Connect property, set Connect to the new connection string (';DATABASE=\\server\path\Backend.accdb' for Access, or an ODBC string for SQL Server) and call RefreshLink. Run it at startup when the current links are invalid.

The back end moved to a new server or folder, links were stored with a mapped drive letter that differs on another PC, the back end was renamed, the SQL Server name or database changed, or a table was renamed or its structure changed on the server.

Yes. Set each linked table's Connect property to a full ODBC connection string starting with 'ODBC;DRIVER={ODBC Driver 18 for SQL Server};SERVER=...;DATABASE=...;' and call RefreshLink. No DSN needs to exist on the user's PC.

If the expected back end is not found, show Application.FileDialog(msoFileDialogFilePicker) so the user (or an administrator) can browse to the back-end file, save the chosen path in a local settings table, and relink to it.

For one-off changes on your own PC, yes. For a front end distributed to many users, or when development and production back ends differ, a VBA relink routine that runs automatically is far more reliable.