ELI5 How to add a field to Business Central

In this video, I walk through the process of adding a field to Business Central, all steps explained. This is also an intro to Business Central development.

https://youtu.be/xob-ic-Pw98

This video is a great starting point for my Beginning AL video series.


In this video, Erik walks through the complete process of adding a custom field to Business Central — from scratch, step by step, explained as simply as possible. Whether you’ve never opened Visual Studio Code before or you’re just looking for a clear refresher, this guide covers everything: setting up a sandbox, installing the AL Language extension, creating a table extension and page extension, publishing to your sandbox, and finally deploying to production.

Why You Need a Sandbox

The first rule of customizing Business Central: never make changes directly in production. You always want to work in a sandbox environment, verify that everything works as expected, and only then deploy to production.

To check which environment you’re in, look at the URL — it will either say /production or have no environment name at all. To manage your environments, click the gear icon in Business Central and go to the Admin Center. From there, you can see all your environments (production and sandbox) and create new ones if needed.

Figuring Out Where to Add the Field

Before writing anything, you need to know two critical pieces of information: which table holds the data and which page displays it. Business Central has a built-in tool for this called the Page Inspector.

Open it by pressing Ctrl+Alt+F1 or navigating to Inspect pages and data. In this example, the Page Inspector tells us we’re on:

  • Page: Item Card (page 30)
  • Table: Item (table 27)

The Page Inspector also shows you field numbers, names, and the sections they belong to. Keep this information handy — you’ll need it when building your extension.

Setting Up Visual Studio Code

Visual Studio Code (VS Code) is the tool you’ll use to define your field and where it should appear. Don’t be intimidated — think of it as Notepad with some extra functionality. You can download it from code.visualstudio.com and install it like any other application.

Installing the AL Language Extension

Once VS Code is installed, you need to teach it the AL language — the language of Business Central. Click the Extensions icon on the sidebar (it looks like a little puzzle piece or Tetris block), search for “AL Language”, and click Install. Seconds later, VS Code is ready to work with Business Central.

Creating a New AL Project

Open the Command Palette (from the View menu or Ctrl+Shift+P) and type AL: Go!. This command creates a new project. You’ll be asked to:

  1. Choose a path — Type the path to a new folder (it will be created for you). For example: C:\Users\Erik\Documents\AL\MySingleField
  2. Select a version — If you’re in the cloud, choose the latest version at the top of the list.
  3. Choose a server — Select Microsoft Cloud Sandbox for cloud environments.

Understanding the Generated Files

After running AL: Go!, VS Code generates several files:

  • launch.json — Defines which Business Central environment you’re connecting to. The key field is "environmentName", which should match the name of your sandbox in the Admin Center.
  • app.json — Defines metadata about your extension: name, publisher, version, and the ID range you can use for your custom objects.
  • HelloWorld.al — A sample file you can safely delete.

Here’s what a typical app.json looks like:

{
  "id": "8e3be37f-f69d-4897-a0f6-8a5d48a90b66",
  "name": "AddFieldToGLEntry",
  "publisher": "Default publisher",
  "version": "1.0.0.0",
  "brief": "",
  "description": "",
  "privacyStatement": "",
  "EULA": "",
  "help": "",
  "url": "",
  "logo": "",
  "dependencies": [],
  "screenshots": [],
  "platform": "1.0.0.0",
  "application": "21.0.0.0",
  "idRanges": [
    {
      "from": 51200,
      "to": 51249
    }
  ],
  "resourceExposurePolicy": {
    "allowDebugging": true,
    "allowDownloadingSource": true,
    "includeSourceInSymbolFile": true
  },
  "runtime": "10.0",
  "features": [
    "NoImplicitWith"
  ]
}

The idRanges section is important — it defines the number range available for your custom objects and fields. In Business Central, everything is numbered behind the scenes. Numbers below 50,000 belong to Microsoft. Numbers between 50,000 and 99,999 are yours to use. Numbers above 100,000 are typically reserved for apps and ISV solutions.

Make sure to update the publisher field to something meaningful — always sign your work. And remember: every time you deploy a new version, you must increment the version number. It doesn’t matter how you increment it, as long as the new number is bigger than the previous one.

