How can I programmatically create a DSN?

前端 未结 3 1024
失恋的感觉
失恋的感觉 2020-12-11 10:40

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

相关标签:
3条回答
  • 2020-12-11 11:04

    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.

    0 讨论(0)
  • 2020-12-11 11:14

    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.

    0 讨论(0)
  • 2020-12-11 11:26

    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.

    0 讨论(0)
提交回复
热议问题