1. Home
  2. /
  3. Docs
  4. /
  5. Articles Report Writer
  6. /
  7. Report Functions
  8. /
  9. Formatting Functions

Formatting Functions

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
ParameterTypeDescription
CompanyStringCompany name
ContactStringContact person name
Address1StringStreet address line 1
Address2StringStreet address line 2 (suite, unit, etc.)
CityStringCity
StateStringState or province
ZipStringPostal code
CountryStringCountry (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
ParameterTypeDescription
CityStringCity name
StateStringState or province abbreviation
ZipStringPostal 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
ParameterTypeDescription
FmtStringFormat template string containing format specifiers
ArgsarrayArray of values to substitute into the template

Common format specifiers:

SpecifierDescription
%dInteger
%fFloating point
%sString
%nNumber with thousands separator
%.2fFloat with 2 decimal places
%5dInteger 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
ParameterTypeDescription
VVariantThe boolean or boolean-like value to evaluate
TrueTextStringText to return when the value is true
FalseTextStringText 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
ParameterTypeDescription
VVariantThe 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
ParameterTypeDescription
VVariantThe 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
ParameterTypeDescription
DateValueDateThe date value to format
MaskStringA FormatDateTime mask string (e.g. 'mm/dd/yyyy')

Common mask characters:

MaskOutput
d / ddDay without / with leading zero
m / mmMonth without / with leading zero
mmmAbbreviated month name (Jan, Feb…)
mmmmFull month name (January, February…)
yy / yyyy2 or 4 digit year
hh:nn:ssHours, 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
ParameterTypeDescription
StartDateVariantThe range start date
EndDateVariantThe 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
ParameterTypeDescription
VVariantThe date value to format. Null values return a blank string.
MaskStringA 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
ParameterTypeDescription
FmtStringA format mask string (same mask characters as FormatDate)
DateTimeTDateTimeThe 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
ParameterTypeDescription
FmtStringA numeric format mask string
ValueExtendedThe number to format

Common format mask characters:

MaskDescription
0Digit 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
ParameterTypeDescription
EditMaskStringThe mask string defining the output format
ValueStringThe 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
ParameterTypeDescription
VVariantThe numeric or variant value to format
DecimalsIntegerNumber 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
ParameterTypeDescription
SStringA 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
ParameterTypeDescription
SStringThe 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
ParameterTypeDescription
SStringThe 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
ParameterTypeDescription
CompanyStringCompany name
ContactStringContact person name
Address1StringStreet address line 1
Address2StringStreet address line 2
CityStringCity
StateStringState or province
ZipStringPostal code
CountryStringCountry
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'