Connecting to access backend from access 2013 frontend using VBA - ms-access

I have 5-6 clients to whom I will be selling my Access based Product. Where there is Back-end Database file (Password Protected). Access accdr Front-end file which saves data in back-end file. The location of the backend file will change client to client, hence want to have a VBA Code which links front-end t back-end.
I tried the below code
sConnect = "Provider=Microsoft.ACE.OLEDB.12.0; " _
& Data Source= " & "C:\MyDB_be.accdb" & ";" _
& "Jet OLEDB:Database Password=123;"
But, the tables are not getting reconnected.
I Got the above code from this Ques on Stackoverflow.
Then I tried the below code
Const LnkDataBase = "C:\MyDB_be.accdb"
Sub relinktables()
'Routine to relink the tables automatically. Change the constant LnkDataBase to the desired one and run the sub
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim strTable As String
Set dbs = CurrentDb()
For Each tdf In dbs.TableDefs
If Len(tdf.Connect) > 1 Then 'Only relink linked tables
If tdf.Connect <> ";DATABASE=" & LnkDataBase Then 'only relink tables if the are not linked right
If Left(tdf.Connect, 4) <> "ODBC" Then 'Don't want to relink any ODBC tables
strTable = tdf.Name
dbs.TableDefs(strTable).Connect = ";DATABASE=" & LnkDataBase
dbs.TableDefs(strTable).RefreshLink
End If
End If
End If
Next tdf
End Sub
This works, when the file is not password protected. This code I got from This Ques. But there is no provision of specifying password.
Please help me out.
Either point out mistake in 1st code. OR How to specify password in
2nd Code OR New code altogether.
Spent 4 hrs on searching for solution. New to access VBA.
Went through this and this, but did not understand how to implement.

Give this a try:
Const LnkDataBase = "C:\MyDB_be.accdb"
Sub relinktables()
'Routine to relink the tables automatically. Change the constant LnkDataBase to the desired one and run the sub
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim strTable As String
Set dbs = CurrentDb()
For Each tdf In dbs.TableDefs
If Len(tdf.Connect) > 1 Then 'Only relink linked tables
If tdf.Connect <> ";DATABASE=" & LnkDataBase Then 'only relink tables if the are not linked right
If Left(tdf.Connect, 4) <> "ODBC" Then 'Don't want to relink any ODBC tables
strTable = tdf.Name
dbs.TableDefs(strTable).Connect = "Provider=Microsoft.ACE.OLEDB.12.0; " _
& "Data Source= " & LnkDataBase & ";" _
& "Jet OLEDB:Database Password=123;"
dbs.TableDefs(strTable).RefreshLink
End If
End If
End If
Next tdf
End Sub

After investing another 4 Hrs to this problem. Finally found the solution.
This is the code which worked flawlessly.
Const LnkDataBase = "C:\MyDB_be.accdb"
Const DBPassword = "123"
Sub relinktables()
'Routine to relink the tables automatically. Change the constant LnkDataBase to the desired one and run the sub
Dim dbs As DAO.Database
Dim tdf As DAO.TableDef
Dim strTable As String
Set dbs = CurrentDb()
For Each tdf In dbs.TableDefs
If Len(tdf.Connect) > 1 Then 'Only relink linked tables
If tdf.Connect <> ";DATABASE=" & LnkDataBase Then 'only relink tables if the are not linked right
If Left(tdf.Connect, 4) <> "ODBC" Then 'Don't want to relink any ODBC tables
strTable = tdf.Name
dbs.TableDefs(strTable).Connect = "MS Access;PWD=" & DBPassword & ";DATABASE=" & LnkDataBase
dbs.TableDefs(strTable).RefreshLink
End If
End If
End If
Next tdf
End Sub
I would encourage VBA Experts to add their comments OR Modify this code to add Error Debugging. Like - IF PC is not connected to network, and the path specified is on Network, then Access hangs. This issue is yet to be fixed.

Related

How to delete all records of a table in MS Access using VB6 ADO

I want to delete all records of a table in MS Access using VB.6 code.
Actually I'm going to reset my database with it, by that I mean to have NO records anymore.
How can I do that?
I have done it.
On Error Resume Next
Dim cnn As New ADODB.Connection
cnn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & App.Path & "\DB.mdb"
cnn.Open
cnn.Execute "delete * from LogTBL"
cnn.Close
Here is code that will delete all records in all tables of the Access database you are connected to. HOWEVER!! If you have built relationships between tables and have not specified 'Cascade Delete', then you can't delete the 'owner' table until deleting from the 'member' table. One way around that is to add an error trap so that you check that condition, then ignore (Resume Next). But then you would need to repeat running this code until no errors. You need to set your connection string (see comment in code)!!
Function Delete_All_Data()
Dim cnLocalData As ADODB.Connection
Dim catLocal As ADOX.Catalog
Dim tdf As ADOX.Table
Dim strSQL As String
Dim strTableName As String
Set cnLocalData = New ADODB.Connection
MsgBox " Add code to connect to your database either using Connection cnLocalData or your own and change this code!!!"
Set catLocal = New ADOX.Catalog
catLocal.ActiveConnection = cnLocalData
For Each tdf In catLocal.Tables
If UCase(tdf.Type) = "TABLE" And UCase(Left(tdf.Name, 4)) <> "MSYS" Then
if tdf.Name <> "INFOTBL" Then
strTableName = tdf.Name
strSQL = "delete * from [" & strTableName & "];"
cnLocalData.Execute strSQL
End If
End If
Next tdf
Set tdf = Nothing
Set catLocal = Nothing
cnLocalData.Close
Set cnLocalData = Nothing
End Function

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.

