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

如何从Business Central客户文档布局获取自定义报表布局ID

问题:Business Central销售订单PDF导出需适配客户自定义文档布局

我正在开发Business Central扩展,在销售订单列表页面添加按钮,以Sales Order [订单号].pdf格式保存销售订单确认单PDF。部分客户会在客户卡片 > 客户 > 文档布局中定义自定义报表布局,该布局优先级要高于报表布局选择中的设置。但Report.SaveAs、Report.Execute这类保存报表的方法需要指定报表ID,我找不到如何从客户文档布局中获取自定义报表布局ID,也没找到对应的文档布局表。目前代码除了自定义报表布局的适配问题外,其他功能正常。

现有代码:

pageextension 50100 SalesOrderExt extends "Sales Order List"
{
    actions
    {
        addafter("Print Confirmation")
        {
            action("Save Confirmation as PDF")
            {
                Caption = 'Save Confirmation As PDF';
                ApplicationArea = All;
                Image = ExportFile;
                Promoted = true;
                PromotedCategory = Category8;
                PromotedIsBig = true;
                ToolTip = 'Save the order confirmation as a PDF';

                trigger OnAction()
                var
                    SalesHeader: Record "Sales Header";
                    TempBlob: Codeunit "Temp Blob";
                    FileManagement: Codeunit "File Management";
                    RecRef: RecordRef;
                    OStream: OutStream;
                    XmlParameters: Text;
                begin
                    XmlParameters := '<?xml version="1.0" standalone="yes"?>' +
                                    '<ReportParameters name="Sales Order" id="' + System.Format(Report::"Sales Order") + '">' +
                                        '<Options>' +
                                            '<Field name="NoCopies">0</Field>' +
                                            '<Field name="PrintCompany">false</Field>' +
                                            '<Field name="ArchiveDocument">false</Field>' +
                                            '<Field name="LogInteraction">false</Field>' +
                                            '<Field name="DisplayAssemblyInformation">false</Field>' +
                                        '</Options>' +
                                        '<DataItems>' +
                                            '<DataItem name="Sales Header">VERSION(1) SORTING(Field1,Field3) WHERE(Field3=1(' + Rec."No." + '))</DataItem>' +
                                            '<DataItem name="Sales Line">VERSION(1) SORTING(Field1,Field3,Field4)</DataItem>' +
                                            '<DataItem name="SalesLineComments">VERSION(1) SORTING(Field1,Field2,Field7,Field3)</DataItem>' +
                                            '<DataItem name="Sales Comment Line">VERSION(1) SORTING(Field1,Field2,Field7,Field3)</DataItem>' +
                                            '<DataItem name="CopyLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="PageLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="SalesLine">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="AsmLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                        '</DataItems>' +
                                    '</ReportParameters>';
                    SalesHeader.Reset();
                    SalesHeader.SetRange("Document Type", Rec."Document Type");
                    SalesHeader.SetRange("No.", Rec."No.");
                    SalesHeader.FindFirst();
                    Clear(OStream);
                    CurrPage.SetSelectionFilter(SalesHeader);
                    RecRef.GetTable(SalesHeader);
                    TempBlob.CreateOutStream(OStream, TextEncoding::UTF8);
                    Report.SaveAs(Report::"Sales Order", XmlParameters, ReportFormat::Pdf, OStream, RecRef);
                    FileManagement.BLOBExport(TempBlob, 'Sales Order ' + Rec."No." + '.pdf', true);
                end;
            }
        }
    }
}
解决方案

1. 找到对应的文档布局表

客户自定义的文档布局存储在Document Layout表(ID:9650)中,该表关联了客户、文档类型和对应的报表布局ID。

2. 获取客户的自定义报表ID逻辑

  • 先获取销售订单关联的客户编号
  • 查询Document Layout表,筛选条件为当前公司、客户编号、文档类型(销售订单对应Order)
  • 若查询到记录,则使用该记录的Report ID;否则使用默认的Sales Order报表ID

3. 修改后的完整代码

