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; }
问题原因分析
- 触发时机不完整:当前仅在
TotalPlannedTime自身被修改(OnValidate)或记录插入前(OnBeforeInsert)触发计算,而Setup Time、Run Time、Input Quantity这三个核心依赖字段被修改时,不会自动触发TotalPlannedTime的更新。 - 事件订阅未持久化数据:在
OnAfterInsertEvent和OnAfterModifyEvent中仅修改了内存中的Rec变量,但未调用Modify()将更新写入数据库,导致修改不会被保存。 - 触发器执行顺序冲突:第三方扩展若也对
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
相关产品推荐
相关产品推荐

