每个表单记录问题的 VBA/Access RecordSet

Posted

技术标签:

【中文标题】每个表单记录问题的 VBA/Access RecordSet【英文标题】:VBA/Access RecordSet per form record problem 【发布时间】:2009-09-25 21:19:37 【问题描述】:

我是 VBA 和 Access 的新手,在尝试使用我提出的另一个问题 (DLookup in Access not running until textBox clicked on in Form) 中提出的替代实现时遇到了这个问题

下面的代码运行,问题是 Me.Key 对于表单中显示的每条记录都是不同的,并且在表单打开事件中运行它意味着它仅从第一条记录中获取分配给 Me.Key 的第一个值。我怎样才能让这个运行,以便 Me.Key 对于显示的每条记录/行都不同?

Dim rs As DAO.Recordset 将 db 作为数据库 将 qdf 调暗为 QueryDef 将 prm 作为参数调暗 设置 db = CurrentDb 设置 qdf = db.QueryDefs("[MF INCOME - STREAM MONTHLY]") 对于 qdf.Parameters 中的每个 prm prm.Value = Eval(prm.Name) 下一次 设置 rs = qdf.OpenRecordset(dbOpenDynaset) rs.FindFirst "[MyMonth]=10 AND [Org_Type]='" & Me.Key & "'" Me.Oct = rs!SumVal '...其他月份的作业

【问题讨论】:

您可以通过记录集导航浏览表单的记录。但我建议您考虑是否最好打开一次记录集并通过 .FindFirst 导航,或者是否最好只打开每行记录的记录。 【参考方案1】:

我猜 Me.Key 是指位于表单详细信息部分的控件。在这种情况下,为了列出控件采用的所有值,您需要浏览所有记录。其中一种方法可以是:

Dim m_position as Long
for m_position = 1 to Me.recordset.recordcount
   me.seltop = m_position
   debug.print me.key
next m_position

很遗憾,您在浏览所有行时会看到屏幕闪烁。你当然可以在网上找到一些用于 VBA 的“screenFreezer”实用程序(只要我记得,就有一个叫做 LockWindowUpdate)。

另一种解决方案是浏览底层记录集的克隆(浏览记录集将引发与以前相同的屏幕行为)。假设 Me.Key 控件绑定到记录集的“Key”列,代码可以是:

Dim rsClone as DAO.recordset
set rsClone = Me.recordsetclone
if rsClone.EOF and rsClone.BOF then
Else
    rsClone.moveFirst
    Do while not rsClone.EOF
        debug.print rsCLone.fields("Key")
        rsClone.moveNext
    Loop
Endif
set rsClone = nothing

我最喜欢的是第一个,添加了“冻结”选项。您的代码可以管理表单的 seltop 和 selheight 值。这意味着您可以浏览用户选择的特定记录和/或在浏览完所有记录后返回到原始记录选择。

编辑:

根据@Ben 的评论,我将补充一点,如果您的“myControl”控件位于详细信息部分并且未绑定,那么您将无法管理每行一个值。当窗体显示为“连续”时,控件的所有行的值都相同。

如果您的“myControl”控件绑定到记录集的“myField”字段,则以下任何代码都会同时增加“myControl”控件值和“myField”字段值。您将能够在每一行上拥有不同的值:

解决方案 1:

Dim m_position as Long
for m_position = 1 to Me.recordset.recordcount
   me.seltop = m_position
   me.controls("myControl") = m_position
next m_position

解决方案 2:

Dim rsClone as DAO.recordset, _
    i as long

set rsClone = Me.recordsetclone
if rsClone.EOF and rsClone.BOF then
Else
    rsClone.moveFirst
    i = 1
    Do while not rsClone.EOF
        rsClone.fields("myField") = i
        rsClone.update
        rsClone.moveNext
        i = i+1
    Loop
Endif
set rsClone = nothing

【讨论】:

很抱歉回复晚了,其他项目妨碍了。这看起来可能很有帮助......眨眼对我的用户来说不是问题(我在一段时间内自愿参加的小型慈善机构),系统使用第一个解决方案替换了数百个便利贴、电子表格和电子邮件;)您发布了我可以遍历不同的键并查看每个键计算的正确值,但每次设置 Me.Oct= 时,每个记录的“Oct”字段都会获得相同的值。我以前没见过 SetTop ... 有什么方法可以使用该值为当前记录设置“Oct”吗? 感谢您的撰写,我认为在我的具体情况下这不起作用,但作为对原始问题的一般回答,它非常好。干杯。【参考方案2】:

您可以按照之前的建议尝试表单的当前事件:)

【讨论】:

它运行良好,并且使用任一事件显示数字......问题是 Me.Key 如果像这样运行它总是相同的值,而在表单本身中它每行不同。我觉得我犯了一些新手错误! 您说的是行,这表明您使用的是连续表单或数据表,如果是这种情况,您将需要查看不同的方法,例如设置查询或更改到一个单一的形式。 使用连续表单,所以我猜我需要做一些不同的事情,我不能使用单一表单方法,因为这种表单是作为用户导航器构建的 - 每行显示聚合财务信息可以多次深入了解,以查看(最终)个人收入以及慈善机构在每个项目/捐助者/收入流中收到的日期。是否有一种访问标准的方法可以根据该行中的值从数据库中填充表单的每行数据? 我想你可能需要一个合适的查询,因为连续表单的问题是只有绑定的控件会为每一行显示不同的数据。也许您可以为要从中显示数据的表提供架构? 感谢您对此的所有回答......到运行此查询时,大约有 8 个数据库表,可能使用了 30 个不同的列,所以我想我会使用所有这些而不是垃圾邮件仔细查看重新处理表单的 RecordSource 查询以包含月份。【参考方案3】:

完全不清楚您在该查询中需要什么参数。我建议您简单地构建一个不带任何参数的查询,其中包含您需要的所有列。

然后根据这个查询构建小表单。然后,您可以将此小表单拖放到现有表单中,并根据键值设置显示多个数据字段。 (只需确保为子表单设置链接主设置和子设置)。这是一个表单的样子:

(来源:shaw.ca)

因此,在上面的账单中,根据客户 ID 显示客户信息,并且是发票中的相关表格。

换句话说,要根据另一个表中的键值显示多个数据字段,您不需要编写一行代码。因此,您的整个过程和目标可以通过鼠标拖放来完成。我经常有发票或采购订单之类的东西,而我只有客户 ID。通过使用子表单,我可以显示整个地址和多个数据字段,而无需编写任何代码。当您从一条记录移动到另一条记录时,这整套字段将更新并始终显示正确的相关数据。

【讨论】:

感谢您的回答-我认为这会起作用,因为我在您的示例中显示了多个“键”或多个“客户”,我不认为我可以让一个连续的表格有一个子表格。

以上是关于每个表单记录问题的 VBA/Access RecordSet的主要内容,如果未能解决你的问题,请参考以下文章

vba access 2010更新过滤子表单

在子表单中搜索值 (vba Access 2013)

在不使用 VBA/Access 中的内联查询的情况下向表中添加记录

从 VBA (MS-Access) 填写 PDF 表单

如何在 access accde 中更新表单和编译的 vba

如何在 vba(access) 中将变量设置为我的表单列表框之一?