pageextension 50100 SalesOrderExt extends "Sales Order List"
{
    actions
    {
        addafter("Print Confirmation")
        {
            action("Save Confirmation as PDF")
            {
                Caption = 'Save Confirmation As PDF';
                ApplicationArea = All;
                Image = ExportFile;
                Promoted = true;
                PromotedCategory = Category8;
                PromotedIsBig = true;
                ToolTip = 'Save the order confirmation as a PDF';

                trigger OnAction()
                var
                    SalesHeader: Record "Sales Header";
                    DocumentLayout: Record "Document Layout";
                    TempBlob: Codeunit "Temp Blob";
                    FileManagement: Codeunit "File Management";
                    RecRef: RecordRef;
                    OStream: OutStream;
                    XmlParameters: Text;
                    TargetReportId: Integer;
                begin
                    // 获取销售订单头部信息
                    SalesHeader.Reset();
                    SalesHeader.SetRange("Document Type", Rec."Document Type");
                    SalesHeader.SetRange("No.", Rec."No.");
                    if not SalesHeader.FindFirst() then
                        exit;

                    // 获取客户对应的自定义报表ID,无自定义则用默认
                    TargetReportId := Report::"Sales Order";
                    DocumentLayout.Reset();
                    DocumentLayout.SetRange("Company Name", CompanyName);
                    DocumentLayout.SetRange("Customer No.", SalesHeader."Sell-to Customer No.");
                    DocumentLayout.SetRange("Document Type", DocumentLayout."Document Type"::Order);
                    if DocumentLayout.FindFirst() then
                        TargetReportId := DocumentLayout."Report ID";

                    // 构建XML参数,替换报表ID为目标ID
                    XmlParameters := '<?xml version="1.0" standalone="yes"?>' +
                                    '<ReportParameters name="Sales Order" id="' + System.Format(TargetReportId) + '">' +
                                        '<Options>' +
                                            '<Field name="NoCopies">0</Field>' +
                                            '<Field name="PrintCompany">false</Field>' +
                                            '<Field name="ArchiveDocument">false</Field>' +
                                            '<Field name="LogInteraction">false</Field>' +
                                            '<Field name="DisplayAssemblyInformation">false</Field>' +
                                        '</Options>' +
                                        '<DataItems>' +
                                            '<DataItem name="Sales Header">VERSION(1) SORTING(Field1,Field3) WHERE(Field3=1(' + Rec."No." + '))</DataItem>' +
                                            '<DataItem name="Sales Line">VERSION(1) SORTING(Field1,Field3,Field4)</DataItem>' +
                                            '<DataItem name="SalesLineComments">VERSION(1) SORTING(Field1,Field2,Field7,Field3)</DataItem>' +
                                            '<DataItem name="Sales Comment Line">VERSION(1) SORTING(Field1,Field2,Field7,Field3)</DataItem>' +
                                            '<DataItem name="CopyLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="PageLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="SalesLine">VERSION(1) SORTING(Field1)</DataItem>' +
                                            '<DataItem name="AsmLoop">VERSION(1) SORTING(Field1)</DataItem>' +
                                        '</DataItems>' +
                                    '</ReportParameters>';

                    // 执行PDF导出
                    Clear(OStream);
                    CurrPage.SetSelectionFilter(SalesHeader);
                    RecRef.GetTable(SalesHeader);
                    TempBlob.CreateOutStream(OStream, TextEncoding::UTF8);
                    Report.SaveAs(TargetReportId, XmlParameters, ReportFormat::Pdf, OStream, RecRef);
                    FileManagement.BLOBExport(TempBlob, 'Sales Order ' + Rec."No." + '.pdf', true);
                end;
            }
        }
    }
}

关键注意点

  • 必须同步修改XML参数中的报表ID,否则会出现参数与实际调用报表不匹配的问题
  • Document Layout表的筛选条件要包含当前公司名称,避免跨公司布局干扰
  • 若客户没有设置自定义布局,会自动 fallback 到默认报表,保证原有逻辑正常运行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 02:54:51