Downloading Symbols

Before you can start coding, VS Code needs to know what’s in your Business Central environment. Open the Command Palette and run AL: Download Symbols. You’ll be prompted to authenticate via a device login flow — a browser will open, you’ll paste a code, and sign in with your Business Central credentials.

Once symbols are downloaded, VS Code knows everything about your Business Central environment — all the tables, pages, fields, and objects. You’ll see a new .alpackages folder appear in your project.

Creating the Table Extension

Now for the actual work. You need to add the field in two places: first to the database (table extension), then to the screen (page extension). You must start with the table because the field needs to exist in the database before you can display it on a page.

Right-click in the file explorer panel and create a new file. Name it something descriptive with the .al extension — for example, NewItemField.al. The .al extension is critical; it tells VS Code to treat this file as AL code, just like .docx tells Windows to open a file in Word.

In the video, Erik adds a “Last Counted” date field to the Item table. Here’s what a table extension looks like. The source code files provided show a similar pattern applied to the G/L Entry table:

tableextension 51200 "My G/L Entry" extends "G/L Entry"
{
    fields
    {
        field(51200; AccountingPeriod; Integer)
        {
            Caption = 'Account Period';
        }
    }
    keys
    {
        key(AP; AccountingPeriod)
        {
        }
    }
}

Let’s break down the structure:

  • tableextension 51200 — The object type and its ID number (must be within your defined range).
  • "My G/L Entry" — The name of your table extension (use quotes if it contains spaces).
  • extends "G/L Entry" — Specifies which base table you’re extending. Use Ctrl+Space to get an auto-complete list of all available tables.
  • field(51200; AccountingPeriod; Integer) — Defines the new field with an ID, name, and data type.
  • Caption — The display name shown to users. Always add a caption; the field name can never be changed later, but the caption can.

The keys section is optional — in this example, a key is added on the new field to support efficient querying. For a simple date field like “Last Counted,” you may not need an additional key.

Understanding Data Types

When defining your field, you need to specify the correct data type. You can use Ctrl+Space to see all available types. Common ones include:

  • Date — For date values (what Erik uses for “Last Counted”)
  • Integer — For whole numbers
  • Decimal — For numbers with decimal places
  • Text[100] — For text fields (you must specify a maximum length in square brackets)
  • Code[20] — Like text but always uppercase, used for identifiers and codes
  • Boolean — For true/false values

You can use the Page Inspector in Business Central to look at existing fields and see what data types they use as a reference.

Creating the Page Extension

With the table extension in place, you now need to tell Business Central where to display the new field. Create another .al file (e.g., NewItemCard.al) for the page extension. Many developers prefer keeping table and page extensions in separate files for better organization.

Here’s the page extension from the source code, which adds the AccountingPeriod field to the General Ledger Entries page:

pageextension 51200 "My G/L Entry List" extends "General Ledger Entries"
{
    layout
    {
        addbefore("Posting Date")
        {
            field(AccountingPeriod; Rec.AccountingPeriod)
            {
                ApplicationArea = all;
            }
        }
    }
    actions
    {
        addfirst(processing)
        {
            action(AddActP)
            {
                Caption = 'Add Account Period to posted entries';
                ApplicationArea = all;
                trigger OnAction()
                var
                    OddMgt: Codeunit "Odd Accounting";
                begin
                    OddMgt.UpdateAccountingPeriods();
                end;
            }
        }
    }
}

Key points about page extensions:

  • The structure mirrors the table extension: pageextension [ID] [Name] extends [BasePage]
  • Instead of fields, page extensions use layout to define where fields appear on screen
  • You use positioning commands like addbefore, addafter, addfirst, and addlast to place your field relative to existing elements
  • The anchor (inside the parentheses) tells Business Central which existing element to position relative to — use Ctrl+Space to browse available anchors
  • ApplicationArea = all; is required — without it, nobody will see the field
  • The field expression uses Rec.FieldName to reference the field from the underlying table record

This example also demonstrates adding a custom action to the page within the actions section, which calls a codeunit to perform business logic.

Adding Business Logic with a Codeunit

