使用Excel VBA从Access数据库获取数据

时间:2019-02-19 22:42:35

标签: excel vba ms-access

我无法从Access数据库获取数据。我在网上找到了这段代码,它似乎可以工作(一定程度上),但是由于某种原因,它只会提取列标题,而不会提取查询中的任何数据。我对Access不太熟悉,这就是为什么我从离线状态中拉一个。

某人在一段时间前有类似的帖子,他们使用的代码是相同的,我们的查询是完全相同的,但是我们有不同的问题。 Importing Data From Access Using Excel VBA

有人会偶然知道为什么数据无法提取吗?

Sub getDataFromAccess()   

Dim DBFullName As String
Dim Connect As String, Source As String
Dim Connection As ADODB.Connection
Dim Recordset As ADODB.Recordset
Dim Col As Integer
Dim startdt As String
Dim stopdt As String
Dim refresh

refresh = MsgBox("Start New Query?", vbYesNo)
If refresh = vbYes Then
    Sheet1.Cells.Clear
    startdt = Application.InputBox("Please Input Start Date for Query (MM/DD/YYYY): ", "Start Date")
    stopdt = Application.InputBox("Please Input Stop Date for Query (MM/DD/YYYY): ", "Stop Date")

    DBFullName = "X:\MyDocuments\CMS\CMS Database.mdb"
    ' Open the connection
    Set Connection = New ADODB.Connection
    Connect = "Provider=Microsoft.ACE.OLEDB.12.0;"
    Connect = Connect & "Data Source=" & DBFullName & ";"
    Connection.Open ConnectionString:=Connect

    Set Recordset = New ADODB.Recordset
    With Recordset
        Source = "SELECT * FROM Tracking WHERE [Date_Logged] BETWEEN " & startdt & " AND " & stopdt & " ORDER BY [Date_Logged]"
        .Open Source:=Source, ActiveConnection:=Connection

        For Col = 0 To Recordset.Fields.Count - 1
            Range(“A1”).Offset(0, Col).Value = Recordset.Fields(Col).Name
        Next

        Range(“A1”).Offset(1, 0).CopyFromRecordset Recordset
    End With
    ActiveSheet.Columns.AutoFit
    Set Recordset = Nothing
    Connection.Close
    Set Connection = Nothing

End Sub

3 个答案:

答案 0 :(得分:1)

发布的代码缺少End If行。也许这只是张贴错误,因为代码不应编译和运行。

查询SQL的日期参数需要#个定界符:

Source = "SELECT * FROM Tracking WHERE [Date_Logged] BETWEEN #" & startdt & "# AND #" & stopdt & "# ORDER BY [Date_Logged]"

文本字段将需要撇号定界符。数字字段不需要定界符。

答案 1 :(得分:0)

几个小时后我解决了自己的问题的答案,我发现另一套工作正常的代码。谢谢大家的帮助!

Sub getdatamdb()
          Dim cn As Object, rs As Object
          Dim intColIndex As Integer
          Dim DBFullName As String
          Dim TargetRange As Range

10        DBFullName = "X:\MyDocuments\CMS\CMS Database.mdb"

20        On Error GoTo Whoa

30        Application.ScreenUpdating = False

40        Set TargetRange = Sheets("Sheet1").Range("A1")

50        Set cn = CreateObject("ADODB.Connection")
60        cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & DBFullName & ";"

70        Set rs = CreateObject("ADODB.Recordset")
80        rs.Open "SELECT * FROM Tracking WHERE [Date_Logged] BETWEEN #" & startdt & "# AND #" & stopdt & "# ORDER BY [Date_Logged]", cn, , , adCmdText

          ' Write the field names
90        For intColIndex = 0 To rs.Fields.Count - 1
100           TargetRange.Offset(1, intColIndex).Value = rs.Fields(intColIndex).Name
110       Next

          ' Write recordset
120       TargetRange.Offset(1, 0).CopyFromRecordset rs

LetsContinue:
130       Application.ScreenUpdating = True
140       On Error Resume Next
150       rs.Close
160       Set rs = Nothing
170       cn.Close
180       Set cn = Nothing
190       On Error GoTo 0
200       Exit Sub
Whoa:
210       MsgBox "Error Description :" & Err.Description & vbCrLf & _
             "Error at line     :" & Erl & vbCrLf & _
             "Error Number      :" & Err.Number
220       Resume LetsContinue
End If
End Sub

答案 2 :(得分:0)

在Excel中(尤其是从Access中)获取数据的一种简单方法是使用菜单“数据> Access”。这将创建到表的连接,您可以自由编辑该表。
至少,这是一种将调查范围限制为的简便方法:

  • 您键入的查询(连接字符串始终可以,因此,如果没有任何值,则来自查询)
  • 或VBA本身(如果表返回的是值,而不是相应的VBA Sub,那么您知道它来自VBA本身,而不是SQL)。

我跳过了连接的创建,因为它非常简单。最好将注意力集中在表格创建后可以执行的操作上。

编辑连接

选择表并转到菜单“数据>属性”,然后在窗口中单击右上角的按钮“连接属性”,即可获得连接的定义,即第一个选项卡中的某些属性以及第二个标签中的实际定义。

如果移动.mdb文件,则必须相应地更改连接字符串。不应有其他事件迫使您进行更改。

如果要键入实际的复杂查询,则需要:

  1. 将命令类型从“表”更改为“ SQL”
  2. 在底部的编辑框中键入查询。
    请注意,如果要在WHERE子句中定义动态参数,则可以使用问号(?)代替硬编码值。问号可以链接到常量(提示更改其值)或单元格。

在VBA中使用

检查完所有连接后,就有2种解决方案将其放入VBA。

请完全使用上面的代码;在这种情况下,您只需复制连接字符串和查询即可使事情变得简单。

或者,这是我的建议,我们之前构建的表可以在VBA中轻松更新。

使用这段代码:

WorksheetWithTable.ListObjects(1).QueryTable.Refresh 

您实际上不需要多于1行代码即可进行刷新。
如果您将查询设置为在修改单元格的值时自动刷新,那么您甚至根本不需要它。

注释#1:您可以使用表名来代替.ListObjects(1)中的索引。
节点#2:如果要在后台刷新查询,则刷新具有可选参数来驱动。 True表示VBA代码在移至下一条指令之前不会等待执行结束。 False显然是相反的。