← Back to TutorialsAL DEVELOPMENT

Codeunits in Business Central: Complete Beginner Guide

Dynexal • Beginner Guide • 10 min read

Codeunits are one of the main places where reusable business logic lives in Microsoft Dynamics 365 Business Central. In this guide, you will learn how codeunits work, how to create procedures, how to call them, and when to use events.

What you will learn: codeunit structure, procedures, the OnRun trigger, calling codeunits, reusable business logic, event subscribers and common beginner mistakes.

What is a codeunit?

A codeunit is an AL object used to contain reusable business logic. Instead of putting the same logic directly inside several pages or reports, you can move it into a codeunit and call it wherever the functionality is needed. Microsoft describes codeunits as containers for AL code that can be used by many application objects. citeturn0search0

Create a simple codeunit

A basic codeunit can expose a procedure that performs a small piece of reusable logic:

codeunit 50110 "Dynexal Customer Management"
{
    procedure ShowCustomerMessage(CustomerName: Text)
    begin
        Message('Customer: %1', CustomerName);
    end;
}

The object ID should be unique in your extension, while the codeunit name should clearly describe its responsibility. Microsoft also recommends meaningful object naming and readable file structure for AL code. citeturn0search2

What is a procedure?

A procedure is a method that contains a reusable block of AL code. A procedure can receive parameters, perform validation or calculations, work with records, and return a value when required.

procedure CalculateDiscount(Amount: Decimal; Percentage: Decimal): Decimal
begin
    exit(Amount * Percentage / 100);
end;

You can keep helper procedures local when they should only be used inside the same object. Public procedures can be called by other objects when the access rules of the extension allow it.

Using the OnRun trigger

A codeunit can have an OnRun() trigger. It runs when the codeunit itself is run. This is different from simply calling one of its procedures. citeturn0search9

codeunit 50111 "Dynexal Processing"
{
    trigger OnRun()
    begin
        Message('Dynexal processing started.');
    end;
}

Calling a codeunit from another object

One of the most useful patterns is to keep business logic in a codeunit and call it from a page action or another AL object.

codeunit 50112 "Dynexal Order Management"
{
    procedure ProcessOrder(OrderNo: Code[20])
    begin
        Message('Processing order %1', OrderNo);
    end;
}

From another object, you can create a codeunit variable and call the procedure:

var
    OrderManagement: Codeunit "Dynexal Order Management";
begin
    OrderManagement.ProcessOrder('SO-1001');

Business Central also supports running a codeunit directly with Codeunit.Run. The exact form depends on whether the codeunit is associated with a table and whether a record is passed. citeturn0search10

Codeunits and page actions

A common real-world pattern is to keep a page action small and delegate the actual business logic to a codeunit:

action(ProcessOrder)
{
    ApplicationArea = All;
    Caption = 'Process Order';

    trigger OnAction()
    var
        OrderManagement: Codeunit "Dynexal Order Management";
    begin
        OrderManagement.ProcessOrder(Rec."No.");
    end;
}
Best practice: avoid putting large business processes directly inside OnAction(). Keep the page responsible for the user interaction and let a codeunit handle reusable business logic.

Codeunits and events

Codeunits are also central to event-driven Business Central development. Event subscribers are methods placed inside codeunits and decorated with the EventSubscriber attribute. Microsoft documents event subscribers as a way to subscribe to published events and react when those events occur. citeturn0search5turn0search15

codeunit 50113 "Dynexal Event Subscriber"
{
    [EventSubscriber(ObjectType::Table, Database::Customer, 'OnAfterInsertEvent', '', false, false)]
    local procedure AfterCustomerInsert(var Rec: Record Customer)
    begin
        // Add custom logic here.
    end;
}

Common beginner mistakes

  1. Putting every piece of logic into page triggers instead of creating reusable procedures.
  2. Creating one very large codeunit with unrelated responsibilities.
  3. Using unclear names such as Codeunit1 or MyCode.
  4. Making helper procedures public when they only need to be used internally.
  5. Putting UI-specific logic and reusable business logic into the same procedure.
  6. Ignoring events when an extensibility-friendly solution would be better.

How to design better codeunits

What should you learn next?

AL Tables in Business Central — understand the data model that your business logic works with.

Creating List and Card Pages in AL — connect your data model to a user interface.

Page Extensions in Business Central — add actions and fields to standard pages.

Getting Started with AL Development — follow the complete beginner learning path.

← Explore all Dynexal tutorials