即使有从 VBA SQL 返回的记录,EOF 值始终为真

EOF value is always true even if there is record returned from VBA SQL

我正在使用 VBA 查询我的访问权限 table 并将查询结果写入 excel。

EOF 始终为真,但 BOF 为假 - 即使记录数为 1、14 或 100。可能会出现什么错误?我可以看到记录数大于零。获取字符串值中有数据。因此,除了 Headers 之外,没有数据写入目标 sheet。 headers 一切顺利。

已尝试但结果仍然相同的事情列表:

  1. 添加了最后移动和首先移动命令
  2. 尝试了游标位置、游标类型、锁类型的所有可能组合
  3. 尝试执行命令
  4. 尝试使用不同的 MS 访问 table
  5. 尝试了早期和晚期绑定技术

下面是我的查询,下面 link 是我的记录集在 SQL 打开语句后的样子。

    Const MyConn = "Access DB location"
    Dim con As ADODB.Connection
    Dim rs As ADODB.Recordset
    Set con = New ADODB.Connection
    With con
      .Provider = "Microsoft.ACE.OLEDB.12.0"
      .Open MyConn
    End With

    QuerySql = "SELECT * FROM Store_Location"

    Set rs = New ADODB.Recordset
    rs.CursorLocation = adUseClient
    rs.Open QuerySql, con, adOpenStatic, adLockReadOnly, adCmdUnknown
    rs.MoveLast
    rs.MoveFirst


    i = 0  
    For i = 0 To rs.Fields.Count - 1
        Sheets("Search_Temp").Cells(1, i + 1) = rs.Fields(i).Name
    Next i

    Range("A2").CopyFromRecordset rs  


    rs.Close
    Set rs = Nothing
    con.Close
    Set con = Nothing

在调试时,这是我的记录集的样子:

基于 this answer to a similar question,对 Recordset 对象调用 getString 具有将记录集移动到 EOF 的 side-effect。

您没有在代码中的任何地方调用 getString,但您在 rs.getString 上添加了一个监视,它作为监视 window 中的最后一个条目可见。如果您在 rs.getString 上有一个手表,并且您在 rs 打开的代码中有一个断点,那么该断点将导致记录集移动到 EOF。

根据断点发生的位置,这可能不会导致任何问题(例如,如果记录集已经处于 EOF)但是,在这种情况下,它会在您从记录集中复制数据之前将记录集移动到 EOF .

要解决此问题,请移除 rs.getString 上的手表。一般而言,在 Watches window 中放置物品可能不是一个好主意。您也可以通过在记录集打开时不设置任何断点来避免此问题,但完全删除手表会更可靠。

getString 将记录集移动到 EOF 的问题在 ADO documentation 中未提及,但很容易重现此效果。

很少有人会在问题中包含他们设置的整个手表列表,但我不确定如果没有这些信息,这个问题是否可以回答