MS Access Metadata

I'm performing a data cleansing operation on an access database. I have several duplicate records in a table that I want to consolidate down into one single record. In doing this I will need to update all references to the records that I will be consolidating.
If I know the column name that holds the record id is there a way to find all of the tables in access that contain this column?
You can examine the TableDefs collection and determine which tables contain a field with a given name.
Public Sub TablesWithField(ByVal pName As String)
Dim db As DAO.Database
Dim tdf As DAO.TableDef
Dim strMsg As String
Dim strName As String
On Error GoTo ErrorHandler
Set db = CurrentDb
For Each tdf In db.TableDefs
strName = vbNullString
'ignore system and temporary tables '
If Not (tdf.name Like "MSys*" Or tdf.name Like "~*") Then
strName = tdf.Fields(pName).name
If Len(strName) > 0 Then
Debug.Print tdf.name & ": " & pName
End If
End If
Next tdf
ExitHere:
On Error GoTo 0
Set tdf = Nothing
Set db = Nothing
Exit Sub
ErrorHandler:
Select Case Err.Number
Case 3265 'Item not found in this collection. '
Resume Next
Case Else
strMsg = "Error " & Err.Number & " (" & Err.description _
& ") in procedure TablesWithField"
MsgBox strMsg
GoTo ExitHere
End Select
End Sub
Short answer: Yes. And there are many ways to skin that cat. Two ideas:
(1) Via VBA, make use of: Application.CurrentDb.TableDefs(i).Fields(j).Name
(2) Via Tools==>Analyze==>Documenter, make a report and then search its output (Publish it with MS Word).
Sorry, but Access isn't built like MS SQL Server or DB2 - the MSys* tables really aren't set up for querying table schemas like that. However, others have VBA based solutions that look useful.
You can use Schemas, not exactly a query, but similar:
Function ListTablesContainingField(SelectFieldName) As String
'Tables returned will include linked tables
'I have added a little error coding. I don't normally do that
'for examples, so don't read anything into it :)
Dim cn As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim strTempList As String
On Error GoTo Error_Trap
Set cn = CurrentProject.Connection
'Get names of all tables that have a column called <SelectFieldName>
Set rs = cn.OpenSchema(adSchemaColumns, _
Array(Empty, Empty, Empty, SelectFieldName))
'List the tables that have been selected
While Not rs.EOF
'Exclude MS system tables
If Left(rs!Table_Name, 4) <> "MSys" Then
strTempList = strTempList & "," & rs!Table_Name
End If
rs.MoveNext
Wend
ListTablesContainingField = Mid(strTempList, 2)
Exit_Here:
rs.Close
Set cn = Nothing
Exit Function
Error_Trap:
MsgBox Err.Description
Resume Exit_Here
End Function

How to save an ADO recordset into a new local table in Access 2003?