The source code also includes a codeunit that demonstrates how to add business logic to your extension — going beyond just adding a field to actually doing something with it:

codeunit 51200 "Odd Accounting"
{
    Permissions = tabledata "G/L Entry" = RM;

    internal procedure UpdateAccountingPeriods()
    var
        Entry: Record "G/L Entry";
    begin
        if Entry.FindSet() then
            repeat
                Entry.AccountingPeriod := CalcPeriod(Entry."Posting Date");
                Entry.Modify();
            until Entry.Next() = 0;
    end;

    local procedure CalcPeriod(PostingDate: Date): Integer
    var
        DayOfYear: Integer;
        Period: Integer;
    begin
        DayOfYear := PostingDate - DMY2Date(1, 1, Date2DMY(PostingDate, 3));
        Period := DayOfYear div 28 + 1;
        if Period = 14 then
            exit(13)
        else
            exit(Period);
    end;

    [EventSubscriber(ObjectType::Codeunit, Codeunit::"Gen. Jnl.-Post Line",
        'OnBeforeInsertGlEntry', '', true, true)]
    local procedure MyProcedure(var GLEntry: Record "G/L Entry")
    begin
        GLEntry.AccountingPeriod := CalcPeriod(GLEntry."Posting Date");
    end;
}

This codeunit does three things:

  1. UpdateAccountingPeriods — Loops through all existing G/L Entries and calculates an accounting period for each one (useful for backfilling data).
  2. CalcPeriod — A helper function that calculates a 28-day accounting period from a posting date, resulting in 13 periods per year.
  3. Event Subscriber — Automatically sets the accounting period on new G/L entries as they’re posted, by subscribing to the OnBeforeInsertGlEntry event. This is the standard way to hook into Business Central’s existing processes without modifying base code.

While the video focuses on the simplest case (just adding a field), this codeunit shows the natural next step: making your custom fields do something automatically.

Publishing to Your Sandbox

Once your files are ready, it’s time to publish. Go to the Command Palette and choose either:

  • AL: Publish with Debugging — Lets you step through running code (not needed if you’ve only added a field)
  • AL: Publish without Debugging — Simply deploys your extension (this is what you want for a simple field addition)

You’ll be prompted to authenticate again via the device login flow. Once authenticated, VS Code compiles your code, checks for errors, builds an app file, and sends it to Microsoft’s servers. The server then installs and activates your extension in the sandbox environment.

After publishing, Business Central will open in your browser. Navigate to the page you extended, and you should see your new field.

Deploying to Production

Once you’ve verified everything works in your sandbox, it’s time to deploy to production. Before you do, there’s one important step:

Generate a Permission Set

Open the Command Palette and run AL: Generate permission set containing current extension objects. This creates an XML file with permission definitions. You might be blocked from deploying to production without this.

Package and Upload

  1. Run AL: Package from the Command Palette to build the .app file.
  2. In your production Business Central environment, go to Extension Management.
  3. Click Upload Extension and browse to your project folder to find the .app file.
  4. Accept the terms and click Deploy.
  5. Check the Deployment Status page — you can refresh with F5 to monitor progress.

Deployment can take a few minutes depending on server load. Once it shows “Upload Completed,” your extension is live in production. You may need to restart your browser session to see the changes.

Summary

Adding a field to Business Central involves a clear sequence of steps:

  1. Set up a sandbox environment — never work directly in production
  2. Use the Page Inspector (Ctrl+Alt+F1) to identify the table and page you need to extend
  3. Install Visual Studio Code and the AL Language extension
  4. Create a new AL project using the AL: Go! command
  5. Download symbols so VS Code knows your Business Central structure
  6. Create a table extension to add the field to the database
  7. Create a page extension to add the field to the user interface
  8. Publish to sandbox and verify it works
  9. Generate a permission set, package the app, and deploy to production

The setup is the same whether you’re adding a single field or building a complex custom solution. Once you’re comfortable with this process, you can extend it to add fields to other pages, include business logic in codeunits, subscribe to events, and much more. The whole thing can be done in under five minutes once you know the steps — it just takes a bit longer when you’re explaining it all along the way!