Microsoft Access中如何导入修改后的Data Macro至表格?
Access 2019/365数据宏导入失败:批量部署审计追踪的解决方法
问题概述
在为多表格批量创建审计追踪时,从宏设计界面复制XML代码修改后导入Access,报错:Microsoft Access could not understand the macro format.
问题根源
你提供的XML代码存在结构错误:多个独立的<DataMacros>根节点被直接拼接。Access要求数据宏XML必须有且仅有一个<DataMacros>根节点,所有<DataMacro>事件宏都作为其子节点存在。
修正后的XML代码
<DataMacros xmlns="http://schemas.microsoft.com/office/accessservices/2009/11/application"> <DataMacro Event="AfterInsert"> <Statements> <CreateRecord Collapsed="true"> <Data Alias="AT"> <Reference>z_sys_tblAuditTrail</Reference> </Data> <Statements> <Action Name="SetField"> <Argument Name="Field">AT.TableName</Argument> <Argument Name="Value">"_ref_tblOfficeLocatons"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.RecordID</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeBy</Argument> <Argument Name="Value">fDisplayUpdateUser()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.FieldName</Argument> <Argument Name="Value">"MailboxID"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.NewValue</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeDate</Argument> <Argument Name="Value">Now()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.Action</Argument> <Argument Name="Value">"I"</Argument> </Action> </Statements> </CreateRecord> </Statements> </DataMacro> <DataMacro Event="AfterInsert"> <Statements> <CreateRecord Collapsed="true"> <Data Alias="AT"> <Reference>z_sys_tblAuditTrail</Reference> </Data> <Statements> <Action Name="SetField"> <Argument Name="Field">AT.TableName</Argument> <Argument Name="Value">"_ref_tblOfficeLocatons"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.RecordID</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeBy</Argument> <Argument Name="Value">fDisplayUpdateUser()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.FieldName</Argument> <Argument Name="Value">"Building"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.NewValue</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[Building]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeDate</Argument> <Argument Name="Value">Now()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.Action</Argument> <Argument Name="Value">"I"</Argument> </Action> </Statements> </CreateRecord> </Statements> </DataMacro> <DataMacro Event="AfterInsert"> <Statements> <CreateRecord Collapsed="true"> <Data Alias="AT"> <Reference>z_sys_tblAuditTrail</Reference> </Data> <Statements> <Action Name="SetField"> <Argument Name="Field">AT.TableName</Argument> <Argument Name="Value">"_ref_tblOfficeLocatons"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.RecordID</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeBy</Argument> <Argument Name="Value">fDisplayUpdateUser()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.FieldName</Argument> <Argument Name="Value">"Room"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.NewValue</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[Room]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeDate</Argument> <Argument Name="Value">Now()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.Action</Argument> <Argument Name="Value">"I"</Argument> </Action> </Statements> </CreateRecord> </Statements> </DataMacro> <DataMacro Event="AfterInsert"> <Statements> <CreateRecord Collapsed="true"> <Data Alias="AT"> <Reference>z_sys_tblAuditTrail</Reference> </Data> <Statements> <Action Name="SetField"> <Argument Name="Field">AT.TableName</Argument> <Argument Name="Value">"_ref_tblOfficeLocatons"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.RecordID</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeBy</Argument> <Argument Name="Value">fDisplayUpdateUser()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.FieldName</Argument> <Argument Name="Value">"RoomDescr"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.NewValue</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[RoomDescr]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeDate</Argument> <Argument Name="Value">Now()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.Action</Argument> <Argument Name="Value">"I"</Argument> </Action> </Statements> </CreateRecord> </Statements> </DataMacro> <DataMacro Event="AfterInsert"> <Statements> <CreateRecord Collapsed="true"> <Data Alias="AT"> <Reference>z_sys_tblAuditTrail</Reference> </Data> <Statements> <Action Name="SetField"> <Argument Name="Field">AT.TableName</Argument> <Argument Name="Value">"_ref_tblOfficeLocatons"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.RecordID</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[MailboxID]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeBy</Argument> <Argument Name="Value">fDisplayUpdateUser()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.FieldName</Argument> <Argument Name="Value">"RoomType"</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.NewValue</Argument> <Argument Name="Value">[_ref_tblOfficeLocatons].[RoomType]</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.ChangeDate</Argument> <Argument Name="Value">Now()</Argument> </Action> <Action Name="SetField"> <Argument Name="Field">AT.Action</Argument> <Argument Name="Value">"I"</Argument> </Action> </Statements> </CreateRecord> </Statements> </DataMacro> </DataMacros>
正确导入步骤
- 打开目标表格的数据宏设计界面:右键表格 → 表格设计 → 切换到表格工具/设计选项卡 → 点击创建数据宏 → 选择对应的事件(如AfterInsert)
- 在宏设计界面,点击宏工具/设计选项卡 → 加载宏 → 选择修正后的XML文件;或直接粘贴修正后的XML代码到设计界面
- 保存宏并关闭设计窗口,测试表格操作是否触发审计记录
批量部署优化建议
手动修改XML效率低且易出错,可使用VBA代码自动生成数据宏:
- 遍历数据库中需要添加审计的表格
- 针对每个表格的字段,自动生成AfterInsert、AfterUpdate、AfterDelete事件的审计宏代码
- 通过Access的DAO对象模型将宏添加到目标表格
内容的提问来源于stack exchange,提问作者psycoperl
相关产品推荐
相关产品推荐

