【发布时间】:2014-01-21 23:52:08
【问题描述】:
我在 MS Office 应用程序(用于自动化和 ETL 流程)中使用 VBA 有几年的经验,但直到最近才需要在 MS Access 中处理表单。我正在为我设计的数据库设计一些简单的数据提取表单,但我正忙于一项看似简单的任务。
目标:我需要一个数据表子窗体来显示从主窗体上的控件动态构建的 SQL 语句返回的记录。
在我的主窗体上,我有一个按钮,当用户单击它时,该按钮会将用户在其他用户窗体控件中指定的信息编译为 SQL 查询,然后运行该查询,以便子窗体显示结果记录。
无论我做什么,我都无法让它工作。我不断收到(无论如何大部分时间)Microsoft Visual Basic 运行时错误“'2467':您输入的表达式指的是已关闭或不存在的对象。”这就是我使用下面显示的代码时遇到的错误。我不知道我是否需要在任何代码运行后立即启动子表单或什么。我已经尝试了其他代码论坛中也无法使用的其他代码变体,但我似乎发现了几个论坛主题,包括 Stack Overflow 上的一些主题,这些主题表明我下面的代码应该可以工作。
所附图片显示了基本主窗体的外观。我已经标记了用户将单击的按钮 (btnDisplaySWData) 以编译从尚未包含的控件创建的 SQL,但这不是问题。我只是硬编码一个 SQL 语句,如代码 sn-p 所示,试图找出这个问题。如前所述,我希望记录显示在名为 dataDisplaySubform 的子表单中。 “JUNK”是 Access 数据库中的一个表,我可以使用下面的 SQL 代码合法地查询它,我只是将其用于测试目的,直到我弄清楚这一点。显示的数据表单(名为 frmDataExtract)中的所有代码都包含下面代码窗口中的内容。
Option Compare Database
Option Explicit
Public Sub btnDisplaySWData_Click()
Dim pSQL As String
pSQL = "SELECT JUNK.agency_ID, JUNK.agency_desc FROM JUNK"
Me.dataDisplaySubform.Form.RecordSource = pSQL
End Sub
该表单名为 dataDisplaySubform,如下面选中子表单的属性截图所示。
这就是整个表单布局的样子
我已经搜索了几个论坛站点,并且还尝试了搜索 Stack Overflow 的各种术语以找到解决我的问题的潜在解决方案,但即使原始线程被发布者标记为已解决,也没有任何工作。我花了太多时间,大约 2 个工作日,试图找出我做错了什么,但还没有弄清楚。
感谢任何可以帮助我朝着正确方向前进的人,这让我发疯了。
谢谢, --TB
TURKISHGOLD 编辑解决方案
好吧,我想我是自己想出来的,尽管 HansUp 帮助我走上了这条路,提到子表单源对象没有分配任何东西。就我而言,将源对象分配给表单并不是 HansUp 所建议的正确解决方案。相反,保存的查询似乎可以让它做我想做的事。
不确定是否有更好的方法来执行此操作,但您似乎需要设置一个虚拟的、几乎是占位符的查询,因此您可以在 VBA 中将子表单 Source Object 设置为它。 像这样的占位符查询:
SELECT * FROM JUNK WHERE JUNK.agency_ID ="_";
以上 Access 查询保存为名称“TESTQUERY”。它不显示任何内容,但满足将源对象分配给某些内容的需要,本质上是在表单视图中查看主表单时实例化子表单。因此,使用占位符保存的查询,您可以将 RecordSource 重新分配给通过主窗体上的用户界面控件组合在一起的任何 SQL 字符串,如下所示:
Public Sub btnDisplaySWData_Click()
Dim pSQL As String
pSQL = "SELECT JUNK.agency_ID, JUNK.agency_desc FROM JUNK"
Me.dataDisplaySubform.SourceObject = "Query.TESTQUERY"
Me.dataDisplaySubform.Form.RecordSource = pSQL
Me.dataDisplaySubform.Requery
End Sub
当表单投入生产时,存储在 pSQL 字符串变量中的硬编码 SQL 语句将通过用户在主表单控件上的输入组合在一起。
所以现在,当单击 btnDisplaySWData 时,它会执行我尝试执行的操作并显示记录。
【问题讨论】:
-
子表单的名称与要显示的表单无关。屏幕截图清楚地显示没有为子表单控件设置表单。子表单控件可以放置在表单上,但在您将源对象属性设置为合法(现有)表单之前,它不会显示任何表单。如果没有要显示的表单,则无法设置数据源。因此,在您从源对象属性中看到的下拉列表中选择一个表单之前,您拥有正确的子表单控件名称这一事实是没有意义的。此处无需使用或设置虚拟查询。您必须设置源对象属性 = 合法形式。