← Back to TutorialsAL DEVELOPMENT

Enums in Business Central AL: Complete Beginner Guide

Dynexal • Beginner to Intermediate • 12 min read

Enums are a clean way to represent a fixed set of named values in Microsoft Dynamics 365 Business Central. They are commonly used for statuses, document types, categories, methods and other business choices. In this practical guide, you will learn how to create an Enum, use it in tables and AL code, extend an existing Enum with enumextension, compare values, work with Enum methods, and understand why Enums are generally preferred over legacy Options for modern AL development.

What you will learn: Enum syntax, values and ordinals, table fields, variables and parameters, comparisons, enumextension, API scenarios, Enum methods, common mistakes and production best practices.

What is an Enum in Business Central?

An Enum is a data type made up of named constants. For example, an order status might contain Open, Released, Shipped and Cancelled. Instead of storing unexplained numbers or relying on strings, your AL code can work with meaningful named values.

Microsoft documents Enums as types that can be used for table fields, variables and parameters. Enum values have an ID (ordinal value) and a name, and the values are displayed according to their declaration order. An Enum can be extended only when its Extensible property is set to true. Microsoft Learn: Extensible Enums

Why use Enums instead of Options?

Older Business Central development often used the Option data type for a fixed list of choices. Modern AL development uses Enums for new designs because Enums support stronger typing and can be extended through extensions when designed as extensible.

Practical rule: when creating a new Business Central data model, prefer an Enum over an Option unless you have a specific compatibility reason to use an Option.

Creating your first Enum

The basic syntax starts with an object ID and Enum name. Each value has its own ordinal ID and name.

enum 50100 "Order Status"
{
    Extensible = true;

    value(0; Open)
    {
        Caption = 'Open';
    }
    value(1; Released)
    {
        Caption = 'Released';
    }
    value(2; Shipped)
    {
        Caption = 'Shipped';
    }
    value(3; Cancelled)
    {
        Caption = 'Cancelled';
    }
}

Here, 50100 is the Enum object ID. The values have ordinal IDs 0 through 3. The ordinal value must be unique within the Enum.

Understanding Extensible = true

Enums are not extensible by default. If you want another extension to add values, set Extensible = true. Microsoft specifically notes that only Enums with this property set to true can be extended. Extensible property

enum 50101 "Payment Method"
{
    Extensible = true;

    value(0; Cash) { }
    value(1; Card) { }
    value(2; BankTransfer) { }
}

If the Enum is intentionally closed and should not be extended by other apps, leave it non-extensible. Extensibility should be a deliberate design decision.

Using an Enum as a table field

One of the most common uses is storing an Enum value in a table.

table 50110 "Dynexal Order"
{
    DataClassification = CustomerContent;

    fields
    {
        field(1; "No."; Code[20])
        {
            DataClassification = CustomerContent;
        }

        field(2; Status; enum "Order Status")
        {
            DataClassification = CustomerContent;
        }
    }
}

The field type is enum "Order Status". The user sees the Enum values in the Business Central UI when the field is placed on a page.

Using an Enum as a variable

You can declare an Enum variable using the enum keyword followed by the Enum name.

var
    Status: enum "Order Status";

Then assign a specific Enum member:

Status := "Order Status"::Released;

The :: syntax identifies a specific member of the Enum.

Comparing Enum values

Enums are strongly typed, so compare values from the same Enum type rather than comparing unrelated values.

if Status = "Order Status"::Released then begin
    // Continue processing the released order.
end;

You can also use a case statement when different business logic is required for different values.

case Status of
    "Order Status"::Open:
        Message('Order is open.');
    "Order Status"::Released:
        Message('Order is released.');
    "Order Status"::Shipped:
        Message('Order has shipped.');
    "Order Status"::Cancelled:
        Message('Order was cancelled.');
end;
Avoid magic numbers: do not write business logic that depends on an Enum's ordinal number when you can use the named member. "Order Status"::Released is much clearer than relying on a numeric value.

Enum parameters in procedures

Enums can be passed to procedures just like other AL data types.

procedure ProcessOrder(OrderStatus: enum "Order Status")
begin
    if OrderStatus = "Order Status"::Released then begin
        // Process released orders.
    end;
end;

This makes a procedure's expected input type explicit and lets the compiler help catch incompatible assignments.

Extending an existing Enum with enumextension

One of the biggest advantages of an extensible Enum is that another extension can add values without modifying the original Enum object.

enumextension 50102 "Order Status Ext" extends "Order Status"
{
    value(50102; OnHold)
    {
        Caption = 'On Hold';
    }
}

The extension adds a new value named OnHold. The extension value uses its own unique ID. Microsoft documents this pattern as the standard way to extend an existing extensible Enum. Extensible Enums

Enum values in APIs

Enums are particularly useful in Business Central API scenarios. Microsoft recommends using Enums instead of Options for fields exposed through API pages. With an Enum, the API metadata describes the Enum type and its available members rather than treating the value simply as an arbitrary string.

enum 50103 "Fuel Type"
{
    Extensible = true;

