You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Business Central表扩展字段更新异常:TotalPlannedTime值不显示问题

问题

为Business Central的「Prod. Order Routing Line」表新增字段TotalPlannedTime,用于计算并显示工序总计划时间,公式为:总计划时间 = Setup Time + (Input Quantity × Run Time),但字段始终显示0.0,无法正确更新。

已创建表扩展和带事件订阅的代码单元,但均未生效。该表已被第三方应用扩展,确认支持二次扩展。

现有代码

Table Extension 代码

tableextension 50109 ProdRtgLineExt extends "Prod. Order Routing Line"
{
    fields
    {
        field(50100; TotalPlannedTime; Decimal)
        {
            DataClassification = ToBeClassified;
            Caption = 'Total Planned Time';

            trigger OnValidate()
            begin
                //check if have setup or run time or both
                IF Rec."Setup Time" + "Run Time" > 0 then begin
                    Rec.TotalPlannedTime := "Setup Time" + ("Run Time" * "Input Quantity");
                    MESSAGE('OnValidate: TotalPlannedTime updated with value');
                end else begin
                    MESSAGE('OnValidate: TotalPlannedTime is 0');
                end;
            end;
        }
    }

    trigger OnBeforeInsert()
    begin
        Message('Entering OnBeforeInsert trigger');
        //check if have setup or run time or both
        IF Rec."Setup Time" + Rec."Run Time" > 0 THEN begin
            Rec.TotalPlannedTime := Rec."Setup Time" + (Rec."Run Time" * Rec."Input Quantity");
            MESSAGE('OnBeforeInsert: TotalPlannedTime updated with value');
        end else begin
            MESSAGE('OnBeforeInsert: TotalPlannedTime is 0');
        end;
    end;
}

Codeunit 代码

codeunit 50110 GetTotalTime
{
    [EventSubscriber(ObjectType::Table, database::"Prod. Order Routing Line", 'OnAfterInsertEvent', '', true, true)]
    local procedure OnAfterInsertEvent_YourTable(var Rec: Record "Prod. Order Routing Line")
    begin
        IF Rec."Setup Time" + Rec."Run Time" > 0 then
            Rec.TotalPlannedTime := Rec."Setup Time" + (Rec."Run Time" * Rec."Input Quantity");
    end;

    [EventSubscriber(ObjectType::Table, database::"Prod. Order Routing Line", 'OnAfterModifyEvent', '', true, true)]
    local procedure OnAfterModifyEvent_YourTable(var Rec: Record "Prod. Order Routing Line")
    begin
        IF Rec."Setup Time" + Rec."Run Time" > 0 THEN
            Rec.TotalPlannedTime := Rec."Setup Time" + (Rec."Run Time" * Rec."Input Quantity");
    end;
}

问题原因分析

  1. 触发时机不完整:当前仅在TotalPlannedTime自身被修改(OnValidate)或记录插入前(OnBeforeInsert)触发计算,而Setup Time、Run Time、Input Quantity这三个核心依赖字段被修改时,不会自动触发TotalPlannedTime的更新。
  2. 事件订阅未持久化数据:在OnAfterInsertEvent和OnAfterModifyEvent中仅修改了内存中的Rec变量,但未调用Modify()将更新写入数据库,导致修改不会被保存。
  3. 触发器执行顺序冲突:第三方扩展若也对OnBeforeInsert触发器做了修改,可能存在执行顺序问题,导致你的计算逻辑被覆盖或未生效。

解决方法

方案1:设置为计算字段(推荐)

直接将TotalPlannedTime定义为计算字段,系统会自动根据依赖字段的变化实时计算值,无需手动维护:

tableextension 50109 ProdRtgLineExt extends "Prod. Order Routing Line"
{
    fields
    {
        field(50100; TotalPlannedTime; Decimal)
        {
            DataClassification = ToBeClassified;
            Caption = 'Total Planned Time';
            CalcFormula = "Setup Time" + ("Run Time" * "Input Quantity");
            Editable = false; // 计算字段不可编辑,避免手动修改
        }
    }
}

此方式无需额外触发器或事件订阅,是最稳定的实现方案。

方案2:修复事件订阅逻辑(需存储字段时使用)

如果需要将字段值持久化到数据库,需修改事件订阅代码,确保修改后的数据被保存:

codeunit 50110 GetTotalTime
{
    [EventSubscriber(ObjectType::Table, database::"Prod. Order Routing Line", 'OnAfterInsertEvent', '', true, true)]
    local procedure OnAfterInsertEvent_YourTable(var Rec: Record "Prod. Order Routing Line")
    begin
        UpdateTotalPlannedTime(Rec);
    end;

    [EventSubscriber(ObjectType::Table, database::"Prod. Order Routing Line", 'OnAfterModifyEvent', '', true, true)]
    local procedure OnAfterModifyEvent_YourTable(var Rec: Record "Prod. Order Routing Line")
    begin
        UpdateTotalPlannedTime(Rec);
    end;

    local procedure UpdateTotalPlannedTime(var Rec: Record "Prod. Order Routing Line")
    begin
        if Rec."Setup Time" + Rec."Run Time" > 0 then begin
            Rec.TotalPlannedTime := Rec."Setup Time" + (Rec."Run Time" * Rec."Input Quantity");
        end else begin
            Rec.TotalPlannedTime := 0;
        end;
        Rec.Modify(true); // 保存修改,true表示跳过权限检查
    end;
}

同时移除表扩展中的OnValidate和OnBeforeInsert触发器,避免逻辑冲突。

额外检查点

  • 确认事件订阅的EventSubscriber参数正确:第四个参数为空表示对所有公司生效,第五、六个参数true, true确保你的订阅逻辑优先执行。
  • 调试查看第三方扩展是否拦截了Prod. Order Routing Line表的核心事件,可通过断点确认事件是否被触发。

内容的提问来源于stack exchange,提问作者Jeff Brelsford

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:21:16