为什么我的 Access 数据库连接 vb 显示身份验证失败

Why is my Access Database connection vb stating authentication failed

提问人:St3althPatchin 提问时间:9/8/2023 最后编辑:Joel CoehoornSt3althPatchin 更新时间:9/9/2023 访问量:130

问:

enter image description here

我是第一次尝试使用 Microsoft Access。使用它创建一个数据库,用于存储我将从大量 Microsoft Excel 文件中提取的信息。不幸的是,当我尝试从Excel文件设置函数和与数据库的连接时,我遇到了这个错误,我不知道如何解决。我一直在使用在线资源来尝试第一次构建它,但我还没有看到任何人自己遇到具体问题。每次它通过我拥有的一个函数时,似乎都会发生此错误。我希望有人能够提供一些见解。似乎每次我运行它并去调试它时都会突出显示.打开时显示 GetKeyID 函数中的错误。但我以前从未见过这种情况。

Sub TestTransferDataToAccess()
    Dim ConnObj As ADODB.Connection
    Dim RecSet As ADODB.Recordset
    Dim ConnCmd As ADODB.Command
    Dim ColNames As ADODB.Fields
    Dim DataSource As String
    Dim intLoop As Integer
    
    'Datasource
    DataSource = "O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.accdb"
    
    'Create a new connection object & a new command object
    Set ConnObj = New ADODB.Connection
    Set ConnCmd = New ADODB.Command
    
    'Create a new connection
    With ConnObj
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = DataSource
        .Open
    End With
    
    'command object to use Active Connection shortcut method
    ConnCmd.ActiveConnection = ConnObj
    
    ' Define Excel workbook and worksheet
    Dim wb As Workbook
    Dim ws As Worksheet
    
    ' Set Excel workbook and worksheet
    Set wb = Workbooks.Open("O:\Swap\Chicago\GenoF\Reading-2021-03-22-10-14-48.xls")
    ' Set worksheet
    Set ws = wb.Sheets("As Found-CW Data")
    
    ' Loop through Excel data and insert into Access database
    Dim headerID As Long
    Dim keyID As Long
    Dim torqueValue As Double
    Dim row As Long
    
    For row = 16 To 25 ' Rows B16 to B25 for Channel 1 data
        headerID = GetHeaderID(ws.Cells(row, 2).Value) ' Used for header lookup
        keyID = GetKeyID("Channel 1") ' Used for key lookup
        torqueValue = CDbl(ws.Cells(row, 3).Value) ' Used for torque data cell
        
        ' Insert data into Access database
        strSQL = "INSERT INTO tblTorqueData (headerID, keyID, torqueValue) VALUES (" & headerID & ", " & keyID & ", " & torqueValue & ")"
        ConnCmd.Execute strSQL
        
        
    Next row
    
    ' Close the Recordset and Connection
    RecSet.Close
    ConnObj.Close
    Set RecSet = Nothing
    Set ConnCmd = Nothing
    Set ConnObj = Nothing
    
    MsgBox "Data transfer to Access completed."
End Sub

Function GetHeaderID(headerName As String) As Long
    'variables for database connection
    Dim conn As Object
    Dim rs As Object
    Dim RecSet As ADODB.Recordset
    
    'Define the Datasource
    DataSource = "O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.accdb"
     
    'Create a new connection object & a new command object
    Set ConnObj = New ADODB.Connection
    Set ConnCmd = New ADODB.Command
    
    'Create a new connection
    With ConnObj
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = DataSource
        .Open
    End With
    
    'Allow command object to use the Active Connection shortcut method
    'ConnCmd.ActiveConnection = ConnObj
    
    ' Use SQL query to retrieve HeaderID based on headerName
    Dim strSQL As String
    strSQL = "SELECT HeaderID FROM tblHeaders WHERE HeaderName = '" & headerName & "'"
    
     'Execute the Query & Get the Column Names.
    'rs.Open strSQL, conn
    Set rs = CreateObject("ADODB.Recordset")
    
       ' Check if record was found
    'If Not rs.EOF Then
     '   GetHeaderID = rs.Fields(0).Value
    'Else
        ' Handle the case where no record was found
     '   GetHeaderID = -1 ' Replace with default value
    'End If

    
        ' Close the Connection
    ConnObj.Close
    
    ' Release ADODB objects
    Set rs = Nothing
    Set conn = Nothing
End Function

