Built-in Functions
Introduction
ToolBox provides a comprehensive set of built-in functions that you can call directly in your scripts. These functions cover date and time operations, math, string manipulation, dialogs, system operations, and type handling.
Each function is documented below with its syntax, parameters, return value, description, and a usage example.
Date and Time Functions
today
today(): Date
Returns the current system date.
var
CurrentDate: Date;
begin
CurrentDate := Today();
Message('Today is: %1', CurrentDate);
end;
workdate
workdate(): Date
workdate(newWorkDate: Date): Date
Returns the current work date as set in Business Central. The work date may differ from the system date if a user has configured it. With an argument, it sets the work date for the session and returns it.
begin
Message('Work date: %1', WorkDate());
Message('System date: %1', Today());
WorkDate(20250101D); // change the work date for this session
end;
time
time(): Time
Returns the current system time.
begin
Message('Current time: %1', Time());
end;
currentdatetime
currentdatetime(): DateTime
Returns the current date and time as a DateTime value.
var
Now: DateTime;
begin
Now := CurrentDateTime();
Message('Current date and time: %1', Now);
end;
createdatetime
createdatetime(date: Date, time: Time): DateTime
Creates a DateTime value from separate date and time components.
| Parameter | Type | Description |
|---|---|---|
| date | Date | The date part |
| time | Time | The time part |
var
MyDateTime: DateTime;
begin
MyDateTime := CreateDateTime(Today(), Time());
Message('Created DateTime: %1', MyDateTime);
end;
dmy2date
dmy2date(day: Integer, month: Integer, year: Integer): Date
Creates a Date value from day, month, and year components.
| Parameter | Type | Description |
|---|---|---|
| day | Integer | Day of the month (1-31) |
| month | Integer | Month (1-12) |
| year | Integer | Year (e.g., 2025) |
var
SpecificDate: Date;
begin
SpecificDate := DMY2Date(15, 6, 2025);
Message('Date: %1', SpecificDate);
end;
date2dmy
date2dmy(date: Date, what: Integer): Integer
Extracts a component from a date value.
| Parameter | Type | Description |
|---|---|---|
| date | Date | The date to extract from |
| what | Integer | 1 = day, 2 = month, 3 = year |
var
MyDate: Date;
begin
MyDate := Today();
Message('Day: %1', Date2DMY(MyDate, 1));
Message('Month: %1', Date2DMY(MyDate, 2));
Message('Year: %1', Date2DMY(MyDate, 3));
end;
date2dwy
date2dwy(date: Date, what: Integer): Integer
Extracts week-related information from a date value.
| Parameter | Type | Description |
|---|---|---|
| date | Date | The date to extract from |
| what | Integer | 1 = day of week (1-7), 2 = week number, 3 = year |
var
MyDate: Date;
begin
MyDate := Today();
Message('Day of week: %1', Date2DWY(MyDate, 1));
Message('Week number: %1', Date2DWY(MyDate, 2));
Message('Year: %1', Date2DWY(MyDate, 3));
end;
calcdate
calcdate(formula: Text): Date
calcdate(formula: Text, date: Date): Date
Calculates a new date by applying a date formula to a base date. Without a base date, the work date is used.
| Parameter | Type | Description |
|---|---|---|
| formula | Text | The date formula (e.g., '<+30D>'); a DateFormula variable is accepted too |
| date | Date | Optional. The base date to calculate from (default: work date) |
var
BaseDate: Date;
FutureDate: Date;
begin
BaseDate := Today();
FutureDate := CalcDate('<+30D>', BaseDate);
Message('30 days from now: %1', FutureDate);
FutureDate := CalcDate('<+1M>', BaseDate);
Message('1 month from now: %1', FutureDate);
FutureDate := CalcDate('<CW>', BaseDate);
Message('End of current week: %1', FutureDate);
end;
dt2date / dt2time
dt2date(datetime: DateTime): Date
dt2time(datetime: DateTime): Time
Extract the date part or the time part from a DateTime value.
var
Now: DateTime;
begin
Now := CurrentDateTime();
Message('Date part: %1', DT2Date(Now));
Message('Time part: %1', DT2Time(Now));
end;
dwy2date
dwy2date(weekday: Integer[, week: Integer[, year: Integer]]): Date
Builds a date from a weekday (1 = Monday .. 7 = Sunday) and, optionally, a week number and year. It is the inverse of Date2DWY.
| Parameter | Type | Description |
|---|---|---|
| weekday | Integer | 1 = Monday .. 7 = Sunday |
| week | Integer | Optional. ISO week number |
| year | Integer | Optional. Year |
var
D: Date;
begin
D := DWY2Date(1, 10, 2025); // Monday of week 10 in 2025
Message('Date: %1', D);
end;
normaldate / closingdate
normaldate(date: Date): Date
closingdate(date: Date): Date
ClosingDate returns the closing date associated with a date (used for period-end closing entries); NormalDate strips the closing-date marker, returning the ordinary date.
var
D: Date;
C: Date;
begin
D := DMY2Date(31, 12, 2024);
C := ClosingDate(D); // closing date for year-end
Message('Closing: %1, Normal: %1', C, NormalDate(C));
end;
Math Functions
abs
abs(number: Decimal): Decimal
Returns the absolute (non-negative) value of a number.
var
Value: Decimal;
begin
Value := -42.5;
Message('Absolute value: %1', Abs(Value)); // 42.5
end;
power
power(base: Decimal, exponent: Decimal): Decimal
Raises a number to the specified power.
| Parameter | Type | Description |
|---|---|---|
| base | Decimal | The base number |
| exponent | Decimal | The exponent |
begin
Message('2^10 = %1', Power(2, 10)); // 1024
Message('Square root of 16 = %1', Power(16, 0.5)); // 4
end;
round
round(number: Decimal[, precision: Decimal[, direction: Text]]): Decimal
Rounds a number to the specified precision.
| Parameter | Type | Description |
|---|---|---|
| number | Decimal | The number to round |
| precision | Decimal | Optional. The rounding precision (default 1) |
| direction | Text | Optional. '=' nearest (default), '>' up, '<' down |
begin
Message('Round 3.456 to 2 decimals: %1', Round(3.456, 0.01)); // 3.46
Message('Round up: %1', Round(3.451, 0.01, '>')); // 3.46
Message('Round down: %1', Round(3.459, 0.01, '<')); // 3.45
Message('Round to nearest 5: %1', Round(17, 5, '=')); // 15
end;
random
random(maxvalue: Integer): Integer
Returns a random integer between 1 and the specified maximum value (inclusive).
| Parameter | Type | Description |
|---|---|---|
| maxvalue | Integer | The maximum value (must be >= 1) |
var
Roll: Integer;
begin
Roll := Random(6);
Message('Dice roll: %1', Roll);
end;
randomize
randomize([seed: Integer])
Initializes the random number generator. Call this before using Random() to get different sequences on each run.
| Parameter | Type | Description |
|---|---|---|
| seed | Integer | Optional. Specific seed for reproducible results |
var
I: Integer;
begin
Randomize();
for I := 1 to 5 do
Message('Random number: %1', Random(100));
end;
String Functions
strlen
strlen(text: Text): Integer
Returns the number of characters in a text value.
begin
Message('Length: %1', StrLen('Hello World')); // 11
end;
strpos
strpos(text: Text, substring: Text): Integer
Returns the position of the first occurrence of a substring within a text value. Returns 0 if the substring is not found.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The text to search in |
| substring | Text | The text to search for |
begin
Message('Position: %1', StrPos('Hello World', 'World')); // 7
Message('Not found: %1', StrPos('Hello World', 'xyz')); // 0
end;
copystr
copystr(text: Text, position: Integer[, length: Integer]): Text
Extracts a substring from a text value.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The source text |
| position | Integer | The starting position (1-based) |
| length | Integer | Optional. Number of characters to extract |
begin
Message('Substring: %1', CopyStr('Hello World', 7)); // World
Message('Substring: %1', CopyStr('Hello World', 1, 5)); // Hello
end;
delstr
delstr(text: Text, position: Integer, length: Integer): Text
Deletes a number of characters from a text value.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The source text |
| position | Integer | The starting position (1-based) |
| length | Integer | Number of characters to delete |
begin
Message('Result: %1', DelStr('Hello World', 6, 6)); // Hello
end;
delchr
delchr(text: Text[, where: Text[, which: Text]]): Text
Deletes specified characters from a text value. With one argument it removes leading spaces; where and which refine what is removed.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The source text |
| where | Text | Optional. '<' from start, '>' from end, '=' anywhere (combine as '<>') |
| which | Text | Optional. Characters to delete (default: space) |
begin
Message('Result: %1', DelChr(' Hello ', '<>', ' ')); // Hello
Message('Result: %1', DelChr('A1B2C3', '=', '0123456789')); // ABC
end;
uppercase / lowercase
uppercase(text: Text): Text
lowercase(text: Text): Text
Converts text to uppercase or lowercase.
begin
Message('Upper: %1', UpperCase('hello')); // HELLO
Message('Lower: %1', LowerCase('HELLO')); // hello
end;
incstr
incstr(text: Text): Text
Increments a numeric suffix in a text value. This is useful for generating sequential document numbers.
begin
Message('Next: %1', IncStr('DOC-0001')); // DOC-0002
Message('Next: %1', IncStr('INV-0099')); // INV-0100
end;
padstr
padstr(text: Text, length: Integer[, padchar: Text]): Text
Pads or truncates a text value to a specified length.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The source text |
| length | Integer | Desired length (negative = pad left) |
| padchar | Text | Optional. Character to use for padding |
begin
Message('Padded: [%1]', PadStr('Hello', 10)); // [Hello ]
Message('Padded: [%1]', PadStr('Hello', -10)); // [ Hello]
end;
convertstr
convertstr(text: Text, from: Text, to: Text): Text
Converts characters in a text value by replacing each character in from with the corresponding character in to.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The source text |
| from | Text | Characters to replace |
| to | Text | Replacement characters |
begin
Message('Result: %1', ConvertStr('1-2-3', '-', '/')); // 1/2/3
end;
maxstrlen
maxstrlen(text: Text): Integer
Returns the maximum length defined for a text variable.
var
ShortText: Text[50];
begin
Message('Max length: %1', MaxStrLen(ShortText)); // 50
end;
selectstr
selectstr(index: Integer, text: Text): Text
Returns a specific comma-separated value from a text string by index.
| Parameter | Type | Description |
|---|---|---|
| index | Integer | The 1-based index of the value |
| text | Text | Comma-separated string |
begin
Message('Second value: %1', SelectStr(2, 'Alpha,Beta,Gamma')); // Beta
end;
insstr
insstr(text: Text, newText: Text, position: Integer): Text
Inserts newText into text at the 1-based position.
begin
Message('%1', InsStr('Hello World', ' Beautiful', 6)); // Hello Beautiful World
end;
strchecksum
strchecksum(text: Text[, weights: Text[, modulus: Integer]]): Integer
Calculates a checksum for a text of digits, optionally weighted and reduced by a modulus (the standard AL algorithm used for check digits).
begin
Message('Checksum: %1', StrCheckSum('123456789', '131313131', 10));
end;
format
format(value: Any[, length: Integer[, formatstring: Text]]): Text
Converts any value to its text representation, following the native AL Format rules.
| Parameter | Type | Description |
|---|---|---|
| value | Any | The value to format |
| length | Integer | Optional. Desired output length (0 = as needed) |
| formatstring | Text or Integer | Optional. A format string such as '<Precision,2:2><Standard Format,0>', or a standard format number such as 9 for the XML/culture-invariant format |
An Option value formats as its member caption, a whole record as its primary key, and JSON values, lists, and dictionaries as their JSON text.
var
Amount: Decimal;
D: Date;
begin
Amount := 12345.678;
Message('Default: %1', Format(Amount));
Message('Formatted: %1', Format(Amount, 0, '<Precision,2:2><Standard Format,0>'));
D := Today();
Message('XML date: %1', Format(D, 0, 9)); // 2025-06-15
end;
strsubstno
strsubstno(template: Text, arg1: Any[, arg2: Any, ...]): Text
Performs string substitution, replacing %1, %2, etc. with the provided arguments.
| Parameter | Type | Description |
|---|---|---|
| template | Text | The template with placeholders |
| arg1..N | Any | Values to substitute |
var
Result: Text;
begin
Result := StrSubstNo('Customer %1 has %2 orders totaling %3', 'C10000', 5, 12500.00);
Message(Result);
end;
evaluate
evaluate(var variable: Any, text: Text[, xmlFormat: Integer]): Boolean
Parses a text value and stores the result in a typed variable. Returns true if the parsing succeeds; on failure it returns false and leaves the variable unchanged. Used as a statement (not inside if), a failed parse raises an error. Pass 9 as the third argument to parse the culture-invariant XML format.
| Parameter | Type | Description |
|---|---|---|
| variable | Any | The variable to receive the parsed value. Supported types: Boolean, Integer, BigInteger, Decimal, Text, Code, Date, Time, DateTime, Duration, Guid, DateFormula |
| text | Text | The text to parse |
| xmlFormat | Integer | Optional. 9 for the XML format |
var
Amount: Decimal;
MyDate: Date;
begin
if Evaluate(Amount, '1234.56') then
Message('Parsed amount: %1', Amount);
if Evaluate(MyDate, '01/15/2025') then
Message('Parsed date: %1', MyDate);
end;
Dialog Functions
message
message(text: Text[, arg1: Any, ...])
Displays a message. In ToolBox, messages are typically sent to the console output, one line per call. Up to seven placeholder values (%1..%7) can be supplied; use StrSubstNo first when you need more.
begin
Message('Simple message');
Message('Customer %1 has balance %2', 'C10000', 5000.00);
end;
confirm
confirm(text: Text[, default: Boolean]): Boolean
Displays a Yes/No confirmation dialog and returns the user's choice.
| Parameter | Type | Description |
|---|---|---|
| text | Text | The question to display |
| default | Boolean | Optional. Default selection (true = Yes) |
begin
if Confirm('Do you want to continue?', true) then
Message('User selected Yes')
else
Message('User selected No');
end;
strmenu
strmenu(options: Text[, default: Integer[, instruction: Text]]): Integer
Displays a selection menu and returns the selected option number. Returns 0 if the user cancels. Requires a user session (see GuiAllowed).
| Parameter | Type | Description |
|---|---|---|
| options | Text | Comma-separated list of options |
| default | Integer | Optional. Default selection (1-based) |
| instruction | Text | Optional. Instruction text shown above the options |
var
Choice: Integer;
begin
Choice := StrMenu('Option A,Option B,Option C', 1);
case Choice of
1: Message('You chose Option A');
2: Message('You chose Option B');
3: Message('You chose Option C');
0: Message('You cancelled');
end;
end;
error
error(text: Text[, arg1: Any, ...])
Raises a runtime error, terminating the script and displaying the error message (in the console when console capture is on). Up to seven placeholder values can be supplied. There is no way to catch an error inside a script: asserterror, [TryFunction], and GetLastErrorText are not available.
var
Customer: Record Customer;
begin
if not Customer.Get('INVALID') then
Error('Customer %1 does not exist.', 'INVALID');
end;
System Functions
commit
commit()
Commits the current database transaction. After calling Commit(), you cannot roll back any changes made before this point.
var
Customer: Record Customer;
begin
Customer.Get('10000');
Customer.Name := 'Updated Name';
Customer.Modify();
Commit();
Message('Changes committed');
end;
createguid
createguid(): Guid
Generates a new globally unique identifier (GUID).
var
NewId: Guid;
begin
NewId := CreateGuid();
Message('New GUID: %1', NewId);
end;
startsession
startsession(var sessionId: Integer, codeunitId: Integer[, companyName: Text[, record: Record]]): Boolean
Starts a background session that runs a specified codeunit, exactly like the standard AL function. The first argument receives the new session id.
| Parameter | Type | Description |
|---|---|---|
| sessionId | Integer | Receives the id of the started session |
| codeunitId | Integer | The ID of the codeunit to run |
| companyName | Text | Optional. The company to run in |
| record | Record | Optional. Record variable to pass to the session |
var
NewSessionId: Integer;
begin
if StartSession(NewSessionId, 50100, CompanyName()) then
Message('Background session %1 started', NewSessionId)
else
Message('Failed to start session');
end;
companyname
companyname(): Text
Returns the name of the current company.
userid / guiallowed / sessionid
userid(): Text
guiallowed(): Boolean
sessionid(): Integer
Return the current user id, whether a user interface is available, and the current session id. These three can also be written without parentheses (UserId), as in standard AL. Use GuiAllowed to skip dialogs when a program runs from the Job Queue.
begin
if GuiAllowed then
Message('Hello %1', UserId)
else
Message('Running in the background as %1 (session %2)', UserId, SessionId);
end;
isnullguid
isnullguid(value: Guid): Boolean
Returns true when the GUID is the empty (all-zero) GUID.
clear
clear(var variable: Any)
Resets a variable to its default value: empty text, zero, false, 0D, the null GUID, an empty collection or JSON value, or an array with every element reset. For a record variable it removes filters and clears the fields; a temporary record keeps its rows (use DeleteAll). Clear(Rec.Field) resets that one field only and leaves the rest of the record and its filters untouched; on a Blob field it empties the content and discards an open OutStream's unsaved writes.
sleep
sleep(milliseconds: Integer)
Pauses script execution for the specified number of milliseconds.
| Parameter | Type | Description |
|---|---|---|
| milliseconds | Integer | Duration to pause in milliseconds |
begin
Message('Starting...');
Sleep(2000);
Message('2 seconds later...');
end;
Type Functions
arraylen
arraylen(array: Array): Integer
Returns the number of elements in an array.
var
Values: array[10] of Integer;
begin
Message('Array length: %1', ArrayLen(Values)); // 10
end;
compressarray
compressarray(array: Array): Integer
Moves all non-empty entries in an array to the beginning and returns the count of non-empty entries.
var
Names: array[5] of Text;
Count: Integer;
begin
Names[1] := 'Alice';
Names[3] := 'Charlie';
Names[5] := 'Eve';
Count := CompressArray(Names);
Message('Non-empty entries: %1', Count); // 3
// Names[1] = 'Alice', Names[2] = 'Charlie', Names[3] = 'Eve'
end;
copyarray
copyarray(newArray: Array, sourceArray: Array, position: Integer[, length: Integer])
Clears newArray, then copies elements from sourceArray starting at position. When length is omitted, it copies to the end of the source. For more on arrays, see Arrays.
var
Source: array[5] of Integer;
Dest: array[5] of Integer;
I: Integer;
begin
for I := 1 to 5 do
Source[I] := I * 10;
CopyArray(Dest, Source, 3); // Dest gets 30, 40, 50
Message('%1, %2, %3', Dest[1], Dest[2], Dest[3]);
end;
Stream Functions
These functions move data between streams and the client. See Streams for how to obtain InStream/OutStream values.
copystream
copystream(toOutStream: OutStream, fromInStream: InStream)
Copies all remaining data from an InStream into an OutStream.
downloadfromstream
downloadfromstream(inStream: InStream, dialogTitle: Text, toFolder: Text, toFilter: Text, var toFile: Text): Boolean
Sends the contents of an InStream to the user as a file download. Returns false if the user cancels.
uploadintostream
uploadintostream(dialogTitle: Text, fromFolder: Text, fromFilter: Text, var fromFile: Text, var inStream: InStream): Boolean
Prompts the user to upload a file and exposes it as an InStream. Returns false if the user cancels.
var
In: InStream;
FileName: Text;
Content: Text;
begin
if UploadIntoStream('Select a file', '', 'Text Files (*.txt)|*.txt', FileName, In) then begin
In.ReadText(Content);
Message('First line of %1: %2', FileName, Content);
end;
end;
Summary
These built-in functions provide the foundation for writing effective ToolBox scripts. You can combine them to handle date calculations, string processing, math operations, user interactions, and system-level tasks. For methods that operate on specific data types (such as text instance methods or record methods), see the related topics below.