Email this post as a PDFDevelopment · 30 September 2026 · 2 min read

Number series in AL: using the No. Series module properly

Every document and master record gets its number from a number series, and since version 24 the API for doing that from code changed. The new No. Series codeunit, peeking versus getting, the gap problem, date ordering, manual numbers, and how to set up and consume a series for your own table.

Contents
  1. Setting up your own
  2. Peek versus get
  3. Date ordering and starting dates
  4. Relationships between series
  5. Batches and performance
  6. Posted numbers

If your extension creates records that need a number (a shipment, a return, a case), it should take it from a number series like every base document does: configurable prefix, sequential, optionally date-ordered, with the user able to change it in setup. The API for this was rewritten in version 24 as the No. Series module; the old NoSeriesManagement codeunit is obsolete.

Setting up your own

Add a "CON Shipment Nos." field (Code[20], TableRelation = "No. Series") to your setup table and a line for it on the setup page. Your table's "No." field gets the standard trigger pattern: on insert, if blank, take the next number; on validate, if the user typed one, check the series allows manual numbers (NoSeries.TestManual).

trigger OnInsert()
var
    Setup: Record "CON Setup";
    NoSeries: Codeunit "No. Series";
begin
    if "No." = '' then begin
        Setup.GetRecordOnce();
        Setup.TestField("CON Shipment Nos.");
        "No. Series" := Setup."CON Shipment Nos.";
        "No." := NoSeries.GetNextNo("No. Series", WorkDate());
    end;
end;

Peek versus get

PeekNextNo shows what the next number would be without consuming it (for display, for a "number will be" message). GetNextNo consumes it. Consuming inside a transaction that then errors rolls the consumption back too, so numbers are not lost on failed inserts. What does lose numbers is consuming, committing, and then deleting the record; if gapless numbering matters (posted documents for VAT), do not do that.

Date ordering and starting dates

A series with "Date Order" = true refuses a number for a date earlier than the last one used, which is what you want for posted documents and not for master data. Series lines with a "Starting Date" let a new range begin on a date; the number comes from the line in force for the date you pass, which is why you pass a real date and not 0D, and why the January "no number range for this date" ticket exists (ten tickets).

Relationships between series

The "No. Series Relationship" table lets a document choose from several series (the AssistEdit on "No."). NoSeries.LookupRelatedNoSeries gives you the standard dialog; AreRelated checks a chosen one is allowed.

Batches and performance

For bulk creation, the new module has a "No. Series - Batch" codeunit that reserves numbers in memory and writes the series state once, which avoids one update to the series line per record and the lock contention that came with it. Use it for imports and integrations creating hundreds of records.

Posted numbers

If your document posts into a posted version, give the posted table its own series (as sales invoices do), copy the number series code to the posted record, and never let the posted series allow manual numbers. The audit trail depends on it.

Email this post as a PDF
A branded PDF of this post, sent to your inbox to keep, print or share. Copy in colleagues if you like.
We only use these addresses to send this PDF. Nobody is added to a mailing list. Mike at Business Boxed receives a copy. See our privacy notice.
Email this post
Talk to us
Want this done in your Business Central?
Book a 30 minute callGet the monthly newsletter

Related posts