[英]Access VBA: Query returns no rows
I've written some VBA: 我写了一些VBA:
For x = LBound(resProdID) To UBound(resProdID)
CurrentDb.QueryDefs("qry_findID_vba").SQL = "" & _
"SELECT tbl_products.ProdID " & _
"FROM tbl_products " & _
"WHERE (tbl_products.Size = " & resSize(x) & " " & _
"AND tbl_products.SupplID = '" & Forms.frm_suppliers.SupplID & "')"
Dim dbs As DAO.Database
Dim rst As DAO.Recordset
Set dbs = CurrentDb()
Set rst = dbs.OpenRecordset("qry_findID_vba")
MsgBox rst.RecordCount
If rst.RecordCount <> 0 Then
rst.MoveLast
rst.MoveFirst
newProdID(x) = rst.Fields(0).Value
MsgBox "This never fires"
End If
rst.Close
Set rst = Nothing
dbs.Close
Set dbs = Nothing
Next x
What happens when I run it, is that a box pops up saying 0. I click Ok, and it repeats one more time. 当我运行它时会发生什么,是弹出一个框说0。我点击确定,然后再重复一次。 This is because I have two items in my resProdID-array.
这是因为我的resProdID数组中有两个项目。
However, if I open the query "qry_findID_vba" normally, it shows one row, like I expected. 但是,如果我正常打开查询“qry_findID_vba”,它会显示一行,就像我预期的那样。
Why doesn't VBA return this row? 为什么VBA不返回这一行? Have I done anything wrong?
我做错了什么吗?
Does this code messagebox the correct count? 此代码消息框是否正确计数? Can you use it instead?
你可以用吗? (Note, I haven't actually run it, so watch out for slight syntax errors.)
(注意,我实际上没有运行它,所以要注意轻微的语法错误。)
For x = LBound(resProdID) To UBound(resProdID)
Dim sql as String
Dim rst As DAO.Recordset
sql = "Select tbl_products.ProdID FROM tbl_products " & _
"WHERE (tbl_products.Size = " & resSize(x) & " " & _
"AND tbl_products.SupplID = '" & Forms.frm_suppliers.SupplID & "')"
Set rst = dbs.OpenRecordset(sql)
if not rst.eof then
MsgBox rst.fields("ProdID")
else
Msgbox "None found!"
end if
rst.Close
Set rst = Nothing
Next x
Also, try copying everything to a new form, and compacting and repairing the database ... 另外,尝试将所有内容复制到新表单,并压缩和修复数据库...
First off, you really should use QueryDef parameters. 首先,你真的应该使用QueryDef参数。 They provide a number of benefits:
它们提供了许多好处:
Your situation is exactly what parameterized QueryDefs are for. 您的情况正是参数化QueryDefs的用途。
Change the query text of qry_findID_vba
in Access to: 在Access
qry_findID_vba
的查询文本更改为:
PARAMETERS [ProductSize] Text (255), [SupplID] Number;
SELECT ProdID
FROM tbl_products
WHERE [tbl_products].[Size] = [ProductSize] AND [tbl_products].[SupplID] = [SupplID];
Replace the parameter data types according to your actual data types in the table. 根据表中的实际数据类型替换参数数据类型。
Next, when you're in a loop, don't re-define fixed variables again and again. 接下来,当您处于循环中时,不要一次又一次地重新定义固定变量。
dbs
and rst
don't need to be defined inside the loop at all. dbs
和rst
根本不需要在循环内定义。
Last point, the RecordCount
property does not work the way you think. 最后一点,
RecordCount
属性不像您想象的那样工作。 Quote from the docs , emphasis mine: 从文档引用 ,强调我的:
Use the
RecordCount
property to find out how many records in a Recordset or TableDef object have been accessed.使用
RecordCount
属性可以找出Recordset或TableDef对象中已访问的记录数。 The RecordCount property doesn't indicate how many records are contained in a dynaset–, snapshot–, or forward–only–type Recordset object until all records have been accessed.在访问所有记录之前 ,RecordCount属性不指示动态集,快照或仅前向类型Recordset对象中包含的记录数。 [...] To force the last record to be accessed, use the
MoveLast
method on the Recordset object.[...]要强制访问最后一条记录,请使用Recordset对象上的
MoveLast
方法。
Instead of calling MoveLast
, you can also check the .EOF
property. 您也可以检查
.EOF
属性,而不是调用MoveLast
。 If it is false, at least one record is available. 如果为false,则至少有一条记录可用。
For one-off query results like this one, I would recommend using the snapshot type Recordset. 对于像这样的一次性查询结果,我建议使用快照类型Recordset。 You can define which type you want to use when you call
OpenRecordset
on the QueryDef. 您可以在QueryDef上调用
OpenRecordset
时定义要使用的类型 。
Now: 现在:
Dim qry_findID_vba As DAO.QueryDef
Set qry_findID_vba = CurrentDb().QueryDefs("qry_findID_vba")
qry_findID_vba.Parameters("SupplID") = Forms.frm_suppliers.SupplID
For x = LBound(resProdID) To UBound(resProdID)
qry_findID_vba.Parameters("ProductSize") = resSize(x)
With qry_findID_vba.OpenRecordset(dbOpenSnapshot)
If Not .EOF Then
newProdID(x) = .Fields("ProdID").Value
End If
End With
Next x
Note that I use With
to save maintaining a helper rst
variable. 请注意,我使用
With
来保存辅助器rst
变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.