Use Enums as Text Constants

Earlier in January AJ Kauffmann tweeted a question about using Enum as Text Constants and a few weeks later I found a great use case for that. In this video, I show how to use Enum to store large constant strings.

https://youtu.be/QIcGPciPsPc

In this video, Erik explores a creative technique for using enums as text constants in AL for Business Central. Inspired by a tweet from his friend AJ Kauffmann, Erik demonstrates how enum captions can store text content — from simple strings to even large Base64-encoded images — providing a clean, centralized way to manage constants that AL doesn’t natively support as a language feature.

The Problem: No Global Text Constants in AL

Many programming languages have the concept of defining text constants — a small library of reusable strings that can be referenced from anywhere in your codebase. AL for Business Central doesn’t really have this concept. Everything tends to become a runtime string. While AL does have labels, they’re scoped locally and aren’t easily accessible from a global scope.

This means developers often end up with text values scattered across variables and procedures, making code harder to read and maintain.

AJ Kauffmann’s Clever Idea

Back in January, Erik’s friend AJ Kauffmann (who Erik highly recommends following on Twitter, especially if you work with Business Central APIs) tweeted an interesting observation:

“Discussing globals or locals in AL — we don’t have resource files to store text in like you can do in other languages, but we can use (abuse) enums for that. What do you think? Good idea or is this a no-go?”

AJ’s example showed an ErrorMessages enum where each enum value’s caption contained an actual error message string. This way you could write something like:

Error(Format(ErrorMessages::"Field Incorrect Value"));

The Format function on an enum returns its caption, effectively giving you a globally accessible text constant.

Basic Enum Structure in AL

Before diving deeper into the hack, let’s look at how enums work in AL. Here’s a straightforward enum definition from the source code:

enum 54800 RainbowColors
{
    // Red,Orange,Yellow,Green,Blue,Indigo,Violet
    value(0; Red) { }
    value(1; Orange) { }
    value(2; Yellow) { }
    value(3; Green) { }
    value(4; Blue) { }
    value(5; Indigo) { }
    value(6; Violet) { }
}

Enums can be used as field types in tables, replacing the older Option type:

table 54800 "Rainbow Component"
{
    fields
    {
        field(1; Layer; Integer)
        {
            Caption = 'Layer';
        }
        field(2; Size; Decimal)
        {
            Caption = 'Size';
        }
        field(3; Color; Enum RainbowColors)
        {
            Caption = 'Color';
        }
    }

    procedure Add(_Layer: Integer; _Size: Decimal; _Color: Enum RainbowColors)
    begin
        Rec.Init();
        Rec.Layer := _Layer;
        Rec.Size := _Size;
        Rec.Color := _Color;
    end;

    procedure Test(): List of [Text]
    begin
        Add(10, 1000, RainbowColors::Indigo);
    end;
}

And displayed on a page:

page 54800 "The Rainbow"
{
    Caption = 'Rainbow';
    UsageCategory = Administration;
    ApplicationArea = all;
    SourceTable = "Rainbow Component";
    PageType = List;
    layout
    {
        area(Content)
        {
            repeater(rep)
            {
                field(Layer; Rec.Layer)
                {
                    ApplicationArea = all;
                }
                field(Size; Rec.Size)
                {
                    ApplicationArea = all;
                }
                field(Color; Rec.Color)
                {
                    ApplicationArea = all;
                }
            }
        }
    }
}

This is the standard use case. But the real fun begins when you start using enum captions to store arbitrary text content.

Taking It Further: Base64 Images in Enum Captions

Erik took AJ’s idea and ran with it — quite literally into a chess engine built in AL. When building a chess game, he needed to manage a large number of bitmap images for all the different chess pieces. These bitmaps were essentially constants, so he thought: why not store them as enum captions?

The concept looked something like this:

enum 54801 "Chess Piece"
{
    value(0; "Black Bishop")
    {
        Caption = 'iVBORw0KGgoAAAANSUhEUgAA...'; // ~9,000 character Base64 string
    }
    // ... more pieces
}

This meant that in the code, setting a piece on the board looked beautifully readable:

Engine.SetBitmapOnPosition(Board, ChessPiece::"Black Bishop", Position);

The caption for “Black Bishop” contained the entire Base64-encoded image — approximately 9,000 characters — and AL handled it without any issues.

Practical Example: Refactoring the Tic-Tac-Toe Game

To demonstrate the technique more concretely, Erik refactored his existing Tic-Tac-Toe game (also built entirely in AL). Previously, the game had a function that created an array of text values and filled it with Base64 image strings — around 5,000 to 6,000 characters each for the blank, X, and O images.

The original approach required initializing an array and selecting from it every time a bitmap was placed on the board. By moving those Base64 strings into enum captions, the code became dramatically simpler.

Before: Array-Based Approach

The old code initialized an array of text variables, populated them with long Base64 strings, and then selected the correct one based on the image type. This was functional but verbose.

After: Enum-Based Approach

After refactoring, the image type enum had its captions set to the Base64 strings directly:

enum 54802 "Image Type"
{
    value(0; Blank)
    {
        Caption = '...'; // Base64 for blank square
    }
    value(1; X)
    {
        Caption = '...'; // Base64 for X image
    }
    value(2; O)
    {
        Caption = '...'; // Base64 for O image
    }
}

The SetBitmapOnPosition function was then simplified to just:

Format(ImageType)

That single Format call returns the caption of the enum value, which contains the entire Base64 string. All the array initialization code could be removed entirely, making the codebase significantly cleaner.

How It Works

The key insight is simple: calling Format() on an enum value returns its caption. If you set the caption to any text content you need — whether it’s an error message, a file header, or a Base64-encoded image — you effectively have a globally accessible, named text constant.

The syntax in your code becomes highly readable:

TextConstant::"My Named Value"

This makes it immediately clear that you’re referencing a constant, and the enum name can even be called TextConstant if that’s what it represents.

One Caveat: Translations

There is one important consideration with this approach. If you have translations enabled in your project, enum captions will appear in the translation files (XLIFF). You need to make sure that translators don’t attempt to translate your Base64 strings or other non-human-readable constants into another language. However, Erik notes this is fairly manageable — it’s usually quite obvious that a 9,000-character Base64 string isn’t something that needs translation.

When to Use This Technique

This approach works well when you have:

  • Text constants needed across multiple places in your codebase
  • Base64-encoded images or other binary data stored as text
  • File format headers or templates
  • Error messages that you want centralized and named
  • Any scenario where you’d want a global, named string constant

Instead of scattering these values across variables in different procedures, you put them in one place and use the enum to address them by name.

Conclusion

While AL doesn’t natively support global text constants or resource files like other languages do, using enum captions as text storage is a creative and effective workaround. The code becomes more readable, constants are centralized, and the approach scales well — even handling strings of 9,000+ characters without issues. It’s a clever hack that makes your AL code cleaner and more maintainable. As Erik puts it: “On this channel, we salute a nice hack.”