如何将Item表的Vendor Item No.映射至Sales Line自定义字段?
需求与问题
需要将Item表的系统默认字段「Vendor Item No.」同步到Sales Lines表的自定义字段中,用于报表展示。已尝试TableRelation、FlowField公式、DataTransfer过程,但自定义字段始终为空,无报错,报表中无法显示该字段值。
现有表扩展代码
tableextension 50102 SalesLineVendorTble extends "Sales Line" { fields { //Item表的原字段是(32; "Vendor Item No."; Text[50]) //字段能成功创建,但无关联数据 field(999; "Vendor Item Custom Table"; Text[50]) { //TableRelation尝试无效 DataClassification = ToBeClassified; //DataClassification或FlowField二选一 TableRelation = Item."Vendor Item No." where("No." = field("No.")); //FlowField的CalcFormula尝试 //FieldClass = FlowField; //DataClassification或FlowField二选一 //CalcFormula = lookup(item."Vendor Item No." where("No." = field("No."))); } } //以下是尝试关联的多种方法的过程 /* local procedure CopyVendorItemNum() var dt: datatransfer; dest: Record "Sales Line"; src: Record Item; begin //尝试让SalesLine.CustomField等于Item.VendorNumber,无效 //rec."Vendor Item Custom Table" := src."Vendor Item No."; //设置DataTransfer关联表并复制字段,无效 dt.SetTables(Database::Item, Database::"Sales Line"); dt.AddFieldValue(src.FieldNo("Vendor Item No."), dest.Fieldno("Vendor Item Custom Table")); dt.AddJoin(src.FieldNo("No."), dest.FieldNo("No.")); dt.CopyFields(); end; */ }
现有报表扩展代码
reportextension 50101 PickAddVendor extends "Pick Instruction" { RDLCLayout = './CustomReport.rdlc'; dataset { add("Sales Line") { //FactoryCodeTable为内部使用名称,Vendor Item Custom Table是自定义字段 column("FactoryCodeTable"; "Vendor Item Custom Table") { } } } }
问题分析与解决方案
1. FlowField模式的正确配置
你之前注释的FlowField方案方向是对的,但有两处细节错误:
- 必须启用
FieldClass = FlowField,同时注释掉TableRelation(两者不能共存) - AL语言区分大小写,公式中的表名
item要改为大写Item
修正后的字段定义:
field(999; "Vendor Item Custom Table"; Text[50]) { FieldClass = FlowField; CalcFormula = lookup(Item."Vendor Item No." where("No." = field("No."))); DataClassification = ToBeClassified; }
配置后,需要在报表中触发FlowField计算,否则报表无法自动获取值。在报表扩展中添加事件处理:
reportextension 50101 PickAddVendor extends "Pick Instruction" { RDLCLayout = './CustomReport.rdlc'; dataset { add("Sales Line") { column("FactoryCodeTable"; "Vendor Item Custom Table") { } } } trigger OnPreDataItem() begin if DataItemName = 'Sales Line' then begin //可选:仅处理物料类型的销售行 CurrReport.SetRange("Sales Line".Type, "Sales Line".Type::Item); //强制计算FlowField值 "Sales Line".CalcFields("Vendor Item Custom Table"); end; end; }
2. 存储式同步模式(非FlowField)的正确做法
如果不想用动态计算的FlowField,而是要把值实际存储到Sales Line表中,需要在销售行创建/修改时自动同步:
- 给Sales Line表添加
OnInsert和OnModify触发器,当物料编号变化时从Item表拉取值
修正后的表扩展代码:
tableextension 50102 SalesLineVendorTble extends "Sales Line" { fields { field(999; "Vendor Item Custom Table"; Text[50]) { DataClassification = ToBeClassified; //可选:添加表关系用于数据验证 TableRelation = Item."Vendor Item No." where("No." = field("No.")); } } trigger OnInsert() begin SyncVendorItemNo(); end; trigger OnModify() begin //仅当物料编号变化时重新同步 if xRec."No." <> Rec."No." then SyncVendorItemNo(); end; local procedure SyncVendorItemNo() var ItemRec: Record Item; begin if Rec.Type = Rec.Type::Item then begin if ItemRec.Get(Rec."No.") then Rec."Vendor Item Custom Table" := ItemRec."Vendor Item No."; end else Rec."Vendor Item Custom Table" := ''; end; }
这种方式会自动同步新创建或修改的销售行数据,历史数据可以用下面的批量同步方法处理。
3. DataTransfer批量同步历史数据
你之前的DataTransfer代码只是配置了规则,但没有执行实际的批量同步逻辑。如果要更新历史销售行,需要添加一个可调用的批量处理函数(比如通过页面或代码单元触发):
local procedure BatchSyncAllSalesLines() var dt: DataTransfer; SalesLineRec: Record "Sales Line"; ItemRec: Record Item; begin dt.SetTables(Database::Item, Database::"Sales Line"); dt.AddFieldValue(ItemRec.FieldNo("Vendor Item No."), SalesLineRec.FieldNo("Vendor Item Custom Table")); dt.AddJoin(ItemRec.FieldNo("No."), SalesLineRec.FieldNo("No.")); //过滤仅处理物料类型的销售行 dt.AddDestinationFilter(SalesLineRec.FieldNo(Type), '=', SalesLineRec.Type::Item); dt.CopyFields(); end;
注意:批量同步前建议先备份数据,或测试小范围数据。
内容的提问来源于stack exchange,提问作者Boardies
相关产品推荐
相关产品推荐

