如何使用 .AfterUpdate 数据宏更新同一个表中的多条记录,而不会出现“数据宏资源限制已达到”错误。

Posted

技术标签:

【中文标题】如何使用 .AfterUpdate 数据宏更新同一个表中的多条记录,而不会出现“数据宏资源限制已达到”错误。【英文标题】:How to update multiple records in same table using .AfterUpdate data macro without error "A data macro resource limit was hit." 【发布时间】:2017-07-07 15:13:49 【问题描述】:

我有一个 tblItems 表,其中包含库存项目列表。该表有许多列来描述这些项目,包括 SupplierName、SupplierOrderNumber 和 PredictedArrivalDate 列。

如果我从供应商处订购多件新商品,我将在表格中分别记录每件商品,并使用相同的供应商名称、订单号和预计到货日期。

我想添加一个数据宏,这样如果我更新一条记录的 PredictedArrivalDate,该值将被复制到具有相同 SupplierName 和 SupplierOrderNumber 的其他记录/项目的 PredictedArrivalDate 列。

我得到的最接近的是:

SetLocalVar (MySupplierName, [SupplierName])
SetLocalVar (MySupplierOrderNumber , [SupplierOrderNumber ])
SetLocalVar (MyPredictedArrivalDate, [PredictedArrivalDate])

For Each Record in tblItems
    Where Condition = [SupplierOrderNumber] Like [MySupplierOrderNumber] And [SupplierName] Like [MySupplierName] And [PredictedArrivalDate]<>[MyPredictedArrivalDate]
    Alias OtherRecords

EditRecord
    SetField ([OtherRecords].[PredictedArrivalDate], [MyPredictedArrivalDate])
End EditRecord

但是,当我运行这个时,只有5条记录更新,并且错误日志报告错误-20341:

"达到了数据宏资源限制。这可能是由数据引起的 宏递归调用自身。 Updated() 函数可能是 用于检测记录中的哪个字段已更新以提供帮助 防止递归调用。”

我怎样才能让它工作?

【问题讨论】:

听起来您的表可以使用一些重构。为什么不将 tblItems 中特定于订单的列拆分为新的OrderParts 表或类似的表? 我尝试过拆分表,但后来我只是将相同的 FOR 循环应用于新表,并再次遇到相同的错误。我需要一种方法来从表外触发此 FOR 循环,但要在 .AfterUpdate 事件上。 这个函数归结为进行查找和替换,但基于查询并接受一些初始参数。 如果它被拆分为父表,但您不需要任何循环/触发器,因为数据只存在于一条记录中。 好的。我知道你要去哪里。当我有时间时,我必须尝试一下。我确实找到了一个基于表单的宏解决方案,它可以工作并给我一个临时修复,我很快就会在这里发布。 【参考方案1】:

我不喜欢使用宏来做任何事情,所以我会使用 VBA 和记录集/动作查询来进行更新。

您可以通过将本地 var 设置为等于其结果来调用数据宏中的用户定义函数。

Access 不喜欢数据宏自行触发(您正在使用 on update 宏并在不同记录上更新同一个表中的字段),因为存在意外创建无限循环的风险。看起来您触发了一项旨在防止这种情况的措施。我会尽量避免这种情况。

注意:当您从 Access 外部(例如通过 ODBC)链接到表时,在数据宏中使用用户定义的函数可能会导致问题。

【讨论】:

谢谢。这几乎就是我认为正在发生的事情,但我并不完全确定。【参考方案2】:

这不是一个好的解决方案(它不是数据宏),但它确实可以作为临时修复。

我创建了一个名为“updatePredictedArrivalDate”的更新查询:

PARAMETERS
ItemID Long,
MyPredictedArrivalDate DateTime,
MySupplierName Text ( 255 ),
MySupplierOrderNumber Text ( 255 );

UPDATE tblItems
SET tblItems.PredictedArrivalDate = [MyPredictedArrivalDate]
WHERE (((tblItems.SupplierName) = [MySupplierName])
AND   ((tblItems.SupplierOrderNumber) = [MySupplierOrderNumber])
AND   ((tblItems.ID) <> [ItemID]));

在 PredictedArrivalDate 表单字段 .AfterUpdate 事件中,我添加了这个宏:

IF [PredictedArrivalDate].[OldValue]<>[PredictedArrivalDate] Or [PredictedArrivalDate]<>""

OpenQuery (updatePredictedArrivalDate, Datasheet, Edit, [ID], [PredictedArrivalDate], [SupplierName], [SupplierOrderNumber])

我现在必须记住将此 .AfterUpdate 事件添加到我创建的用于修改该特定字段的任何其他表单中。

如果有人有更好的解决方案,请告诉我。

【讨论】:

以上是关于如何使用 .AfterUpdate 数据宏更新同一个表中的多条记录,而不会出现“数据宏资源限制已达到”错误。的主要内容,如果未能解决你的问题,请参考以下文章

MS Access“更新后”事件:引发错误

如何使用 Ruby 读取和写入同一个 EXCEL 文件?

需要在同一个Access表中创建一条记录的副本,然后更新数据

MS Access 事件驱动数据宏更新表(示例)

如何在同一个 crate 中使用由另一个宏定义的宏?

AFTER UPDATE 触发器使用更新表中的聚合