How can a relative path specify a linked table in Access 2007? - ms-access

I have a front end and back end of an Access database. The front end references linked tables and I need to do a relative link instead of an explicit one i.e. "../database" is referenced instead of "address/database"
Is it possible to do this, or must I specify the absolute path?

Tables linked to files (such as mdb, accdb, dbf, etc.) require absolute paths in their connection strings.
However there is a workaround: during the database startup you can use vba to redefine the the links to match the directory of the current database instance.
(The code below has not been tested / debugged)
Private Sub RelinkTables()
Dim oldConnection As String
Dim newConnection As String
Dim currentPath As String
currentPath = CurrentProject.Path
Dim tblDef As TableDef
For Each tblDef In CurrentDb.TableDefs
oldConnection = tblDef.Connect
' Depending on the type of linked table
' some string manipulation which defines
' newConnection = someFunction(oldConnection,currentPath)
tblDef.Connect = newConnection
tblDef.RefreshLink
Next tblDef
End Sub

I have tried some of the answers above, especially the answer of Martin Thompson which I got some errors with, and thus modified it as follows:
Public Function reLinkTables() As Boolean
On Error GoTo ErrorRoutine
Dim sMyConnectString As String
Dim tdf As TableDef
Dim db_name As String
' The Main Answer is by Martin Thompson
' Modified by Dr. Mohammad Elnesr
'We will link all linked tables to an accdb Access file located in the same folder as this file.
'Replace the DATA file name in the following statement with the name of your DATA file:
sMyConnectString = ";DATABASE=" & CurrentProject.Path & "\"
For Each tdf In CurrentDb.TableDefs
If Len(tdf.Connect) > 0 Then
'It's a linked table, so re-link:
'First, get the database name
db_name = GetFileName(tdf.Connect)
' Then link the table to the current path
tdf.Connect = sMyConnectString & db_name
tdf.RefreshLink
End If
Next tdf
ExitRoutine:
MsgBox "All tables were relinked successfully"
Exit Function
ErrorRoutine:
MsgBox "Error in gbLinkTables: " & Err.Number & ": " & Err.Description
Resume ExitRoutine
End Function
Function GetFileName(FullPath As String) As String
Dim splitList As Variant
splitList = VBA.Split(FullPath, "\")
GetFileName = splitList(UBound(splitList, 1))
End Function
After fininshing this, Goto Access Ribon>Create>Macro From the dropdown select "RunCode", then in the function name type "reLinkTables" which we typed here. Then save the macro with the name "AutoExec". Every time you open the database, all the linked tables will be relinked to the original path. This is very useful if you put your databases in a portable media.

As far as I know, your TableDef's Connect property requires an absolute path. If I'm wrong on that point, I hope someone will tell how to create a linked table using a relative path.
Take a look at Armen Stein's free utility to manage your table links: J Street Access Relinker

Here is a simple routine that worked for me:
Public Function gbLinkTables() As Boolean
On Error GoTo ErrorRoutine
Dim sMyConnectString As String
Dim tdf As TableDef
'We will link all linked tables to an accdb Access file located in the same folder as this file.
'Replace the DATA file name in the following statement with the name of your DATA file:
sMyConnectString = ";database=" & CurrentProject.Path & "\Loan-Tracking-Data.accdb"
For Each tdf In CurrentDb.TableDefs
If Len(tdf.Connect) > 0 Then
'It's a linked table, so re-link:
tdf.Connect = sMyConnectString
tdf.RefreshLink
End If
Next tdf
ExitRoutine:
Exit Function
ErrorRoutine:
MsgBox "Error in gbLinkTables: " & Err.Number & ": " & Err.Description
Resume ExitRoutine
End Function

The following code has been tested in the Form_Load event of the form listed in the "Display Form" option for the database; that is the form that loads whenever the database is opened. This code could also be called from the AutoExec macro for the database:
Private Sub Form_Load()
Dim strOldConnect As String
Dim strNewConnect As String
Dim intSlashLoc As Integer
Dim intEqualLoc As Integer
Dim strConnect As String
Dim strFile As String
Dim strCurrentPath As String
strCurrentPath = CurrentProject.path
Dim tblDef As TableDef
Dim tblPrp As Property
For Each tblDef In CurrentDb.TableDefs
Debug.Print tblDef.Name
If tblDef.Connect & "." <> "." Then
strOldConnect = tblDef.Connect
intEqualLoc = InStr(1, strOldConnect, "=", vbTextCompare)
strConnect = Left(strOldConnect, intEqualLoc)
intSlashLoc = InStrRev(strOldConnect, "\", -1, vbTextCompare)
strFile = Right(strOldConnect, Len(strOldConnect) - intSlashLoc)
strNewConnect = strConnect & strCurrentPath & "\" & strFile
tblDef.Connect = strNewConnect
tblDef.RefreshLink
End If
Next tblDef
End Sub

you can make a "calculated" field.. works for me in Office Access 2016
"F:\Komponenten\Datenbank\Bilder\" & [Kategorie] & "\Pinout\" & [Bezeichnung] & ".jpg"
maybe there are better solutions, see images
calculated path
result

Related

MS Access Linked Table Manager doesn't update new data source

I have an MS Access 2010 Database that has a table that is linked to a CSV file. Upating the CSV files location using the inbuilt Access "Linked Table Manager" doesn't work.
I check the file i want to update, choose "always prompt for new location" and select the new file. I get a message telling me that the update was successful, but when I go to check, the table is still linked to the old file.
Is this a MS Access bug and if so what is the most efficient workaround?
I ended up deleting the old table and manually recreating a new table with the same specifications.
*Updated: -- I forgot to include the referenced Function Relink_CSV :(
Yes, I would call it a bug. Microsoft probably calls it a 'design characteristic'.
As you have discovered, you can manually fix the issue. If you are interested in a code solution, then I may have something that will work for you -- if your CSV file is delimited by comma's.
The following code (which you need to modify!) will delete the existing linked csv file, then add a link to the same file. For debugging, my code then deletes that link and adds a link to a different file name, but in the same folder.
There are other solutions that make use of a saved Import Specification, that you can reuse, if your csv format is not simple.
Option Explicit
Option Compare Database
Sub Call_Relink()
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim strTableName As String
Dim strPath As String
Dim strFile As String
Dim iReply As Integer
iReply = MsgBox("WARNING!!!! This code will remove the linked tables 'FileA' and 'FileB'" & vbCrLf & vbCrLf & _
"Click 'Yes' to Continue" & vbCrLf & "Click 'No' to Stop", vbYesNo, "CAUTION!! Will remove linked table(s)")
If iReply <> vbYes Then
Exit Sub
End If
On Error GoTo Error_Trap
Set dbs = CurrentDb
dbs.TableDefs.Delete "FileA" ' For testing; delete table if it already exists
strPath = "C:\Temp\"
strFile = "FileA.csv"
strTableName = "FileA" ' Table name in Access
Relink_CSV strTableName, strPath, strFile ' Call function to link the CSV file
dbs.TableDefs.Refresh ' Refresh TDF's
Debug.Print "Pause here and check file link" ' Put a breakpoint here; pause and look at the table in Access
dbs.TableDefs.Delete "FileA" ' For testing; delete table if it already exists
strPath = "C:\Temp\" ' Path to next csv
strFile = "FileB.csv" ' Name of next csv file
strTableName = "FileA" ' Table name in Access
Relink_CSV strTableName, strPath, strFile ' Call function to link to a different CSV file
dbs.TableDefs.Refresh
Debug.Print "Pause here and check file link" ' Put a breakpoint here; pause and look at the table in Access
My_Exit:
Set dbs = Nothing
Exit Sub
Error_Trap:
Debug.Print Err.Number & vbTab & Err.Description
If Err.Number = 3265 Then ' Item not found in this collection.
' Ignore this error
Resume Next
End If
MsgBox Err.Number & vbTab & Err.Description
Resume My_Exit
Resume
End Sub
Function Relink_CSV(strTableName As String, strPath As String, strFile As String)
' (1) Name of the table in Access
' (2) Path to the file
' (3) File name
On Error GoTo Relink_Err
DoCmd.TransferText acLinkDelim, , strTableName, strPath & strFile, False, ""
Relink_Exit:
Exit Function
Relink_Err:
Debug.Print Err.Number & vbTab & Err.Description
MsgBox Err.Number & vbTab & Err.Description
Resume Relink_Exit
Resume
End Function

Get contents of laccdb file through VBA

I want to be able to view the contents of my access database's laccdb file through VBA so I can use it to alert users (through a button) who else is in the database.
I specifically don't want to use a 3rd Party tool. I have tried using:
Set ts = fso.OpenTextFile(strFile, ForReading)
strContents = ts.ReadAll
This works fine if only 1 user is in the database. But for multiple users it gets confused by the presumably non-ASCII characters and goes into this kind of thing after one entry:
Does anyone have any suggestions? It's fine if I just open the file in Notepad++...
Code eventually used is as follows (I didn't need the title and have removed some code not being used):
Sub ShowUserRosterMultipleUsers()
Dim cn As New ADODB.Connection, rs As New ADODB.Recordset
cn.Provider = "Microsoft.ACE.OLEDB.12.0"
cn.Open "Data Source=" & CurrentDb.Name
Set rs = cn.OpenSchema(adSchemaProviderSpecific, , "{947bb102-5d43-11d1-bdbf-00c04fb92675}")
While Not rs.EOF
Debug.Print rs.Fields(0)
rs.MoveNext
Wend
End Sub
I found this which should help, it's not actually reading the ldb file, but it has the info that you need (Source: https://support.microsoft.com/en-us/kb/198755):
Sub ShowUserRosterMultipleUsers()
Dim cn As New ADODB.Connection
Dim cn2 As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i, j As Long
cn.Provider = "Microsoft.Jet.OLEDB.4.0"
cn.Open "Data Source=c:\Northwind.mdb"
cn2.Open "Provider=Microsoft.Jet.OLEDB.4.0;" _
& "Data Source=c:\Northwind.mdb"
' The user roster is exposed as a provider-specific schema rowset
' in the Jet 4 OLE DB provider. You have to use a GUID to
' reference the schema, as provider-specific schemas are not
' listed in ADO's type library for schema rowsets
Set rs = cn.OpenSchema(adSchemaProviderSpecific, _
, "{947bb102-5d43-11d1-bdbf-00c04fb92675}")
'Output the list of all users in the current database.
Debug.Print rs.Fields(0).Name, "", rs.Fields(1).Name, _
"", rs.Fields(2).Name, rs.Fields(3).Name
While Not rs.EOF
Debug.Print rs.Fields(0), rs.Fields(1), _
rs.Fields(2), rs.Fields(3)
rs.MoveNext
Wend
End Sub
I put together some code to read through the lock file and output a message listing users currently using the system.
Trying to read the whole file in at once seems to result in VBA treating the string as Unicode in the same way notepad does so I read in character by character and filter out non printing characters.
Sub TestOpenLaccdb()
Dim stm As TextStream, fso As FileSystemObject, strLine As String, strChar As String, strArr() As String, nArr As Long, nArrMax As Long, nArrMin As Long
Dim strFilename As String, strMessage As String
strFilename = CurrentProject.FullName
strFilename = Left(strFilename, InStrRev(strFilename, ".")) & "laccdb"
Set fso = New FileSystemObject
Set stm = fso.OpenTextFile(strFilename, ForReading, False, TristateFalse) 'open the file as a textstream using the filesystem object (add ref to Microsoft Scripting Runtime)
While Not stm.AtEndOfStream 'Read through the file one character at a time
strChar = stm.Read(1)
If Asc(strChar) > 13 And Asc(strChar) < 127 Then 'Filter out the nulls and other non printing characters
strLine = strLine & strChar
End If
Wend
strMessage = "Users Logged In: " & vbCrLf
'Debug.Print strLine
strArr = Split(strLine, "Admin", , vbTextCompare) 'Because everyone logs in as admin user split using the string "Admin"
nArrMax = UBound(strArr)
nArrMin = LBound(strArr)
For nArr = nArrMin To nArrMax 'Loop through all machine numbers in lock file
strArr(nArr) = Trim(strArr(nArr)) 'Strip leading and trailing spaces
If Len(strArr(nArr)) > 1 Then 'skip blank value at end
'Because I log when a user opens the database with username and machine name I can look it up in the event log
strMessage = strMessage & DLast("EventDescription", "tblEventLog", "[EventDescription] like ""*" & strArr(nArr) & "*""") & vbCrLf
End If
Next
MsgBox strMessage 'let the user know who is logged in
stm.Close
Set stm = Nothing
Set fso = Nothing
End Sub

Relinking database tables: Access, VBA

I have a procedure that relinks all the tables in a database baed on whether or not they are a linked table. Currently this is set up to run automatically as it's set inside an AutoExec macro which calls the function.
The code works but only if I close the database and reopen it. I know that this is because this needs to be done for the new links to take effect but is there anyway around this? Or, failing that, would it be better to make the VBA code close the database and reopen it?
Thanks in advance for the feedback
P.S. Here's the code, in case you're curious:
'*******************************************************************
'* This module refreshes the links to any linked tables *
'*******************************************************************
'Procedure to relink tables from the Common Access Database
Public Function RefreshTableLinks() As String
On Error GoTo ErrHandler
Dim strEnvironment As String
strEnvironment = GetEnvironment
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strCon As String
Dim strBackEnd As String
Dim strMsg As String
Dim intErrorCount As Integer
Set db = CurrentDb
'Loop through the TableDefs Collection.
For Each tdf In db.TableDefs
'Verify the table is a linked table.
If Left$(tdf.Connect, 10) = ";DATABASE=" Then
'Get the existing Connection String.
strCon = Nz(tdf.Connect, "")
'Get the name of the back-end database using String Functions.
strBackEnd = Right$(strCon, (Len(strCon) - (InStrRev(strCon, "\") - 1)))
'Debug.Print strBackEnd
'Verify we have a value for the back-end
If Len(strBackEnd & "") > 0 Then
'Set a reference to the TableDef Object.
Set tdf = db.TableDefs(tdf.Name)
If strBackEnd = "\Common Shares_Data.mdb" Or strBackEnd = "\Adverse Events.mdb" Then
'Build the new Connection Property Value - below needs to be changed to a constant
tdf.Connect = ";DATABASE=" & strEnvironment & strBackEnd
Else
tdf.Connect = ";DATABASE=" & CurrentProject.Path & strBackEnd
End If
'Refresh the table links
tdf.RefreshLink
End If
End If
Next tdf
ErrHandler:
If Err.Number <> 0 Then
'Create a message box with the error number and description
MsgBox ("Error Number: " & Err.Number & vbCrLf & _
"Error Description: " & Err.Description & vbCrLf)
End If
End Function
EDIT
Following on from Gords comments I have added the macro AutoExec method for calling the code below. Anyone see a problem with this?
Action: RunCode
Function Name: RefreshTableLinks()
The most common error in this situation is forgetting to .RefreshLink the TableDef but you are already doing that. I just tested the following VBA code which toggles a linked table named [Products_linked] between two Access backend files: Products_EN.accdb (English) and Products_FR.accdb (French). If I run the VBA code and then immediately open the linked table I see that the change has taken place; I don't have to close and re-open the database.
Function ToggleLinkTest()
Dim cdb As DAO.Database, tbd As DAO.TableDef
Set cdb = CurrentDb
Set tbd = cdb.TableDefs("Products_linked")
If tbd.Connect Like "*_EN*" Then
tbd.Connect = Replace(tbd.Connect, "_EN", "_FR", 1, 1, vbBinaryCompare)
Else
tbd.Connect = Replace(tbd.Connect, "_FR", "_EN", 1, 1, vbBinaryCompare)
End If
tbd.RefreshLink
Set tbd = Nothing
Set cdb = Nothing
End Function
I even tested calling that code from an AutoExec macro and it also seems to work as expected.
One thing you could try would be to call db.TableDefs.Refresh right at the end of your routine to see if that helps.
Edit
The issue here was that the database had a "Display Form" specified in its "Application Options", and that form apparently opens automatically before the AutoExec macro runs. Moving the function call for the re-linking code to the Form_Load event handler for that "startup form" seems a likely fix.

How do I utilize Access 2007 Linked Table Manager in C#

Scenario: I have a Front End and a Back End Access 2007 Database that are currently linked to each other through the Linked Table Manager Database Tool. The Back End DB is going to be moved to a location on a server. The server name will be different for each facility and there are about 40 or so now which will increase throughout the year.
What I need to try to accomplish is changing the linked tables programatically. I will need to build the linked string to something like:
\\something\facilitynum(gathered from Environment variable)\c$\somefolder\.
I have found that the column Database in MSysObjects contains the link string that would need to be changed. The question becomes, how do get permissions to change a System table or use some .dll that will allow me to change the link to the newly built string?
Everything that I have found so far always leads back to manually changing the link within the Access Database.
You can programmatically change the link from within Access (using VBA) like so (this uses a dsn file to contain the actual server information)
Private Sub UpdateDSN()
On Error GoTo ErrorHandler
Dim dbPath As String
Dim connStr As String
Dim Tdf As TableDef
dbPath = Application.CodeDb.Name
dbPath = Left(dbPath, InStr(dbPath, Dir(dbPath)) - 1)
For Each Tdf In CurrentDb.TableDefs
connStr = Tdf.Connect
If InStr(1, UCase(connStr), "ODBC") Then
connStr = "odbc; FILEDSN=" & dbPath & "db.dsn;"
Tdf.Connect = connStr
Tdf.RefreshLink
End If
Next
Dim fName As String
Dim fNumber As Integer
Dim InputStr As String
fNumber = FreeFile()
fName = dbPath & "db.dsn"
Dim serverName As String
Open fName For Input As fNumber
Do While Not EOF(fNumber)
Line Input #fNumber, InputStr
If InStr(1, UCase(InputStr), "SERVER=") > 0 Then
serverName = Right(InputStr, Len(InputStr) - _
(InStr(1, InputStr, "SERVER=") + 6))
End If
Loop
ErrorHandler:
On Error GoTo 0
DoCmd.OpenForm "Main"
cap = Forms!main.Caption
If InStr(1, cap, "(") > 1 Then
cap = Left(cap, InStr(1, cap, "("))
End If
Forms!main.Caption = "db" & " (" & serverName & ")"
End Sub

Preserving linked tables for Access DBs in same folder when the folder changes

I've got two Access databases that share linked tables. They are deployed together in a directory and accessed via code in a Word form.
How can I make sure that the links are preserved when the two databases are copied (together) to a different folder? Since I'm not "opening" the database, per se (it's being accessed via ADO), I don't know how to write code to refresh the links.
Update 14APR2009
I found that the previous answer I gave here was erroneous, so I updated it with new code.
How to proceed
Copy the code below to a VBA module.
From code or from the Immediate window in the VBA IDE, simply type:
RefreshLinksToPath Application.CurrentProject.Path
This will now relink all the linked tables to use the directory where your application is located.
It only needs to be done once or whenever you relink or add new tables.
I recommend doing this from code every time you start your application.
You can then move your databases around without problems.
Code
'------------------------------------------------------------'
' Reconnect all linked tables using the given path. '
' This only needs to be done once after the physical backend '
' has been moved to another location to correctly link to '
' the moved tables again. '
' If the OnlyForTablesMatching parameter is given, then '
' each table name is tested against the LIKE operator for a '
' possible match to this parameter. '
' Only matching tables would be changed. '
' For instance: '
' RefreshLinksToPath(CurrentProject.Path, "local*") '
' Would force all tables whose ane starts with 'local' to be '
' relinked to the current application directory. '
'------------------------------------------------------------'
Public Function RefreshLinksToPath(strNewPath As String, _
Optional OnlyForTablesMatching As String = "*") As Boolean
Dim collTbls As New Collection
Dim i As Integer
Dim strDBPath As String
Dim strTbl As String
Dim strMsg As String
Dim strDBName As String
Dim strcon As String
Dim dbCurr As DAO.Database
Dim dbLink As DAO.Database
Dim tdf As TableDef
Set dbCurr = CurrentDb
On Local Error GoTo fRefreshLinks_Err
'First get all linked tables in a collection'
dbCurr.TableDefs.Refresh
For Each tdf In dbCurr.TableDefs
With tdf
If ((.Attributes And TableDefAttributeEnum.dbAttachedTable) = TableDefAttributeEnum.dbAttachedTable) _
And (.Name Like OnlyForTablesMatching) Then
collTbls.Add Item:=.Name & .Connect, key:=.Name
End If
End With
Next
Set tdf = Nothing
' Now link all of them'
For i = collTbls.count To 1 Step -1
strcon = collTbls(i)
' Get the original name of the linked table '
strDBPath = Right(strcon, Len(strcon) - (InStr(1, strcon, "DATABASE=") + 8))
' Get table name from connection string '
strTbl = Left$(strcon, InStr(1, strcon, ";") - 1)
' Get the name of the linked database '
strDBName = Right(strDBPath, Len(strDBPath) - InStrRev(strDBPath, "\"))
' Reconstruct the full database path with the given path '
strDBPath = strNewPath & "\" & strDBName
' Reconnect '
Set tdf = dbCurr.TableDefs(strTbl)
With tdf
.Connect = ";Database=" & strDBPath
.RefreshLink
collTbls.Remove (.Name)
End With
Next
RefreshLinksToPath = True
fRefreshLinks_End:
Set collTbls = Nothing
Set tdf = Nothing
Set dbLink = Nothing
Set dbCurr = Nothing
Exit Function
fRefreshLinks_Err:
RefreshLinksToPath = False
Select Case Err
Case 3059:
Case Else:
strMsg = "Error Information..." & vbCrLf & vbCrLf
strMsg = strMsg & "Function: fRefreshLinks" & vbCrLf
strMsg = strMsg & "Description: " & Err.Description & vbCrLf
strMsg = strMsg & "Error #: " & Format$(Err.Number) & vbCrLf
MsgBox strMsg
Resume fRefreshLinks_End
End Select
End Function
This code is adapted from this source: http://www.mvps.org/access/tables/tbl0009.htm.
I removed all dependency on other functions to make it self-contained, that's why it's a bit longer than it should.
Renaud's answer no longer works in Access 2010 with Excel or CSV files.
I have made a few modifications:
Adapted to the current pattern for the connection string
Handled the database path differently for Excel files (includes filename) and CSV files (does not include filename)
Here is the code:
Public Function RefreshLinksToPath(strNewPath As String, _
Optional OnlyForTablesMatching As String = "*") As Boolean
Dim collTbls As New Collection
Dim i As Integer
Dim strDBPath As String
Dim strTbl As String
Dim strMsg As String
Dim strDBName As String
Dim strcon As String
Dim dbCurr As DAO.Database
Dim dbLink As DAO.Database
Dim tdf As TableDef
Set dbCurr = CurrentDb
On Local Error GoTo fRefreshLinks_Err
'First get all linked tables in a collection'
dbCurr.TableDefs.Refresh
For Each tdf In dbCurr.TableDefs
With tdf
If ((.Attributes And TableDefAttributeEnum.dbAttachedTable) = _
TableDefAttributeEnum.dbAttachedTable) _
And (.Name Like OnlyForTablesMatching) Then
Debug.Print "Name: " & .Name
Debug.Print "Connect: " & .Connect
collTbls.Add Item:=.Name & ";" & .Connect, Key:=.Name
End If
End With
Next
Set tdf = Nothing
' Now link all of them'
For i = collTbls.Count To 1 Step -1
strConnRaw = collTbls(i)
' Get table name from the full connection string
strTbl = Left$(strConnRaw, InStr(1, strConnRaw, ";") - 1)
' Get original database path
strDBPath = Right(strConnRaw, Len(strConnRaw) - (InStr(1, strConnRaw, "DATABASE=") + 8))
' Get the name of the linked database
strDBName = Right(strDBPath, Len(strDBPath) - InStrRev(strDBPath, "\"))
' Get remainder of connection string
strConn = Mid(strConnRaw, InStr(1, strConnRaw, ";") + 1, InStr(1, strConnRaw, "DATABASE=") _
- InStr(1, strConnRaw, ";") - 1)
' Reconstruct the full database path with the given path
' CSV-Files are not linked with their name!
If Left(strConn, 4) = "Text" Then
strDBPath = strNewPath
Else
strDBPath = strNewPath & "\" & strDBName
End If
' Reconnect '
Set tdf = dbCurr.TableDefs(strTbl)
With tdf
.Connect = strConn & "Database=" & strDBPath
.RefreshLink
collTbls.Remove (.Name)
End With
Next
RefreshLinksToPath = True
fRefreshLinks_End:
Set collTbls = Nothing
Set tdf = Nothing
Set dbLink = Nothing
Set dbCurr = Nothing
Exit Function
fRefreshLinks_Err:
RefreshLinksToPath = False
Select Case Err
Case 3059:
Case Else:
strMsg = "Error Information..." & vbCrLf & vbCrLf
strMsg = strMsg & "Function: fRefreshLinks" & vbCrLf
strMsg = strMsg & "Description: " & Err.Description & vbCrLf
strMsg = strMsg & "Error #: " & Format$(Err.Number) & vbCrLf
MsgBox strMsg
Resume fRefreshLinks_End
End Select
End Function
Are you referring to updating the links within your Word form, or the linked table links between your Access databases?
For the former, the best way that I know is to keep your connection string(s) at the Module level within your Word document/VBA project and make them const strings. Then when setting the connection string for your ADO Connection objects, pass it the relative connection string const.
For the latter, I would be tempted to use a relative path in the connection string to data within each Access database to the other. For example,
Dim connectionString as String
connectionString = ";DATABASE=" & CurrentProject.Path & "\[Database Name Here].mdb"
if as you say, the databases are copied together to a different folder (I'm assuming into the same folder).
I am unfortunately still on Access 2007. I started with one of the code blocks above which was not working for me. Having less access vba power I simplified it to only the first loop which gets the table paths and updates it in place. The next guy running into this can comment or update.
Option Compare Database
'------------------------------------------------------------'
' Reconnect all linked tables using the given path. '
' This only needs to be done once after the physical backend '
' has been moved to another location to correctly link to '
' the moved tables again. '
' If the OnlyForTablesMatching parameter is given, then '
' each table name is tested against the LIKE operator for a '
' possible match to this parameter. '
' Only matching tables would be changed. '
' For instance: '
' RefreshLinksToPath(CurrentProject.Path, "local*") '
' Would force all tables whose ane starts with 'local' to be '
' relinked to the current application directory. '
'
' Immediate window type
' RefreshLinksToPath Application.CurrentProject.Path
'------------------------------------------------------------'
Public Function RefreshLinksToPath(strNewPath As String, _
Optional OnlyForTablesMatching As String = "*") As Boolean
Dim strDBPath As String
'Dim strTbl As String
'Dim strMsg As String
Dim strDBName As String
Dim dbCurr As DAO.Database
Dim dbLink As DAO.Database
Dim tdf As TableDef
Set dbCurr = CurrentDb
Dim strConn As String
Dim strNewDbConn1 As String
Dim strNewDbConn2 As String
Dim strNewDbConn As String
' On Local Error GoTo fRefreshLinks_Err
'First get all linked tables in a collection'
dbCurr.TableDefs.Refresh
For Each tdf In dbCurr.TableDefs
With tdf
If ((.Attributes And TableDefAttributeEnum.dbAttachedTable) = TableDefAttributeEnum.dbAttachedTable) _
And (.Name Like OnlyForTablesMatching) Then
strConn = tdf.Connect
strDBPath = Right(strConn, Len(strConn) - (InStr(1, strConn, "DATABASE=") + 8))
strDBName = Right(strDBPath, Len(strDBPath) - InStrRev(strDBPath, "\"))
Debug.Print ("===========================")
Debug.Print (" connect is " + strConn)
Debug.Print (" DB PAth is " + strDBPath)
Debug.Print (" DB Name is " + strDBName)
strDBNewPath = strNewPath & "\" & strDBName
Debug.Print (" DB NewPath is " + strDBNewPath)
strNewDbConn1 = Left(strConn, (InStr(1, strConn, "DATABASE=") - 1))
strNewDbConn2 = "DATABASE=" & strDBNewPath
strNewDbConn = strNewDbConn1 & strNewDbConn2
Debug.Print (" DB strNewDbConn is " + strNewDbConn)
'Change the connect path
tdf.Connect = strNewDbConn
tdf.RefreshLink
End If
End With
Next
End Function