    value(0; Petrol) { }
    value(1; Diesel) { }
    value(2; Electric) { }
}

table 50104 "Vehicle"
{
    fields
    {
        field(1; "No."; Code[20]) { }
        field(2; "Fuel Type"; enum "Fuel Type") { }
    }
}

Microsoft's custom API guidance uses this type of Enum field and explains that Enum metadata exposes the available Enum members. Developing a custom API

Useful Enum methods

AL provides methods for working with Enum values. For example, Enum.Names() returns the names of the values as a List of [Text]. This can be useful when building generic UI or diagnostic logic.

var
    Status: enum "Order Status";
    Names: List of [Text];
begin
    Names := Status.Names();
end;

Use generic Enum methods when you genuinely need dynamic handling. For normal business logic, explicit Enum members are usually easier to read and maintain. Enum.Names()

Real-world example: order processing

Imagine an e-commerce integration where an order moves through several stages. An Enum can represent the state without scattering strings such as "pending", "paid" and "shipped" throughout the application.

enum 50105 "Ecom Order Status"
{
    Extensible = true;

    value(0; Pending) { }
    value(1; Paid) { }
    value(2; Fulfilled) { }
    value(3; Cancelled) { }
}

procedure CanShip(Status: enum "Ecom Order Status"): Boolean
begin
    exit(Status = "Ecom Order Status"::Paid);
end;

The procedure now communicates the business rule directly: an order can be shipped only when its status is Paid. In a larger integration, the Enum can be stored in a table and shown on a List or Card page.

Enums with page fields

If a table contains an Enum field, a page can expose that field directly.

field(Status; Rec.Status)
{
    ApplicationArea = All;
    ToolTip = 'Specifies the current order status.';
}

Business Central renders the available Enum members for the user. This is one reason Enums are useful for controlled choices in business applications.

Enum design and extension best practices

  1. Use meaningful names. Choose names that describe the business concept, not implementation details.
  2. Use extensibility deliberately. Set Extensible = true when partner or per-tenant extensions should be able to add values.
  3. Do not depend on ordinal numbers in business logic. Use named members.
  4. Keep captions user-friendly. The caption is what users see in the UI.
  5. Be careful when changing existing Enum designs. Enum values can be persisted in database fields and used by integrations.
  6. Use the correct object ID range. Microsoft notes that object ID uniqueness is validated during installation, and Marketplace apps must follow assigned ranges.
  7. Use file naming conventions. For example, an Enum file can follow the pattern OrderStatus.Enum.al, and an Enum extension can use OrderStatus.EnumExt.al.

Microsoft's AL best-practices guidance recommends including the object type in file names, with Enum and EnumExt as the relevant abbreviations. AL code best practices

Common Enum mistakes

1. Forgetting Extensible = true

If another extension needs to add a value, the original Enum must be extensible.

2. Comparing different Enum types

Enums are strongly typed. Make sure both sides of a comparison belong to the intended Enum type.

3. Using numbers instead of names

Ordinal IDs are implementation details. Prefer readable members such as Status::Released.

4. Treating an Enum like free-form text

If the value represents a controlled business choice, use an Enum rather than letting arbitrary text values enter the process.

5. Making every Enum extensible

Extensibility is useful, but it should match the intended architecture. If a type is deliberately closed, do not expose it as an extension point without a reason.

Enum vs Option: quick comparison

How to explore existing Enums

Visual Studio Code with the AL development tools includes AL Explorer, which provides an EXTENSIBLE ENUMS view. This can help you discover available extensible Enums and their extension points without searching through application source manually. Microsoft Learn: AL Explorer

Testing an Enum in Business Central

  1. Create the Enum and compile the project.
  2. Add the Enum to a table field.
  3. Expose the field on a test List or Card page.
  4. Publish the extension and verify the available values in the UI.
  5. Test each important business path, including any values added through an Enum extension.
  6. If the Enum is exposed through an API, inspect the API metadata and test the expected values.
Developer tip: test the business behavior associated with each Enum value, not just whether the dropdown displays correctly. An Enum often controls important posting, workflow or integration decisions.

Frequently asked questions

Can an Enum be extended?

Yes. The base Enum must have Extensible = true, and another extension can use enumextension to add values.

Can I use an Enum in a table field?

Yes. A table field can use enum "Your Enum Name" as its data type.

Can I compare Enum values?

Yes. Use the Enum type and its named members, for example Status = Status::Released when the syntax is resolved to the appropriate Enum type.

Should I use Option or Enum?

For new AL development, Enum is generally the better choice for controlled sets of values. Options are primarily encountered in older or compatibility-focused solutions.

Can Enums be used with Business Central APIs?

Yes. Enums are supported in API data models, and Microsoft's custom API guidance recommends Enums instead of Options for API fields.

Continue learning:
AL Tables · List and Card Pages · Interfaces · Custom API Pages · JSON Handling · Event Subscribers

Summary: Enums make Business Central AL code clearer, safer and easier to extend. Learn the basic Enum syntax first, then practice using Enum fields, comparisons and enumextension. Once you understand those patterns, Enums become a powerful foundation for clean Business Central data models and integrations.