BC AL Journey #20
In BC AL Journey #19 we dove deeper into the world of AL Triggers and specifically the Table triggers. This was a continuation of the BC AL Journey #10 where we introduced triggers. This time we are looking at Table Field triggers.
We saw that we can use table triggers for data integrity and management. Table Field triggers function in a similar way, but at the individual field level. This allows us to deal with data updates as they are applied to a field either by a user or other AL processes.
Table Field Triggers
There are only two triggers at the Table Field level: OnValidate and OnLookup.
/*
Customized in BC AL Journey #13
*/
namespace AardvarkLabs;
using Microsoft.Sales.Customer;
table 50001 ARDWarrantyClaim
{
Caption = 'WarrantyClaim';
DataClassification = CustomerContent;
DataCaptionFields = "WarrantyClaimNo.", "CustomerNo.";
fields
{
field(1; "WarrantyClaimNo."; Integer)
{
Caption = 'Warranty Claim No.';
ToolTip = 'Warranty Claim Number';
AutoIncrement = true;
}
field(2; "CustomerNo."; Code[20])
{
Caption = 'Customer No.';
ToolTip = 'Associated Customer Number';
/*
Customized in BC AL Journey #20
*/
trigger OnLookup()
var
Customer: Record Customer;
begin
//Set the filter to only show customers that are not blocked
Customer.SetFilter(Blocked, '%1', Enum::"Customer Blocked"::" ");
//Open the Customer Lookup page and set the filter to the selected customer
if Page.RunModal(page::"Customer Lookup", Customer) <> Action::LookupOK then exit;
//Set the CustomerNo. field to the selected customer
Rec."CustomerNo." := Customer."No.";
end;
}
field(3; Details; Text[255])
{
Caption = 'Details';
ToolTip = 'Warranty claim details';
}
field(4; "Date"; Date)
{
Caption = 'Date';
ToolTip = 'Warranty Claim Date';
}
field(5; Resolved; Boolean)
{
Caption = 'Resolved';
ToolTip = 'Indicate if the Claim has been resolved';
trigger OnValidate()
begin
if Rec.Resolved then
Rec.ResolvedDate := CurrentDateTime;
end;
}
field(6; ResolvedDate; DateTime)
{
Caption = 'Resolved Date';
ToolTip = 'Date the claim was resolved';
}
}
keys
{
key(PK; "WarrantyClaimNo.","CustomerNo.")
{
Clustered = true;
}
}
/*
Customized in BC AL Journey #19
*/
trigger OnInsert()
begin
Rec.Date := DT2Date(CurrentDateTime);
end;
trigger OnModify()
begin
if Rec.Date = 0D then
Rec.Date := DT2Date(CurrentDateTime);
end;
trigger OnDelete()
begin
if Rec.Resolved then
error('Cannot delete a resolved warranty claim');
end;
trigger OnRename()
begin
error('Cannot rename a warranty claim');
end;
}
The OnValidate trigger is the most common trigger. This allows you to immediately perform data validation processes. This happens before the OnInsert or OnModify triggers at the table level. The OnValidate trigger is a good time to validate data entry or update related records based on the user’s data entry. In this example when the Resolved flag is set, we set the resolved date values.
field(5; Resolved; Boolean)
{
Caption = 'Resolved';
ToolTip = 'Indicate if the Claim has been resolved';
trigger OnValidate()
begin
if Rec.Resolved then
Rec.ResolvedDate := CurrentDateTime;
end;
}
Throwing an error here will prevent the record from Inserting or Modifying.
If you are working on a Table Extension, you have a OnBeforeValidate and OnAfterValidate trigger, which operate in much the same way, except before or after the OnValidate defined at the table level.
The other trigger is the OnLookup trigger. This trigger is much less commonly used, but it allows you to control the properties of a record lookup from the table level.
field(2; "CustomerNo."; Code[20])
{
Caption = 'Customer No.';
ToolTip = 'Associated Customer Number';
trigger OnLookup()
var
Customer: Record Customer;
begin
//Set the filter to only show customers that are not blocked
Customer.SetFilter(Blocked, '%1', Enum::"Customer Blocked"::" ");
//Open the Customer Lookup page and set the filter to the selected customer
if Page.RunModal(page::"Customer Lookup", Customer) <> Action::LookupOK then exit;
//Set the CustomerNo. field to the selected customer
Rec."CustomerNo." := Customer."No.";
end;
}
What this code is doing is setting the Customer lookup to filter out any Customer records where the Blocked field is not empty. With this trigger all lookup fields will automatically have this filter applied on every page and list without having to handle it at the page or list level.
While only having two triggers, the Table Field triggers provide a great deal of data validation and user interaction controls. The OnValidate trigger is one of the most used triggers in Business Central as it is critical for providing real time data updates and validation based on user inputs.
This trigger exploration is available in GitHub here: AardvarkMan/BC-AL-Triggers






Leave a comment