Reputation: 67
I have an Access Form that uses a linked sql server table as a datasource. I will need to distribute this file to other users soon and I need a way to programmaticly install the DSN to their machines. This is the process of manually setting up the link:
External Data > More > ODBC Database > Link to data source > Machine data source tab > press new > user data source > sql server > name=up to you; server= serverName > How should SQL server verify the autheticity of the login ID? With windows NT authentication using the network login ID > Attach database File Name (database name) > choose the table and press ok
That is what I did to access my table but I would like it so that the user can press a button and get access to the table and at the same time be authenticated by using windows NT authentication.
I am having trouble finding a way to write this in access vba code can someone direct me in the right direction?
Upvotes: 2
Views: 12244
Reputation: 49039
As a general rule you find MUCH better success by using a DSN less connection. This will eliminate many issues and problems. How to use a DSN less connection is outlined here:
http://www.accessmvp.com/DJSteele/DSNLessLinks.html
And also you do NOT want to store the user name + password in the connection string, but only “log on” one time. Again this saves huge hassles and also means your connection strings and/or DSN does not have to save and expose the user name and password in the actual links.
And this approach means you can have different logons and NOT have to re-link or change existing table links.
The follow shows how to use a cached logon and this thus allows one to have different logons without having to re-link your tables.
https://blogs.office.com/en-us/2011/04/08/power-tip-improve-the-security-of-database-connections/
I highly recommend you adopt both of the above approaches when using linked tables to SQL server.
Upvotes: 5
Reputation: 3635
This question is the first google result for "VBA create DSN", however I do not like the answers since they seem to revolve around touching the registry or otherwise avoiding the use of a DSN. In my case I have a project manager that wants to use a DSN because that is what they are comfortable with and so I could not avoid it. For anyone else struggling with this, I found a very straight forward way to do it elsewhere. Notably starting here.
I used code found there, here and here to cobble this together and put it in the open event of a splash screen form:
Private Declare Function SQLConfigDataSource Lib "ODBCCP32.DLL" _
(ByVal hwndParent As Long, ByVal fRequest As Long, _
ByVal lpszDriver As String, ByVal lpszAttributes As String) As Long
Private Sub Form_Open(Cancel As Integer)
On Error Resume Next
If fDsnExist("DSN=YOUR_DSN_NAME") = True Then
'Do all of your loading or just close this form.
Else
Dim doContinue As Integer
doContinue = MsgBox("There is an issue with the database connection. This can be corrected now or you can reach out to support." _
& vbCrLf & vbCrLf & "Do you want to attempt to correct the issue now?", vbYesNo, "Connection Error")
If doContinue = vbYes Then
Dim vAttributes As String
vAttributes = "DSN=YOUR_DSN_NAME" & Chr(0)
vAttributes = vAttributes & "Description=Self Explnatory" & Chr(0)
vAttributes = vAttributes & "Trusted_Connection=Yes" & Chr(0)
vAttributes = vAttributes & "Server=YOUR_SQL_SERVER_ADDRESS" & Chr(0)
vAttributes = vAttributes & "Database=YOUR_DATABASE_NAME" & Chr(0)
SQLConfigDataSource 0&, 1, "SQL Server", vAttributes
If Err.Number <> 0 Then
MsgBox "The connection could not be restored. Please report this error to support: " & vbCrLf & vbCrLf & Err.Description
Err.Clear
DoCmd.Close acForm, "frmSplash"
DoCmd.Quit acQuitSaveNone
Else
MsgBox "The Connection has been restored.", , "Success"
End If
Else
MsgBox "Please contact support to resolve this issue.", vbCritical + vbOKOnly, "Error"
DoCmd.Close acForm, "frmSplash"
DoCmd.Quit acQuitSaveNone
End If
End If
End Sub
Function fDsnExist(strDsn)
On Error Resume Next
' ------------------------------------------------------
' Declare Variables
' ------------------------------------------------------
Dim objConnection
Dim strReturn
' ------------------------------------------------------
' Create database object
' ------------------------------------------------------
Set objConnection = CreateObject("ADODB.Connection")
objConnection.ConnectionString = strDsn
objConnection.Open
' ------------------------------------------------------
' Check if database is open Correctly
' ------------------------------------------------------
If Err.Number <> 0 Then
strReturn = False
Err.Clear
Else
strReturn = True
' ------------------------------------------------------
' Close database connection
' ------------------------------------------------------
objConnection.Close
End If
Set objConnection = Nothing
' ------------------------------------------------------
' Return database status
' ------------------------------------------------------
fDsnExist = strReturn
End Function
Now when the user opens the access database, the splash form checks for the existence of the DSN and if it is not found, gives the user an option to create it.
You mentioned NT authentication; I use a trusted connection under the assumption that the user is already logged into a domain and has been provided access using those credentials to the SQL server. You may need to modify the DSN connection string in order to prompt for a password and username.
Upvotes: 4
Reputation: 12728
First and foremost, Albert D. Kallal is absolutely correct with his answer. If you can use a DSN-less connection, you should. However, for the sake of answering the question you asked...
ODBC DSN entries are stored in the windows registry. You can add by directly modifying the windows registry. I DO NOT recommend this if you are not familiar with the registry. You can brick a machine if you remove/alter the wrong keys. The particular keys we're looking for are located under Software/ODBC of HKEY_LOCAL_MACHINE and HKEY_CURRENT_USER, depending on whether we're looking for a System or User odbc connection respectively.
My solution is too long and involved to post in it's entirety on Stack Overflow. You can find it on my blog under VBA ODBC DSN Installer complete with class module downloads and examples of how to use them. (Full disclosure, one of them was originally written by Steve McMahon, but I have modified it for use with MS Access.)
The short version is I built a DSN class on top of Mr. McMahon's registry class in order to install DSNs when my MS Access application is started.
Upvotes: 2