You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Power Apps如何实现审计追踪?需保留旧值避免覆盖

在Power Apps中实现审计追踪的完整方案

我来帮你搞定这个审计追踪的问题!你现在的核心痛点是用Patch时旧值被覆盖对吧?其实关键思路就是:在执行主表操作前先把旧值存起来,然后把审计记录追加到Audit Trail表,而不是去覆盖任何记录。下面一步步给你讲具体实现:

一、先搞定Audit Trail表的结构

首先确保你的数据源里已经建好Audit Trail表,字段要和你需求匹配:

  • ID:自动生成的主键(比如用数据源自带的自动编号)
  • DATE:日期时间类型(记录操作时间)
  • USERNAME:文本类型(记录操作人)
  • FORMNAME:文本类型(记录操作的表单/屏幕名)
  • ACTION:文本类型(可选值:New/Edit/Delete/Print)
  • FIELDNAME:文本类型(记录被操作的字段名)
  • OLDVALUE:文本类型(存旧值,兼容性最强)
  • NEWVALUE:文本类型(存新值)

二、分场景实现审计记录

1. 新建记录的审计

新建时没有旧值,所以在创建主表记录后,直接往Audit Trail加一条记录就行:

// 第一步:创建主表的新记录
Patch(
    你的主表名称,
    Defaults(你的主表名称),
    {
        Risk: txtRisk.Text, // 假设你的Risk字段是输入框txtRisk
        // 其他字段按需添加...
    }
);

// 第二步:写入审计追踪
Patch(
    AuditTrail,
    Defaults(AuditTrail),
    {
        DATE: Now(),
        USERNAME: User().FullName,
        FORMNAME: "Form1", // 或者用Screen.Name自动获取当前屏幕名
        ACTION: "New",
        FIELDNAME: "Risk",
        OLDVALUE: "", // 新建无旧值
        NEWVALUE: txtRisk.Text
    }
);

2. 编辑记录的审计(重点解决旧值覆盖问题)

敲黑板!编辑的核心是提前把原始记录存到变量里,这样就算Patch修改了主表,旧值还在变量里不会丢:

  • 首先,在编辑表单的OnVisible事件里,把要编辑的原始记录存起来:
Set(varOriginalRecord, BrowseGallery.Selected); // 假设从浏览画廊选的待编辑记录
  • 然后在保存按钮的OnSelect事件里,先对比新旧值,有变化的字段再写入审计:
// 先执行主表的修改操作
SubmitForm(EditForm1); // 或者用Patch,看你习惯

// 检查Risk字段是否有变化,有就写审计
If(
    varOriginalRecord.Risk <> EditForm1.LastSubmit.Risk,
    Patch(
        AuditTrail,
        Defaults(AuditTrail),
        {
            DATE: Now(),
            USERNAME: User().FullName,
            FORMNAME: "Form1",
            ACTION: "Edit",
            FIELDNAME: "Risk",
            OLDVALUE: varOriginalRecord.Risk,
            NEWVALUE: EditForm1.LastSubmit.Risk
        }
    )
);

// 其他字段同理,复制上面的If块改字段名就行

3. 删除记录的审计

删除前先把要删的记录存下来,删完再写审计:

// 第一步:存储要删除的记录
Set(varRecordToDelete, BrowseGallery.Selected);

// 第二步:删除主表记录
Remove(你的主表名称, varRecordToDelete);

// 第三步:写入审计(以Risk字段为例)
Patch(
    AuditTrail,
    Defaults(AuditTrail),
    {
        DATE: Now(),
        USERNAME: User().FullName,
        FORMNAME: "Form1",
        ACTION: "Delete",
        FIELDNAME: "Risk",
        OLDVALUE: varRecordToDelete.Risk,
        NEWVALUE: "" // 删除后无新值
    }
);

4. 打印操作的审计

打印不修改数据,所以记录操作本身就行,新旧值可以留空或者记录当前值:

// 点击打印按钮时触发
Patch(
    AuditTrail,
    Defaults(AuditTrail),
    {
        DATE: Now(),
        USERNAME: User().FullName,
        FORMNAME: "Form1",
        ACTION: "Print",
        FIELDNAME: "Risk", // 也可以写"所有字段"
        OLDVALUE: BrowseGallery.Selected.Risk,
        NEWVALUE: BrowseGallery.Selected.Risk // 打印前后值不变
    }
);

// 执行打印逻辑
Print();

三、优化技巧:封装审计函数

重复写Patch太麻烦?可以把审计逻辑做成自定义函数,复用性拉满:

Function CreateAuditLog(formName, action, fieldName, oldVal, newVal)
    Patch(
        AuditTrail,
        Defaults(AuditTrail),
        {
            DATE: Now(),
            USERNAME: User().FullName,
            FORMNAME: formName,
            ACTION: action,
            FIELDNAME: fieldName,
            OLDVALUE: oldVal,
            NEWVALUE: newVal
        }
    )
End Function

调用的时候就简化成:

CreateAuditLog("Form1", "Edit", "Risk", varOriginalRecord.Risk, EditForm1.LastSubmit.Risk)

四、额外提醒

  • 权限控制:给Audit Trail表设置权限,普通用户只能追加记录,不能修改/删除,防止审计记录被篡改。
  • 时区问题:如果是跨国团队,建议用UTCNow()代替Now(),再按需转换成本地时间。
  • 批量字段处理:如果要记录所有修改的字段,可以用ForAll遍历主表的所有字段,自动对比新旧值写入审计,不用手动写每个字段的判断。

内容的提问来源于stack exchange,提问作者Beme MD

火山引擎 最新活动