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

Dimensions in AL: dimension sets, default dimensions and the Dimension Management codeunit

Dimensions are stored as a numbered set, not as fields, and everything that creates a document or journal line has to build the right set. How dimension sets work, how to read and write them in code, applying default dimensions, validating combinations, and the mistakes that leave entries with blank dimensions.

Contents
  1. Dimension sets
  2. Reading and writing them
  3. Default dimensions
  4. Validation
  5. Mistakes

Dimensions look like fields on a document, and two of them (the global ones) are. The rest, and the whole set, are stored differently, and most extension code that creates documents or journal lines gets them subtly wrong. This is how they actually work.

Dimension sets

Every unique combination of dimension values is stored once in Dimension Set Entry under a Dimension Set ID. A document header, line, journal line or ledger entry carries that ID in "Dimension Set ID", plus the two global dimensions copied into "Shortcut Dimension 1 Code" and "Shortcut Dimension 2 Code" for filtering. Changing a dimension on a line does not edit the set; it finds or creates a new set and points the line at it. Sets are immutable and shared.

Reading and writing them

var
    DimMgt: Codeunit DimensionManagement;
    TempDimSetEntry: Record "Dimension Set Entry" temporary;
    NewDimSetID: Integer;
begin
    // read the current set into a temp table
    DimMgt.GetDimensionSet(TempDimSetEntry, SalesLine."Dimension Set ID");
    // add or change a value
    TempDimSetEntry.Init();
    TempDimSetEntry."Dimension Code" := ProjectDimCodeTok;
    TempDimSetEntry."Dimension Value Code" := ProjectCode;
    if not TempDimSetEntry.Insert() then
        TempDimSetEntry.Modify();
    // get (or create) the set for the new combination
    NewDimSetID := DimMgt.GetDimensionSetID(TempDimSetEntry);
    SalesLine."Dimension Set ID" := NewDimSetID;
    DimMgt.UpdateGlobalDimFromDimSetID(NewDimSetID, SalesLine."Shortcut Dimension 1 Code", SalesLine."Shortcut Dimension 2 Code");
end;

Simpler, and preferred for setting one value: SalesLine.ValidateShortcutDimCode(3, Value) for a shortcut dimension by its position, which does all of the above. For the two globals, validating the field does it.

Default dimensions

When a document line is created for an item, customer or G/L account, the base application calls DimMgt.GetDefaultDimID with the list of source records (customer, salesperson, item, and so on) and builds the set from their default dimensions, honouring priority. If your code creates lines without going through the standard Validate of the "No." field, the defaults are never applied, and the line posts with blank dimensions. Always validate Type then "No." on a new line; or call CreateDim on the line, which is what validation does.

Validation

DimMgt.CheckDimValuePosting (and CheckDimIDComb) enforce Code Mandatory, Same Code, blocked values and dimension combinations. Posting calls them; your pre-checks should too, so the user gets the error on the line, not at posting.

Mistakes

  • Assigning "Shortcut Dimension 1 Code" directly without updating the set ID. The global field and the set disagree; reports by set are wrong.
  • Copying a set ID from one document to another of a different kind without re-applying defaults.
  • Storing dimension values in your own fields "to make reporting easier". Use the set; it is what financial reports read.
  • Loading opening journals with no dimensions because the import did not call the validation. See migration tooling.
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