Function GetKeyID(keyName As String) As Long
    ' variables for database connection
    Dim conn As Object
    Dim rs As Object
    Dim RecSet As ADODB.Recordset
    
    'path to Access database file
    Dim dbPath As String
    dbPath = "O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.laccdb"
    
    'database and recordset
    Set conn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
     
     'Create a new connection
    With conn
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = DataSource
        .Open
    End With
    
    'Allow command object to use the Active Connection shortcut method
    ConnCmd.ActiveConnection = ConnObj
    
    ' Use SQL query to retrieve KeyID based on keyName
    Dim strSQL As String
    strSQL = "SELECT KeyID FROM tblKeys WHERE KeyName = '" & keyName & "'"
    
    ' Execute query and get result
    Set RecSet = ConnCmd.Execute
    'rs.Open strSQL, conn
    
    ' Check if record was found
    If Not rs.EOF Then
        GetKeyID = rs.Fields(0).Value
    Else
        ' Handle case where no record was found
        GetKeyID = -1 ' Replace with appropriate default value
    End If
    
    ' Close the Recordset and Connection
    rs.Close
    conn.Close
    
    ' Release ADODB objects
    Set rs = Nothing
    Set conn = Nothing
End Function
Excel VBA 数据库 MS-Access

评论

0赞 Kelsey 9/8/2023
整个错误是什么?
0赞 St3althPatchin 9/9/2023
我将添加它的外观的屏幕截图
0赞 St3althPatchin 9/9/2023
我已经做了必要的改变。我事先没有看到,谢谢。你是对的,这不是错误的原因,但值得赞赏! ;)
0赞 St3althPatchin 9/9/2023
我没有想过明确添加一个选项,这很有趣。我可以试试。目前,我的数据源在我的“局部变量”窗口中显示为空。
0赞 Joel Coehoorn 9/9/2023
代码的部分是非常危险的,对于 .我可能不同意关于使用单个连接的答案,但使用查询参数的示例部分很重要。WHERE HeaderName = '" & headerName & "'"keyName

答:

-1赞 CDP1802 9/9/2023 #1

仅创建一个连接并将其用于所有查询

Option Explicit

Sub TestTransferDataToAccess2()

    Const db = "O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.accdb"
    Const WBPATH = "O:\Swap\Chicago\GenoF\Reading-2021-03-22-10-14-48.xls"
    
    Dim rs As ADODB.Recordset, cmd As ADODB.Command
    Dim keyID As Long, keyName As String, hdr As String
    Dim wb As Workbook, ws As Worksheet, ar, arHdrID
    Dim r As Long, n As Long, num As Long
    Dim t0 As Single: t0 = Timer
    
    ' copy data from sheet to an array
    Set wb = Workbooks.Open(WBPATH)
    Set ws = wb.Sheets("As Found-CW Data")
    With ws
        ar = .Range("B16:C25")
        ReDim arHdrID(1 To UBound(ar))
    End With
    
     ' get keyid for keyname
    keyName = "Channel 1"
    keyID = GetKeyID(keyName, db)
    If keyID < 0 Then
        MsgBox "No KeyID for " & keyName, vbExclamation
        Exit Sub
    End If
    
    ' get header IDs
    Set cmd = New ADODB.Command
    With cmd
        .ActiveConnection = dbConnect(db)
        .CommandText = "SELECT HeaderID FROM tblHeaders WHERE HeaderName = ?"
        .Parameters.Append .CreateParameter("p1", adVarChar, adParamInput, 10)
    
        For r = 1 To UBound(ar)
            hdr = ar(r, 1)
            .Parameters(0) = hdr
            Set rs = .Execute
            If rs.EOF Then
                MsgBox "No HeaderID for " & hdr, vbExclamation
                Exit Sub
            End If
            arHdrID(r) = rs.Fields(0)
            'Debug.Print r, arHdrID(r), rs.Fields(0)
        Next
        
        .ActiveConnection.Close
    End With
    
    ' prepare and execute insert command
    Set cmd = New ADODB.Command
    With cmd
        .ActiveConnection = dbConnect(db)
        .CommandText = "INSERT INTO tblTorqueData (headerID, keyID, torqueValue) VALUES (?,?,?)"
        .Parameters.Append .CreateParameter("p1", adBigInt, adParamInput)
        .Parameters.Append .CreateParameter("p2", adBigInt, adParamInput)
        .Parameters.Append .CreateParameter("p3", adNumeric, adParamInput)
    
        ' execute inserts
        For r = 1 To UBound(ar)
            .Parameters(0) = arHdrID(r) ' headerID
            .Parameters(1) = keyID
            .Parameters(2) = CDbl(ar(r, 2))
            .Execute num
            n = n + num
        Next
        
        .ActiveConnection.Close
    End With
    
    MsgBox n & " records inserted into " & db, vbInformation, Format(Timer - t0, "0.0 secs")
       
