即使有从 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 一切顺利。
已尝试但结果仍然相同的事情列表:
- 添加了最后移动和首先移动命令
- 尝试了游标位置、游标类型、锁类型的所有可能组合
- 尝试执行命令
- 尝试使用不同的 MS 访问 table
- 尝试了早期和晚期绑定技术
下面是我的查询,下面 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 中未提及,但很容易重现此效果。
很少有人会在问题中包含他们设置的整个手表列表,但我不确定如果没有这些信息,这个问题是否可以回答
我正在使用 VBA 查询我的访问权限 table 并将查询结果写入 excel。
EOF 始终为真,但 BOF 为假 - 即使记录数为 1、14 或 100。可能会出现什么错误?我可以看到记录数大于零。获取字符串值中有数据。因此,除了 Headers 之外,没有数据写入目标 sheet。 headers 一切顺利。
已尝试但结果仍然相同的事情列表:
- 添加了最后移动和首先移动命令
- 尝试了游标位置、游标类型、锁类型的所有可能组合
- 尝试执行命令
- 尝试使用不同的 MS 访问 table
- 尝试了早期和晚期绑定技术
下面是我的查询,下面 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 中未提及,但很容易重现此效果。
很少有人会在问题中包含他们设置的整个手表列表,但我不确定如果没有这些信息,这个问题是否可以回答