如何在Access VBA中引用已保存查询?编译报错求助
问题:Access VBA中无法直接引用已保存查询的报错问题
我尝试检查已保存查询中的记录,以此判断VBA是否应禁用某些窗体控件,编写代码如下:
Dim SavedQry SavedQry = Queries!qryCurrentItems 'or Queries("qryCurrentItems")
但无法编译,提示需定义变量“Queries”。既然可以用Forms!FormName!ControlName引用控件数据,为何查询不能这样引用?
补充说明
涉及的查询包含由窗体填充的参数,SQL代码如下:
SELECT tblColour.Colour AS Colour FROM tblColour INNER JOIN (tblGenCol INNER JOIN tblAutCol ON tblAutCol.Colour = tblGenCol.Colour) ON tblGenCol.Colour = tblColour.ID WHERE tblGenCol.Genre = Forms!frmColourChoice!cmbGenre AND tblAutCol.Author = Forms!frmColourChoice!cmbAuthor;
参数为Forms!frmColourChoice!cmbGenre和Forms!frmColourChoice!cmbAuthor。
解答
哈哈,这个问题我之前也踩过坑!其实Forms是Access VBA里的内置全局集合对象,所以你可以直接用Forms!FormName这种方式引用窗体或控件,但Queries不一样——它并不是全局可用的集合,准确来说,已保存的查询属于CurrentDb对象下的QueryDefs集合,必须通过CurrentDb来访问才行,这就是你代码编译报错的核心原因。
下面分两种场景给你正确的写法:
1. 仅需获取查询对象本身(比如查看查询定义、属性)
如果只是要拿到查询的对象引用,而不是读取记录,代码要这么写:
Dim SavedQry As QueryDef ' 通过CurrentDb的QueryDefs集合获取查询 Set SavedQry = CurrentDb.QueryDefs("qryCurrentItems")
注意这里必须用Set赋值,因为QueryDef是对象类型,不能像普通变量那样直接赋值。
2. 读取查询返回的记录(你的核心需求)
如果你是要检查查询有没有返回记录,以此判断是否禁用控件,那得用Recordset来打开这个查询,代码示例如下:
Dim rs As Recordset ' 打开查询对应的记录集 Set rs = CurrentDb.OpenRecordset("qryCurrentItems") ' 判断记录集是否为空 If rs.EOF And rs.BOF Then ' 没有记录,禁用目标控件 Forms!frmColourChoice!YourTargetControl.Enabled = False Else ' 存在记录,保持控件启用状态 Forms!frmColourChoice!YourTargetControl.Enabled = True End If ' 记得关闭记录集并释放资源,避免内存泄漏 rs.Close Set rs = Nothing
关于带参数查询的注意事项
你的查询依赖窗体控件作为参数,这里要提醒两点:
- 如果执行代码时
frmColourChoice窗体处于打开状态,Access会自动读取控件的值作为参数,不需要额外处理; - 如果窗体未打开,或者你不想依赖窗体状态,也可以手动给查询参数赋值,示例代码:
Dim qdf As QueryDef Dim rs As Recordset Set qdf = CurrentDb.QueryDefs("qryCurrentItems") ' 手动为参数赋值(替换成你需要的实际值) qdf.Parameters("Forms!frmColourChoice!cmbGenre").Value = "科幻" qdf.Parameters("Forms!frmColourChoice!cmbAuthor").Value = "Isaac Asimov" ' 通过QueryDef打开记录集 Set rs = qdf.OpenRecordset() ' 后续的记录判断逻辑和之前一致 If rs.EOF And rs.BOF Then ' 禁用控件逻辑 Else ' 启用控件逻辑 End If ' 释放资源 rs.Close Set rs = Nothing Set qdf = Nothing
总结一下:Forms是Access内置的全局集合,而查询属于当前数据库的QueryDefs集合,必须通过CurrentDb来访问,同时对象类型变量要用Set赋值——搞定这两点,你的问题就解决啦!
内容的提问来源于stack exchange,提问作者Isaac Reefman
相关产品推荐
相关产品推荐