End Sub

Function GetKeyID(keyName, db) As Long
      
    Dim rs As ADODB.Recordset
    With New ADODB.Command
        .ActiveConnection = dbConnect(db)
        .CommandText = "SELECT KeyID FROM tblKeys WHERE KeyName = ?"
        .Parameters.Append .CreateParameter("p1", adVarChar, adParamInput, 20, keyName)
        Set rs = .Execute
        If rs.EOF Then
            GetKeyID = -1
        Else
            GetKeyID = rs.Fields(0)
        End If
        .ActiveConnection.Close
    End With
    
End Function

Function dbConnect(db) As ADODB.Connection
   
    Set dbConnect = New ADODB.Connection
    With dbConnect
        .Provider = "Microsoft.ACE.OLEDB.12.0"
        .ConnectionString = db
        .Open
    End With

End Function

评论

0赞 Joel Coehoorn 9/9/2023
不。连接应该是短期的,而不是重复使用的,即使在旧的 ADO 中也是如此。不过,您可以使用一种方法来创建并返回隐藏某些样板的连接对象。
1赞 Joel Coehoorn 9/9/2023 #2

连接字符串应更像这样,而不仅仅是文件路径:

Provider=Microsoft.ACE.OLEDB.12.0;Data Source=O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.accdb;

有关连接字符串的详细信息,请参阅:

https://www.connectionstrings.com/access/

我在这里看到的另一件事是它很可能是共享驱动器。值得一提的是,共享共享驱动器不是系统 (OS) 级别的构造,而是仅限于特定会话,因此一个用户的 O: 驱动器可能不适用于另一个用户,即使在同一台计算机上也是如此。O:

1赞 HansUp 9/9/2023 #3

您告诉我们错误发生在函数的连接步骤中。因此,我建议您将注意力集中在该特定操作(打开 ADODB 连接)上。.OpenGetKeyID

这是在我的系统上运行没有错误的示例代码。将 的值 back 更改为 your 的值并对其进行测试。如果成功,它将在“即时”窗口中打印 1(用于 )。dbPathState

Public Sub test_connection()
    Dim conn As Object
    Dim DataSource As String
    Dim dbPath As String
    
    'dbPath = "O:\Department\Engineering\Einstein\00 - Systems Engineering\04 - Databases\VerificationLogDB.laccdb"
    dbPath = "C:\Users\hansu\AppData\Roaming\AccessApps\AppStarter.accdb"
    DataSource = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & dbPath
    Set conn = CreateObject("ADODB.Connection")
     
    With conn
        .ConnectionString = DataSource
        .Open
        Debug.Print .State
    End With
End Sub

注意,然后是行。您的代码也不包括。这就是为什么你发现“我的数据源在我的局部变量窗口中显示为空”的原因。如果没有,Access 将被视为未声明的变体,并且由于您从未为其分配值,因此它仍然是空变体。所以连接自然会失败。Dim DataSource As StringDataSource = Dim DataSourceDataSourceOpen

添加到代码模块的“声明”部分。然后,至少 Access 可以提醒您注意未声明的变量。Option Explicit

此外,您似乎正在尝试连接到锁定文件。请改为连接到数据库。我的猜测是你想连接到(accdb而不是laccdb)。VerificationLogDB.laccdbVerificationLogDB.accdb

评论

0赞 St3althPatchin 9/11/2023
添加您提供的代码时,我还能够得到“1”结果。我还看到我调用的 Access 在 accdb 中添加了一个“l”。我已经进行了更正,但似乎我仍然出错。现在声明 No value gives for one or more required parameters.它在突出显示错误时特别指示rs.Open strSQL, ConnObj
0赞 HansUp 9/11/2023
发生这种情况时,请执行,然后从“即时”窗口复制语句文本。在查询设计器中创建一个新查询,切换到“SQL 视图”,粘贴复制的文本,然后尝试运行该查询。如果 Access 认为有一个参数需要一个值,它将弹出一个输入框,要求提供一个值,并且该输入对话框将包括 Access 认为是该参数的任何“名称”。叫什么名字?Debug.Print strSQL