通过 VBA 设置表单的记录集也是设置其记录源

Posted

技术标签:

【中文标题】通过 VBA 设置表单的记录集也是设置其记录源【英文标题】:Setting a form's recordset via VBA is also setting its recordsource 【发布时间】:2014-10-18 04:08:27 【问题描述】:

我有一个 Access 2010 数据库,该数据库链接到 SQL Azure 后端(是的,我知道这并不理想,并且正在逐步淘汰)。在后端,我有一个存储过程,我想在每次加载新记录时使用它来填充只读子表单。我试图通过在 VBA 中生成记录集,然后设置子窗体的 RecordSet 属性来做到这一点。它确实有效,但有一个令人讨厌的副作用。

当我设置RecordSet 属性时,它似乎也在设置子表单的RecordSource 属性。 RecordSource 是 Access 无法解析的,因为它是对后端的调用。如果我尝试使用 DAO 直通查询来生成记录集,RecordSource 看起来像:

EXEC dbo.GetDuplicateAddressesByManufacturer N'...', N'...', N'...'

如果我尝试使用 ADO 命令生成记录集,它看起来像:

 call dbo.GetDuplicateAddressesByManufacturer ?, ?, ? 

只要我尝试移动到下一条记录,Access 就会引发错误,因为它首先尝试为子表单加载新记录,并且无法打开它所看到的子表单的 RecordSource。如果我正在尝试 DAO 路由,它会告诉我“无效的 SQL 语句”,如果我使用 ADO,它会告诉我“无法初始化数据提供程序”。

有人知道我该如何解决这个问题吗?难道不设置 RecordSource 就可以设置 RecordSet 属性吗?我可以发誓我以前做过,但也许我从来没有注意到 RecordSource 也被设置了。

如果做不到这一点,有没有办法可以在 Form_Current 事件之前插入一些代码来删除子表单的 RecordSource?我每次用来设置 RecordSet 的代码都很好用——问题是在我的代码工作之前引发的错误。关闭错误消息后,一切正常,但显然我不希望用户每次更改记录时都收到错误消息。

如果所有其他方法都失败了,我想我总是可以使用查询来填充本地临时表,但每次有人移动到新记录时似乎都会产生很多开销。

【问题讨论】:

【参考方案1】:

为什么要使用存储过程呢?只需将子表单链接到表格,然后设置链接主/子设置。您只需下拉所需的记录。

如果子表单是一个包含多个表的复杂查询,那么您当然希望数据连接等发生在服务器端,然后再次简单地创建一个视图并再次将子表单源设置为该视图(以及链接主控) /child 设置将为您完成所有肮脏的工作)。

您没有理由不能创建传递查询并将其简单地分配给表单记录源。

在查询中放置什么“垃圾”并不重要,包括 RAW T-SQL。

虽然您可以使用这种临时想法加载 DAO reocrdset,但您确实不需要这样做。我想你这样做是出于某种愉快的原因,至少如果你必须这样做,那么 recordSoruce 将成为传递的名称,而不是你的原始 T-SQL。

然而,真的,只是转储所有的记录集垃圾,然后就去吧:

Me.MySubForm.Form.RecordSource = "my pass though query". 

因此上面只有一行。

您做所有这些手支架是为了提高性能,那么归根结底,为什么您的主窗体允许导航?您应该构建一个搜索屏幕,显示结果,让用户选择一行,然后启动主表单以编辑/显示 ONE 记录以及子表单数据。

当他们关闭时,他们会重新搜索下一位客户等。这种方法也因此解决了您混乱的导航问题。这也是网络和大多数软件以这种方式工作的原因(它减少了带宽问题)。

但是,如果您必须有导航,并且由于某种原因不能使用视图并且不能让 Access 使用链接主/子设置来完成您的繁琐工作?

然后在当前事件的表单中,您可以修改传递并简单地将其重新分配给子表单。

例如:

With CurrentDb.QueryDefs("qPass")
   .SQL = "select * from FaxBook3 where id = 3"
End With
'
Me.RecordSource = "qpass"

现在我如何在上面的传递查询中使用 RAW T-SQL,然后简单地将传递分配给表单记录源(在您的情况下,您分配给子表单。

 Me.MySubForm.Form.RecordSource = above

上面的.SQL没有理由不能成为你的存储过程

.SQL = "Exec your-storedProcedure " & strVbaStringParmater

然后再次分配表单(或子表单)recordSource。

所以你真的不需要在代码中创建一些 reocrdset,它不会给你带来任何性能提升,但会导致你编写更多代码并遇到你在帖子中概述的问题。

【讨论】:

谢谢,阿尔伯特。我需要导航和存储过程是有原因的,但是当我回到我的计算机时,我会尝试使用 querydef 方法。

以上是关于通过 VBA 设置表单的记录集也是设置其记录源的主要内容,如果未能解决你的问题,请参考以下文章

在表单加载之前捕获记录源错误 - 访问

即使没有找到匹配项,MS Access 记录集也会继续搜索?

为啥我不能从 VBA 中的多实例表单中获取当前记录 ID

VBA 使用变量表名设置记录

如何更改我的 VBA 脚本以显示特定字段设置为“空”的所有记录?

使用 VBA 从主菜单打开一个表单,其中一个字段为空/空白