Formatting functions are available throughout the Articles report script editor. They convert raw data values into display-ready text — handling currency, numbers, dates, phone numbers, addresses, and boolean values consistently across your reports.
AddressBlock
Builds a formatted multi-line address block from individual address components. Empty fields are skipped automatically so blank lines never appear in the output.
AddressBlock(Company, Contact, Address1, Address2, City, State, Zip, Country: String): String
| Parameter | Type | Description |
|---|---|---|
| Company | String | Company name |
| Contact | String | Contact person name |
| Address1 | String | Street address line 1 |
| Address2 | String | Street address line 2 (suite, unit, etc.) |
| City | String | City |
| State | String | State or province |
| Zip | String | Postal code |
| Country | String | Country (omitted if blank) |
// Full address block for a shipping label
Result := AddressBlock(
[Customer.Company],
[Customer.Contact],
[Customer.Address1],
[Customer.Address2],
[Customer.City],
[Customer.State],
[Customer.Zip],
[Customer.Country]
);
// Returns something like:
// Acme Corp
// John Smith
// 123 Main St
// Suite 400
// Miami, FL 33101
// If Address2 and Country are blank they are simply omitted:
// Acme Corp
// 123 Main St
// Miami, FL 33101
CityStateZip
Formats a city, state, and zip code into a single standard line in the form City, State Zip. Empty components are handled gracefully.
CityStateZip(City, State, Zip: String): String
| Parameter | Type | Description |
|---|---|---|
| City | String | City name |
| State | String | State or province abbreviation |
| Zip | String | Postal code |
Result := CityStateZip([Customer.City], [Customer.State], [Customer.Zip]);
// Returns: 'Miami, FL 33101'
// Use inside a larger address expression
Result := [Customer.Address1] + #13#10 +
CityStateZip([Customer.City], [Customer.State], [Customer.Zip]);
Format
Builds a formatted string by substituting values into a format template, similar to printf in other languages. This is the most flexible general-purpose formatting function available and can combine multiple values and literal text in a single call.
Format(Fmt: String; Args: array): String
| Parameter | Type | Description |
|---|---|---|
| Fmt | String | Format template string containing format specifiers |
| Args | array | Array of values to substitute into the template |
Common format specifiers:
| Specifier | Description |
|---|---|
| %d | Integer |
| %f | Floating point |
| %s | String |
| %n | Number with thousands separator |
| %.2f | Float with 2 decimal places |
| %5d | Integer right-aligned in 5 characters |
// Format an integer
Result := Format('Invoice #%d', [InvoiceNumber]);
// Returns: 'Invoice #1234'
// Format a float to 2 decimal places
Result := Format('Total: $%.2f', [OrderTotal]);
// Returns: 'Total: $1250.00'
// Combine multiple values
Result := Format('%s %s — Order #%d', [FirstName, LastName, OrderNumber]);
// Returns: 'John Smith — Order #5001'
// Right-align a number in a fixed width
Result := Format('%8.2f', [Amount]);
// Returns: ' 125.50' (8 characters wide)
FormatBoolText
Formats a boolean or boolean-like variant value as custom true/false text. Use this when Yes/No is not the right wording for your report.
FormatBoolText(V: Variant; TrueText, FalseText: String): String
| Parameter | Type | Description |
|---|---|---|
| V | Variant | The boolean or boolean-like value to evaluate |
| TrueText | String | Text to return when the value is true |
| FalseText | String | Text to return when the value is false |
Result := FormatBoolText([Item.IsActive], 'Active', 'Inactive');
Result := FormatBoolText([Vendor.Approved], 'Approved', 'Pending Review');
Result := FormatBoolText([Employee.FullTime], 'Full Time', 'Part Time');
FormatBoolYesNo
Formats a boolean or boolean-like variant value as Yes or No. See also FormatBoolText for custom wording.
FormatBoolYesNo(V: Variant): String
| Parameter | Type | Description |
|---|---|---|
| V | Variant | The boolean or boolean-like value to evaluate |
Result := FormatBoolYesNo([Customer.TaxExempt]);
// Returns: 'Yes' or 'No'
Result := FormatBoolYesNo([Item.Discontinued]);
// Use in an inline text object expression
// [FormatBoolYesNo([Orders.IsRush])]
FormatCurrencySafe
Formats a value as currency using the system’s current currency settings. Handles Null and non-numeric values safely without raising an error, returning a blank string instead.
FormatCurrencySafe(V: Variant): String
| Parameter | Type | Description |
|---|---|---|
| V | Variant | The numeric or variant value to format |
Result := FormatCurrencySafe([Orders.Total]);
// Returns: '$1,250.00'
// Returns '' safely if the field is NULL rather than raising an error
Result := FormatCurrencySafe([Orders.Balance]);
// Use in a text object
// [FormatCurrencySafe([Invoice.AmountDue])]
FormatDate
Formats a date value using a FormatDateTime mask string. Use this when you need a specific date format rather than the system default. See also FormatDateSafe for null-safe formatting.
FormatDate(DateValue: Date; Mask: String): String
| Parameter | Type | Description |
|---|---|---|
| DateValue | Date | The date value to format |
| Mask | String | A FormatDateTime mask string (e.g. 'mm/dd/yyyy') |
Common mask characters:
| Mask | Output |
|---|---|
| d / dd | Day without / with leading zero |
| m / mm | Month without / with leading zero |
| mmm | Abbreviated month name (Jan, Feb…) |
| mmmm | Full month name (January, February…) |
| yy / yyyy | 2 or 4 digit year |
| hh:nn:ss | Hours, minutes, seconds |
Result := FormatDate([Orders.OrderDate], 'mm/dd/yyyy');
// Returns: '03/15/2024'
Result := FormatDate([Orders.OrderDate], 'mmmm d, yyyy');
// Returns: 'March 15, 2024'
Result := FormatDate([Orders.OrderDate], 'yyyy-mm-dd');
// Returns: '2024-03-15' (ISO format, useful for exports)
FormatDateRange
Formats a start and end date as a readable date range string. Handles Null values in either date safely.
FormatDateRange(StartDate, EndDate: Variant): String
| Parameter | Type | Description |
|---|---|---|
| StartDate | Variant | The range start date |
| EndDate | Variant | The range end date |
Result := FormatDateRange([Project.StartDate], [Project.EndDate]);
// Returns: '01/01/2024 - 03/31/2024'
// Use in a report header to show the period covered
Result := 'Period: ' + FormatDateRange([Report.FromDate], [Report.ToDate]);
FormatDateSafe
Formats a date value using a mask string but handles Null and invalid values safely without raising an error. Use this instead of FormatDate when the date field may be null.
FormatDateSafe(V: Variant; Mask: String): String
| Parameter | Type | Description |
|---|---|---|
| V | Variant | The date value to format. Null values return a blank string. |
| Mask | String | A FormatDateTime mask string |
// Returns '' if LastOrderDate is NULL rather than raising an error
Result := FormatDateSafe([Customer.LastOrderDate], 'mm/dd/yyyy');
// Safe for fields that are often blank
Result := FormatDateSafe([Employee.TerminationDate], 'mm/dd/yyyy');
// Provide a fallback when the date is missing
var d := FormatDateSafe([Vendor.ContractExpiry], 'mm/dd/yyyy');
if d = '' then
Result := 'No expiry'
else
Result := d;
FormatDateTime
Formats a date and time value using a mask string. This is the standard built-in formatting function and works with both date-only and date-time values.
FormatDateTime(Fmt: String; DateTime: TDateTime): String
| Parameter | Type | Description |
|---|---|---|
| Fmt | String | A format mask string (same mask characters as FormatDate) |
| DateTime | TDateTime | The date/time value to format |
Result := FormatDateTime('mm/dd/yyyy', [Orders.OrderDate]);
// Returns: '03/15/2024'
Result := FormatDateTime('mm/dd/yyyy hh:nn:ss', Now);
// Returns: '03/15/2024 14:30:00' (current date and time)
Result := FormatDateTime('dddd, mmmm d yyyy', [Orders.OrderDate]);
// Returns: 'Friday, March 15 2024'
// Use Now to stamp the current date/time on a report
Result := 'Printed: ' + FormatDateTime('mm/dd/yyyy hh:nn', Now);
FormatFloat
Formats a floating point number using a format mask string. Provides fine control over decimal places, digit grouping, and padding.
FormatFloat(Fmt: String; Value: Extended): String
| Parameter | Type | Description |
|---|---|---|
| Fmt | String | A numeric format mask string |
| Value | Extended | The number to format |
Common format mask characters:
| Mask | Description |
|---|---|
| 0 | Digit placeholder — always shows a digit, uses 0 if no digit |
| # | Digit placeholder — shows nothing if no digit |
| . | Decimal point position |
| , | Thousands separator |
| ; | Separates positive and negative format sections |
Result := FormatFloat('0.00', 1250);
// Returns: '1250.00'
Result := FormatFloat('#,##0.00', 1250.5);
// Returns: '1,250.50'
Result := FormatFloat('#,##0.00;(#,##0.00)', -500);
// Returns: '(500.00)' — negative shown in parentheses
Result := FormatFloat('0.0000', [Item.UnitCost]);
// Returns: '1.2500' — 4 decimal places for unit costs
// Show percentage
Result := FormatFloat('0.00"%"', [Stats.Rate] * 100);
// Returns: '12.50%'
FormatMaskText
Formats a string value using an edit mask, inserting literal characters such as dashes, parentheses, and slashes at fixed positions. Useful for formatting codes, phone numbers, or IDs that have a known fixed structure.
FormatMaskText(EditMask: String; Value: String): String
| Parameter | Type | Description |
|---|---|---|
| EditMask | String | The mask string defining the output format |
| Value | String | The raw string value to format |
// Format a 9-digit SSN as 123-45-6789
Result := FormatMaskText('000-00-0000', CleanNumber([Employee.SSN]));
// Format a 10-digit phone number
Result := FormatMaskText('(000) 000-0000', CleanNumber([Customer.Phone]));
// Format a zip+4 code
Result := FormatMaskText('00000-0000', CleanNumber([Customer.Zip]));
FormatNumberSafe
Formats a numeric value with a specified number of decimal places. Handles Null and non-numeric values safely, returning a blank string instead of raising an error.
FormatNumberSafe(V: Variant; Decimals: Integer): String
| Parameter | Type | Description |
|---|---|---|
| V | Variant | The numeric or variant value to format |
| Decimals | Integer | Number of decimal places to display |
Result := FormatNumberSafe([Item.Weight], 2);
// Returns: '12.50'
Result := FormatNumberSafe([Orders.Quantity], 0);
// Returns: '250' (no decimal places)
Result := FormatNumberSafe([Item.UnitCost], 4);
// Returns: '1.2500' (4 decimal places for unit costs)
// Returns '' safely if the field is NULL
Result := FormatNumberSafe([Orders.DiscountRate], 2);
FormatPhone
Formats a 10-digit string of digits as a standard US phone number in the form (xxx) xxx-xxxx. Non-digit characters in the input are ignored.
FormatPhone(S: String): String
| Parameter | Type | Description |
|---|---|---|
| S | String | A string containing at least 10 digits |
Result := FormatPhone([Customer.Phone]);
// '5551234567' becomes '(555) 123-4567'
// '555-123-4567' also becomes '(555) 123-4567'
// Validate length before formatting
if Length(CleanNumber([Customer.Phone])) = 10 then
Result := FormatPhone([Customer.Phone])
else
Result := [Customer.Phone];
NormalizeCountry
Normalises a country value to a consistent standard form. Handles common abbreviations, alternate spellings, and mixed-case input.
NormalizeCountry(S: String): String
| Parameter | Type | Description |
|---|---|---|
| S | String | The country value to normalise |
Result := NormalizeCountry([Customer.Country]);
// 'usa', 'US', 'u.s.a' all return 'United States'
// Use before printing an address block
Result := AddressBlock(
[Customer.Company], [Customer.Contact],
[Customer.Address1], [Customer.Address2],
[Customer.City], [Customer.State], [Customer.Zip],
NormalizeCountry([Customer.Country])
);
NormalizeState
Normalises a state value to a consistent standard abbreviation. Handles full state names, lowercase, and mixed-case input.
NormalizeState(S: String): String
| Parameter | Type | Description |
|---|---|---|
| S | String | The state value to normalise |
Result := NormalizeState([Customer.State]);
// 'florida', 'FL', 'Fl' all return 'FL'
// Useful when state data comes from inconsistent input sources
Result := CityStateZip(
[Customer.City],
NormalizeState([Customer.State]),
[Customer.Zip]
);
OneLineAddress
Formats a complete address as a single line of text, with components separated by commas. Useful for columns, exports, or anywhere a multi-line block will not fit.
OneLineAddress(Company, Contact, Address1, Address2, City, State, Zip, Country: String): String
| Parameter | Type | Description |
|---|---|---|
| Company | String | Company name |
| Contact | String | Contact person name |
| Address1 | String | Street address line 1 |
| Address2 | String | Street address line 2 |
| City | String | City |
| State | String | State or province |
| Zip | String | Postal code |
| Country | String | Country |
Result := OneLineAddress(
[Customer.Company], [Customer.Contact],
[Customer.Address1], [Customer.Address2],
[Customer.City], [Customer.State],
[Customer.Zip], [Customer.Country]
);
// Returns: 'Acme Corp, John Smith, 123 Main St, Miami, FL 33101'