Objective: Introduce the syntax and basic constructs of AL language.
In this blog post, we will explore the fundamentals of AL (Application Language) used in Microsoft Dynamics 365 Business Central. AL is the language used to define the logic and behavior of your extensions, enabling you to customize and extend the capabilities of Business Central. By understanding the syntax and basic constructs of AL, you can create robust extensions that enhance the functionality of the base application. This article will guide you through the essential components of AL, including tables, pages, and codeunits, using practical examples.
Overview of AL Syntax
AL is a domain-specific language designed specifically for business applications. It follows a structured format that is easy to read and write. The primary elements of AL include objects such as tables, pages, and codeunits. Each object type serves a specific purpose and has its own set of properties and methods.
Here is a simple example of AL syntax used to create a basic table object:
table 50100 Reward
{
DataClassification = ToBeClassified;
fields
{
field(1; "Reward ID"; Code[30])
{
DataClassification = ToBeClassified;
}
field(2; Description; Text[250])
{
NotBlank = true;
}
field(3; "Discount Percentage"; Decimal)
{
MinValue = 0;
MaxValue = 100;
DecimalPlaces = 2;
}
}
keys
{
key(PK; "Reward ID")
{
Clustered = true;
}
}
}
In this example, we define a table named “Reward” with three fields: Reward ID, Description, and Discount Percentage. Each field has specific properties that control its behavior and constraints.
Explanation of Tables, Pages, and Codeunits
Tables: Tables in AL are used to store data. Each table object contains fields, keys, and triggers. Fields represent the columns in the table, keys define the primary and secondary keys for indexing, and triggers contain AL code that runs during specific database operations. In the example above, the table 50100 Reward
is used to store reward levels for customers.
Pages: Pages are the user interface elements in Business Central. They define how data is presented to users and allow interaction with the data. Pages can be of various types such as Card, List, and Worksheet. Here is an example of a Card page that displays and edits records from the Reward table:
page 50101 "Reward Card"
{
PageType = Card;
UsageCategory = Tasks;
SourceTable = Reward;
layout
{
area(content)
{
group(Reward)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
}
field(Description; Rec.Description)
{
ApplicationArea = All;
}
field("Discount Percentage"; Rec."Discount Percentage")
{
ApplicationArea = All;
}
}
}
}
}
Codeunits: Codeunits are used to encapsulate logic and functionality in AL. They are similar to classes in other programming languages. Codeunits can contain procedures and triggers that execute specific tasks. Here is an example of an install codeunit that initializes the Reward table with default values when the extension is installed:
codeunit 50105 RewardsInstallCode
{
Subtype = Install;
trigger OnInstallAppPerCompany();
var
Reward: Record Reward;
begin
if Reward.IsEmpty() then
begin
InsertDefaultRewards();
end;
end;
procedure InsertDefaultRewards()
begin
InsertRewardLevel('GOLD', 'Gold Level', 20);
InsertRewardLevel('SILVER', 'Silver Level', 10);
InsertRewardLevel('BRONZE', 'Bronze Level', 5);
end;
procedure InsertRewardLevel(ID: Code[30]; Description: Text[250]; Discount: Decimal)
var
Reward: Record Reward;
begin
Reward.Init();
Reward."Reward ID" := ID;
Reward.Description := Description;
Reward."Discount Percentage" := Discount;
Reward.Insert();
end;
}
Practical Example: Building a Rewards Extension
Let’s create a sample extension that adds a reward system for customers. This extension will include a table to store reward levels, pages to view and edit the rewards, and codeunits for installation and upgrade logic.
At the end of this blog, you will have a section in the customer cards that will let the user select a Reward ID corresponding to the customer. We will develop this functionality further as gain more advanced understanding of AL.
1. Reward Table (Reward.al): This table stores reward levels with an ID, description, and discount percentage.
table 50100 Reward
{
DataClassification = ToBeClassified;
fields
{
field(1; "Reward ID"; Code[30])
{
DataClassification = ToBeClassified;
}
field(2; Description; Text[250])
{
NotBlank = true;
}
field(3; "Discount Percentage"; Decimal)
{
MinValue = 0;
MaxValue = 100;
DecimalPlaces = 2;
}
}
keys
{
key(PK; "Reward ID")
{
Clustered = true;
}
}
}
2. Reward Card Page (RewardCard.al): This page allows users to view and edit reward records.
page 50101 "Reward Card"
{
PageType = Card;
UsageCategory = Tasks;
SourceTable = Reward;
layout
{
area(content)
{
group(Reward)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
}
field(Description; Rec.Description)
{
ApplicationArea = All;
}
field("Discount Percentage"; Rec."Discount Percentage")
{
ApplicationArea = All;
}
}
}
}
}
3. Reward List Page (RewardList.al): This page displays a list of rewards and allows users to select and edit them in the Reward Card page.
page 50102 "Reward List"
{
PageType = List;
UsageCategory = Lists;
SourceTable = Reward;
CardPageId = "Reward Card";
layout
{
area(content)
{
repeater(Rewards)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
}
field(Description; Rec.Description)
{
ApplicationArea = All;
}
field("Discount Percentage"; Rec."Discount Percentage")
{
ApplicationArea = All;
}
}
}
}
}
4. Customer Table Extension (CustomerExt.al): This extension adds the Reward ID field to the Customer table.
tableextension 50103 "Customer Ext" extends Customer
{
fields
{
field(50100; "Reward ID"; Code[30])
{
TableRelation = Reward."Reward ID";
ValidateTableRelation = true;
trigger OnValidate()
begin
if (Rec."Reward ID" <> xRec."Reward ID") and (Rec.Blocked <> Blocked::" ") then
begin
Error('Cannot update the rewards status of a blocked customer.');
end;
end;
}
}
}
5. Customer Card Page Extension (CustomerCardExt.al): This extension adds a Reward ID field to the Customer Card page and a related action to open the Reward List page.
pageextension 50104 "Customer Card Ext" extends "Customer Card"
{
layout
{
addlast(General)
{
field("Reward ID"; Rec."Reward ID")
{
ApplicationArea = All;
Lookup = true;
}
}
}
actions
{
addfirst(Navigation)
{
action("Rewards")
{
ApplicationArea = All;
RunObject = page "Reward List";
}
}
}
}
6. Install Codeunit (RewardsInstallCode.al): This codeunit initializes the Reward table with default values.
codeunit 50105 RewardsInstallCode
{
Subtype = Install;
trigger OnInstallAppPerCompany();
var
Reward: Record Reward;
begin
if Reward.IsEmpty() then
begin
InsertDefaultRewards();
end;
end;
procedure InsertDefaultRewards()
begin
InsertRewardLevel('GOLD', 'Gold Level', 20);
InsertRewardLevel('SILVER', 'Silver Level', 10);
InsertRewardLevel('BRONZE', 'Bronze Level', 5);
end;
procedure InsertRewardLevel(ID: Code[30]; Description: Text[250]; Discount: Decimal)
var
Reward: Record Reward;
begin
Reward.Init();
Reward."Reward ID" := ID;
Reward.Description := Description;
Reward."Discount Percentage" := Discount;
Reward.Insert();
end;
}
By following these steps, you will have created a basic extension that allows customers to be assigned reward levels. This extension demonstrates the core components of AL language, including tables, pages, and codeunits, and provides a solid foundation for further customization and development in Microsoft Dynamics 365 Business Central.
Check out the other articles in this series: