Introduction
Until just recently, I would use system DSNs for all of my MS Access databases that connected to MS SQL Server backends. It is really easy to setup and didn't require all the code that I was seeing online for the DSN-Less connections. However, it is a pain to try to switch to a test server, make sure that you have the correct DSN setup on the client computer (changes depending on 32 or 64 bit client system), etc. So now I have made the switch to DSN-Less connections and decided to post how I did it (since I can't find everything that I need online).
Setup
First, I created two local tables to store the different SQL Server locations and another on for the list of tables and where they should be connected to.
Code
First, I have the code to add a table to the TableDefs collection. This function adds the table to the TableDefs and then adds the table to the table list in tblTableLocatio n.
The parameters are as follows
The code to move a table between servers is very much the same, but before it adds the table to the TableDefs collection, it first deletes it. So the linked table from the old location is deleted and then a new linked table is created that is linked to the new location.
Calling the Code
I have an unbound form that allows me to enter all my information in textboxes and comboboxes. The exact design isn't important, but I have two sections: one to add a table and one to move tables to another server.
First, adding a table. A textbox for the local table name, remote table name, and a combobox for the server/database. I think that the control names are fairly obvious as to what they are.
Moving the tables. Comboboxes for the From and To server/database.
All of my SQL Server backend databases have two databases that they connect to. One is the database for the data and one is an Employee database that lists what their permissions are for that database (A custom built database that I did so that I don't have to create it for every database that I do. I might make another article about it later.). Because of this, I can't just move all tables from one server to another. Having the From combobox lets me only move the tables that are one server/database to another server/database and leave the other tables alone.
Conclusion
I have already used this once and I can tell you it is so much simpler than using the Linked Table Manager and making it ask for a new location. For me, it asks for the new location for every single table. When working with 10+ tables (I've got one right now with 24), this is very annoying. Now all I have to do is make two selections and click a button. Done.
Until just recently, I would use system DSNs for all of my MS Access databases that connected to MS SQL Server backends. It is really easy to setup and didn't require all the code that I was seeing online for the DSN-Less connections. However, it is a pain to try to switch to a test server, make sure that you have the correct DSN setup on the client computer (changes depending on 32 or 64 bit client system), etc. So now I have made the switch to DSN-Less connections and decided to post how I did it (since I can't find everything that I need online).
Setup
First, I created two local tables to store the different SQL Server locations and another on for the list of tables and where they should be connected to.
Code:
[U]tblBE[/U] BE_ID_pk AutoNumber Driver Text Server Text DatabaseName Text [U]tblTableLocation[/U] TableID_pk AutoNumber TableName Text RemoteTableName Text LocationID_fk Number One-to-Many join on tblBE.BE_ID_pk = tblTableLocation.LocationID_fk
First, I have the code to add a table to the TableDefs collection. This function adds the table to the TableDefs and then adds the table to the table list in tblTableLocatio n.
Code:
Public Function AddTable(TableName As String, RemoteTable As String, Location As Long) As Boolean
On Error GoTo Error_Handler
Dim db As DAO.Database
Dim td As TableDef
Dim strCon As String
Dim strAddQry As String
Set db = CurrentDb
strCon = "ODBC;" & GetLocation(Location) & "Trusted_Connection=YES"
Set td = db.CreateTableDef(TableName, dbAttachSavePWD, RemoteTable, strCon)
db.TableDefs.Append td
strAddQry = "INSERT INTO tblTableLocation (TableName, RemoteTableName, LocationID_fk) " & _
"VALUES ('" & TableName & "', '" & RemoteTable & "', " & Location & ")"
db.Execute strAddQry, dbFailOnError
AddTable = True
Exit_Procedure:
Set db = Nothing
Set td = Nothing
Exit Function
Error_Handler:
AddTable = False
Resume Exit_Procedure
End Function
Private Function GetLocation(LocationID As Long) As String
On Error GoTo Error_Handler
Dim db As DAO.Database
Dim rst As DAO.Recordset
Dim strRst As String
Dim strLoc As String
strRst = "SELECT * FROM tblBE WHERE BE_ID_pk = " & LocationID
Set db = CurrentDb
Set rst = db.OpenRecordset(strRst, dbOpenDynaset)
With rst
strLoc = "DRIVER=" & !Driver & ";SERVER=" & !Server & ";DATABASE=" & !DatabaseName & ";"
End With
GetLocation = strLoc
Exit_Procedure:
On Error Resume Next
rst.Close
Set db = Nothing
Set rst = Nothing
Exit Function
Error_Handler:
Resume Exit_Procedure
End Function
- TableName: The name that you want to appear in Access
- RemoteTable: The name of the table in SQL Server (includes the schema name, ie. dbo.Customers)
- Location: The PK value from tblBE for the server/database that you want to connect to. The location information comes from the GetLocation() function.
The code to move a table between servers is very much the same, but before it adds the table to the TableDefs collection, it first deletes it. So the linked table from the old location is deleted and then a new linked table is created that is linked to the new location.
Code:
Public Function MoveTable(LocalTable As String, RemoteTable As String, Location As Long) As Boolean
On Error GoTo Error_Handler
Dim td As TableDef
Dim strCon As String
Dim db As DAO.Database
Set db = CurrentDb
db.TableDefs.Delete LocalTable
strCon = "ODBC;" & GetLocation(Location) & ";Trusted_Connection=YES"
Set td = db.CreateTableDef(LocalTable, dbAttachSavePWD, RemoteTable, strCon)
db.TableDefs.Append td
MoveTable = True
Exit_Procedure:
Set db = Nothing
Set td = Nothing
Exit Function
Error_Handler:
AttachDSNLessTable = False
Resume Exit_Procedure
End Function
Calling the Code
I have an unbound form that allows me to enter all my information in textboxes and comboboxes. The exact design isn't important, but I have two sections: one to add a table and one to move tables to another server.
First, adding a table. A textbox for the local table name, remote table name, and a combobox for the server/database. I think that the control names are fairly obvious as to what they are.
Code:
Private Sub cmdAttachTable_Click()
On Error GoTo Error_Handler
If Me.txtLTable & "" <> "" And Me.txtRTable & "" <> "" And Not IsNull(Me.cboLoc) Then
If AddTable(Me.txtLTable, Me.txtRTable, Me.cboLoc) = False Then
MsgBox "Attempt to attach " & Me.txtLTable & " to the database failed.", vbCritical
End If
Else
MsgBox "All three fields need to be populated in order to attach a table.", vbInformation
End If
Exit_Procedure:
Exit Sub
Error_Handler:
Resume Exit_Procedure
End Sub
Code:
Private Sub cmdChangeBackend_Click()
On Error GoTo Error_Handler
Dim strTables As String
Dim db As DAO.Database
Dim rstTables As DAO.Recordset
Dim strMsg As String
If Not IsNull(Me.cboFrom) And Not IsNull(Me.cboTo) Then
strTables = "SELECT * FROM tblTableLocation WHERE LocationID_fk = " & Me.cboFrom
Set db = CurrentDb
Set rstTables = db.OpenRecordset(strTables, dbOpenDynaset)
With rstTables
Do While Not .EOF
If AttachDSNLessTable(!TableName, !RemoteTableName, Me.cboTo) = False Then
strMsg = "Connection attempt for " & !TableName & " failed."
MsgBox strMsg, vbCritical, "Connection Attempt Failed"
Else
.Edit
!LocationID_fk = Me.cboTo
.Update
End If
.MoveNext
Loop
End With
Else
MsgBox "Both drop-down boxes must have values"
End If
Exit_Procedure:
On Error Resume Next
rstTables.Close
Set db = Nothing
Set rstTables = Nothing
Exit Sub
Error_Handler:
Resume Exit_Procedure
End Sub
Conclusion
I have already used this once and I can tell you it is so much simpler than using the Linked Table Manager and making it ask for a new location. For me, it asks for the new location for every single table. When working with 10+ tables (I've got one right now with 24), this is very annoying. Now all I have to do is make two selections and click a button. Done.
Comment