I'm trying to import tables from a FoxPro 9.0 database into Access 2003. So far, from Google searches and many trials, the only way for me to connect to the tables is through an OLE DB connection programatically. I have set up 3 ODBC connections with different configurations but none of them work: I get "unspecified errors" that I can't find any information on.
With OLE DB I can succesfully connect to the FoxPro database, and import tables in ADO recordsets. The problem is that I can't save the recordset into new table in the local database using SQL. The ADO recordsets behave differently than tables, so I can't query them. The code below gives me a "type mismatch" error at DoCmd.RunCommand ("select * from " & rst & " INTO newClients").
Sub newAdoConn()
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim strSQL As String
Dim decision As Integer
Set cnn = New ADODB.Connection
cnn.ConnectionString = "Provider=vfpoledb;" & _
"Data Source=s:\jobinfo\data\jobinfo.dbc;" & _
"Mode=ReadWrite|Share Deny None;" & _
"Collating Sequence=MACHINE;" & _
"Password=''"
strSQL = "Select * from Jobs"
cnn.Open
Set rst = cnn.Execute("Select * from clients")
If rst.EOF = False Then
Do While Not rst.EOF
decision = MsgBox(rst.Fields!ID & " " & rst.Fields!fname & " " & rst.Fields!lname & vbCrLf & vbCrLf & "Continue?", vbYesNo)
If decision = vbYes Then
rst.MoveNext
Else
Exit Do
End If
Loop
End If
DoCmd.RunCommand ("select * from " & rst & " INTO newClients")
rst.Close
Set rst = Nothing
cnn.Close
Set cnn = Nothing
End Sub
I finally worked out a decent solution. It involves saving the ado recordset from memory to an excel file using the copyFromRecordset function, and then linking the file programmatically to a table in excel using the TransferSpreadsheet()...
Sub saveToExcel()
Dim cnn As ADODB.Connection
'declare variables
Dim rs As ADODB.Recordset
Dim strSQL As String
Dim decision As Integer
Dim colIndex As Integer
' Dim fso As New FileSystemObject
' Dim aFile As File
'set up connection to foxpro database
Set cnn = New ADODB.Connection
cnn.ConnectionString = "Provider=vfpoledb;" & _
"Data Source=s:\jobinfo\data\jobinfo.dbc;" & _
"Mode=ReadWrite|Share Deny None;" & _
"Collating Sequence=MACHINE;" & _
"Password=''"
cnn.Open
Set rs = cnn.Execute("Select * from clients")
'Create a new workbook in Excel
Dim oExcel As Object
Dim oBook As Object
Dim oSheet As Object
Set oExcel = CreateObject("Excel.Application")
Set oBook = oExcel.Workbooks.Add
Set oSheet = oBook.Worksheets(1)
oSheet.Name = "clients"
' Copy the column headers to the destination worksheet
For colIndex = 0 To rs.Fields.Count - 1
oSheet.Cells(1, colIndex + 1).Value = rs.Fields(colIndex).Name
Next
'Transfer the data to Excel
oSheet.Range("A2").CopyFromRecordset rs
' Format the sheet bold and auto width of columns
oSheet.Rows(1).Font.Bold = True
oSheet.UsedRange.Columns.AutoFit
'delete file if it exists - enable scripting runtime model for this to run
'If (fso.FileExists("C:\Documents and Settings\user\Desktop\clients.xls")) Then
' aFile = fso.GetFile("C:\Documents and Settings\user\Desktop\clients.xls")
' aFile.Delete
'End If
'Save the Workbook and Quit Excel
oBook.SaveAs "C:\Documents and Settings\user\Desktop\clients.xls"
oExcel.Quit
'Close the connection
rs.Close
cnn.Close
MsgBox ("Exporting Clients Done")
'link table to excel file
DoCmd.TransferSpreadsheet acLink, acSpreadsheetTypeExcel5, "clientsTest", "C:\Documents and Settings\user\Desktop\clients.xls", True
End Sub
What you will have to do is open the FoxPro table as a recordset and open the local table as another recordset. You can then loop through the FoxPro recordset and do something like this
Do until FoxProRst.EOF
LocatRst.AddNew
LocalRst!SomeField1=FoxProRst!SomeField1
LocalRst!SomeField2=FoxProRst!SomeField2
LocalRst!SomeField3=FoxProRst!SomeField3
LocalRst.Update
FoxProRst.MoveNext
Loop
It might not be the quickest way but it will work
Let me just sketch another approach with SQL queries, that could simplify:
'...
'not required for first time test:
'cnn.Execute("DROP TABLE MyNewTable")
'...
'create the new table in the destination Access database
cnn.Execute("CREATE TABLE MyNewTable (MyField1 int, MyField2 VARCHAR(20), MyField3 Int)")
'insert data in the new table from a select query to the original table
Dim sSQL as string, MyOriginalDBPath as String
sSQL = "INSERT INTO MyNewTable (MyField1, MyField2, MyField3) SELECT OriginalField1, OriginalField2, OriginalField3 FROM [" & MyOriginalDBPath & ";PWD=123].clients"
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
rs.Open sSQL, cnn, adOpenForwardOnly, adLockReadOnly, adCmdText
'...
Note: this 'draft' idea assumes that the connection string is made to the Access database and the connection to the original database would be inside the SQL string, but i have not idea about the correct sintaxis. I have only tested this approach with different access databases.
Note that this is for Access: ...[" & MyOriginalDBPath & ";PWD=123]...
The Jet database engine can reference external databases in SQL statements by using a special syntax that has three different formats:
[Full path to Microsoft Access database].[Table Name]
[ISAM Name;ISAM Connection String].[Table Name]
[ODBC;ODBC Connection String].[Table Name]
...
You can use an ODBC Data Source Name (DSN) or a DSN-less connection string:
DSN: [odbc;DSN=;UID=;PWD=]
DSN-less: [odbc;Driver={SQL Server};Server=;Database=;
UID=;PWD=]
Some references:
Querying data by joining two tables in two database on different servers
C# - Join tables from two different databases using different ODBC drivers
Why not use ODBC to link to the table? http://support.microsoft.com/kb/225861

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

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