Arrays
ToolBox supports one-dimensional arrays: fixed-size, indexed collections of a single element type. Arrays use 1-based indexing, exactly like standard Business Central AL.
Declaring an Array
Declare an array in a var block with the array[N] of ElementType syntax, where N is the number of elements.
var
Scores: array[5] of Integer;
Names: array[8] of Text;
Prices: array[3] of Decimal;
The element type can be any simple type (Integer, BigInteger, Decimal, Text, Code, Boolean, Date, Time, DateTime, Duration, Guid, Char, Byte, DateFormula) or one of the JSON types. Option, Record, Codeunit, Dialog, streams, and collections are not allowed as element types, and the size must be at least 1. Arrays are one-dimensional in ToolBox; multi-dimensional declarations such as array[3, 3] of Integer are not supported.
Accessing Elements
Index an array with square brackets. Valid indexes run from 1 to the declared size.
var
Names: array[3] of Text;
I: Integer;
begin
Names[1] := 'Alice';
Names[2] := 'Bob';
Names[3] := 'Charlie';
for I := 1 to ArrayLen(Names) do
Message('%1: %2', I, Names[I]);
end;
1-based indexing:
Names[1]is the first element. Indexing with0or a value greater than the declared size raises a runtime error.
Array Functions
arraylen
arraylen(array: Array): Integer
Returns the number of elements in the array (its declared size). Arrays are one-dimensional, so the optional dimension argument is always 1.
var
Values: array[10] of Integer;
begin
Message('Array length: %1', ArrayLen(Values)); // 10
end;
compressarray
compressarray(textArray: Array): Integer
Moves all non-empty text entries to the front of the array and returns the count of non-empty entries. The remaining trailing entries are cleared.
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', rest empty
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.
| Parameter | Type | Description |
|---|---|---|
| newArray | Array | Destination (reset before the copy) |
| sourceArray | Array | Source array |
| position | Integer | 1-based start position in the source |
| length | Integer | Optional. Number of elements to copy |
var
Source: array[5] of Integer;
Dest: array[5] of Integer;
I: Integer;
begin
for I := 1 to 5 do
Source[I] := I * 10; // 10, 20, 30, 40, 50
CopyArray(Dest, Source, 3); // copy from index 3 to the end
// Dest[1] = 30, Dest[2] = 40, Dest[3] = 50
Message('%1, %2, %3', Dest[1], Dest[2], Dest[3]);
end;
Arrays Are Passed by Value
An array is a value, not a reference. Passing an array to a procedure copies (clones) the elements — the original and the copy are independent — unless the parameter is declared var, in which case the procedure works on the caller's array. The argument must have the same length and element type as the parameter, and a single element (Arr[1]) cannot be passed to a var parameter. Procedures cannot return arrays. Clear(Arr) resets every element in place.
To match native AL semantics, the ToolBox compiler rejects two constructs as compile errors, so scripts behave the same way they would in standard AL:
| Construct | Result | Native AL equivalent |
|---|---|---|
A := B (whole-array assign) |
Compile error | AL0145 |
foreach X in A (over array) |
Compile error | AL0421 |
// NOT allowed — these do not compile:
// Dest := Source; // whole-array assignment
// foreach V in Source do // foreach over an array
// Do this instead:
CopyArray(Dest, Source, 1); // copy the whole array
for I := 1 to ArrayLen(Source) do
Total += Source[I]; // iterate by index
Differs from standard AL: Nothing — this is exactly the AL behavior. Whole-array assignment and
foreachover an array are compile errors in Business Central AL too, and ToolBox reports them the same way. UseCopyArrayto copy and an indexedforloop to iterate. (foreachis supported over Lists and Dictionaries — see Collections.)
Example: Formatting an Address
The Format Address codeunit fills an array[8] of Text with the lines of a formatted address — the classic AL pattern.
var
Formatter: Codeunit "Format Address";
Customer: Record Customer;
AddrLines: array[8] of Text;
I: Integer;
begin
Customer.Get('10000');
Formatter.Customer(AddrLines, Customer);
for I := 1 to ArrayLen(AddrLines) do
if AddrLines[I] <> '' then
Message('%1', AddrLines[I]);
end;
See Codeunit Support for the full Format Address API, including a text-only form that returns the lines as a List of [Text] instead of filling an array.