实现编号系列模式

已完成

编号系列广泛应用于 Business Central 应用程序。 它们用于自动为任何类型的单据和实体上的数据条目分配唯一编号。 编号系列设计模式介绍了在您自己的扩展中正确使用编号系列所需实施的步骤。

开发解决方案时,您应实现一项功能,即当用户在表中创建新记录时自动为新记录分配编号。 您在创建新项或新客户时,可以看到本功能已实现。 采用编号系列时,用户可以指定本编号系列后跟的编号格式(例如 CUS00001..CUS99999)。

编号系列在两个表中进行定义:表 308 编号系列和表 309 编号系列行,您可以在这两个表中找到编号系列的序列定义。

您应在表级别编写代码,以确保每次插入新记录时,用户都可以键入编号或自动生成编号(如编号系列中所定义)。 因此,编号 系列设计模式指明,开发人员应在不同级别实现该模式。

在表级别,请创建以下参数:

  • 编号字段,类型为“代码”,长度为 20。 此字段是实体表的主键。 此字段将包含自动生成的序列号。

  • 编号系列字段,类型为“代码”,长度为 10。 此字段将包含以下编号系列:用于特定记录,以及用于生成存储在编号字段中的编号。 如果编号系列字段为空,则手动输入编号,而不是使用编号系列生成的编号。

  • OnInsert 触发器应测试编号字段是否已包含值;如果没有,它将根据设置表中配置的默认编号系列请求新编号。

  • 针对编号字段的 OnValidate 触发器将用于检查是否允许用户手动输入编号。

  • AssistEdit 函数,将显示一个可用于实体的编号系列列表。

在页面级别上,您应创建针对编号字段的 OnAssistEdit 触发器。 在本触发器中,您必须调用表中实现的 AssistEdit 函数。

对于特定实体,您可以允许用户输入自己的编号,而不是生成的编号。 对于客户,您可以输入自己的编号,但不允许为销售发票手动输入编号。 您可以在编号系列的配置中定义本设置。

以下示例展示了如何在标准 AL 代码中实现本流程。 下一个代码示例展示了包含编号编号系列字段的客户表。 用户应该无法修改编号系列字段。

OnValidate 触发器中,代码会检查编号的值是否不同于之前的值。 然后,它将从销售和应收帐款设置页面获取设置,并使用 TestManual 函数测试配置的编号系列(在设置表的客户编号系列字段中配置)是否允许用户手动输入编号。 TestManual 函数是在 NoSeriesManagement codeunit 中创建的。 如果不允许用户手动为记录输入编号,TestManual 函数将引发错误,且运行过程将停止。 如果允许手动输入编号,编号系列字段将设为空。

OnInsert 触发器将检查是否有空编号,然后使用 NoSeriesManagement codeunit 生成新编号。 InitSeries 函数将用于该目的。 最后两个参数是引用参数,用于存储生成的编号。 您还可以了解 AssistEdit 函数的使用方式。 本函数将打开一个可用于客户的编号系列列表。

table 18 Customer
{
    fields
    {
        field(1; "No."; Code[20])
        {
            trigger OnValidate()
            begin
                if "No." <> xRec."No." then begin
                    SalesSetup.Get();
                    NoSeriesMgt.TestManual(SalesSetup."Customer Nos.");
                    "No. Series" := '';
                end;
            end;
        }
        field(2; Name; Text[100])
        {
        }
        ...
        field(107; "No. Series"; Code[20])
        {
            Editable = false;
            TableRelation = "No. Series";
        }
}

    trigger OnInsert()
    begin
        if "No." = '' then begin
           SalesSetup.Get();
           SalesSetup.TestField("Customer Nos.");
           NoSeriesMgt.InitSeries(SalesSetup."Customer Nos.", 
                                  xRec."No. Series",    
                                  0D, 
                                  "No.", 
                                  "No. Series");
        end;
        ...
    end;

    var
        SalesSetup: Record "Sales & Receivables Setup";
        NoSeriesMgt: Codeunit NoSeriesManagement;

    procedure AssistEdit(OldCust: Record Customer): Boolean
    var
        Cust: Record Customer;
    begin
        with Cust do begin
            Cust := Rec;
            SalesSetup.Get();
            SalesSetup.TestField("Customer Nos.");
            if NoSeriesMgt.SelectSeries(SalesSetup."Customer Nos.", 
                                        OldCust."No. Series", 
                                        "No. Series") then begin
                NoSeriesMgt.SetSeries("No.");
                Rec := Cust;
                exit(true);
            end;
        end;
    end;
}

本示例展示了客户卡页面的代码片段,其中 OnAssistEdit 函数用于在表中调用 AssistEdit 函数。

group(General)
{
    field("No."; "No.")
    {
        trigger OnAssistEdit()
        begin
            if AssistEdit(xRec) then
                CurrPage.Update;
        end;
    }
}

您可以在所有单据和主表中 找到编号系列设计模式的同一实现。