Report Calculated Fields
Report calculated fields let you add computed values to report datasets without storing data in tables. This page explains how to create and use report calculated fields.
What Are Report Calculated Fields
Report calculated fields are:
- Computed at report runtime
- Based on expressions you define
- Added to the report dataset
- Available in report layouts
Unlike table-stored fields, calculated fields don't occupy database storage. They compute values when the report runs.
Accessing Report Calculated Fields
- Open Tasks > Report Calculated Fields
- Or from Inspect > Reports > Customize Report > Calculated Fields action
Creating a Report Calculated Field
Step 1: Select the Report
- Open Report Calculated Fields
- Click New
- Select the target report
Step 2: Select the Data Item
Choose which data item (table) the calculated field belongs to:
- This determines the scope of available fields
- Your expression can reference fields from this data item
Step 3: Name the Field
Enter a name for your calculated field:
- Use descriptive names
- Follow naming conventions
- SOD adds prefix/suffix automatically
Step 4: Set the Type
Choose the result type:
- Decimal - For numeric calculations
- Integer - For whole-number results
- Text - For text operations
- Date - For date calculations
- Duration - For elapsed-time results
Subtracting two dates gives a day count, not a date. Set the Type to Integer (or Duration), not Date. Setting Type = Date for a subtraction result is a type mismatch and a very common mistake.
Step 5: Write the Expression
Enter your calculation expression. See Expression Editor section below.
Step 6: Optional Properties
If the field type is Decimal, set DecimalPlaces to control display precision. For barcode output (e.g. for label printing), enable Encode As Barcode and set BarCode Encoding.
Report calculated fields are appended to the dataset of the chosen data item; there is no Placement Type / Anchor on report calc fields.
The Report Calculated Fields Page
Columns
| Column | Description |
|---|---|
| Report No. | Target report |
| Report Name | Report name |
| DataItem | Data item/table scope |
| Name | Calculated field name |
| Type | Result type (Decimal / Integer / Text / Date / Duration) |
| Expression | The calculation formula |
| DecimalPlaces | Display precision for Decimal type |
| Encode As Barcode | Render value as a barcode string |
| BarCode Encoding | Barcode symbology to use when encoding |
Expression Editor
Accessing the Editor
- Select a calculated field row
- Click Edit Expression or the expression cell
- The expression editor opens
Expression Syntax
Expressions use AL-like syntax:
Field references:
Rec."Field Name"
Arithmetic:
Rec."Quantity" * Rec."Unit Price"
Conditions (ternary operator — if ... then ... else is not supported in expressions):
Rec."Amount" > 0 ? 'Positive' : 'Negative'
Available Context
Within the expression, you can reference:
- Fields from the current data item (Rec."FieldName")
- System variables
- Functions
Common Functions
| Function | Description | Example |
|---|---|---|
| Round | Round a number | Round(Rec."Amount", 0.01) |
| Abs | Absolute value | Abs(Rec."Quantity") |
| Format | Convert to text | Format(Rec."Amount") |
| Today | Current date | Today() |
| StrSubstNo | String formatting | StrSubstNo('%1 - %2', Rec."No.", Rec."Name") |
Expression Examples
Calculated Amount
Rec."Quantity" * Rec."Unit Price" * (1 - Rec."Line Discount %" / 100)
Concatenated Text
Rec."First Name" + ' ' + Rec."Last Name"
Conditional Value
Rec."Amount" >= 1000 ? 'Large Order' : 'Standard Order'
Percentage Calculation
Rec."Total Amount" <> 0 ?
Round(Rec."Line Amount" / Rec."Total Amount" * 100, 0.01) :
0
Date Difference
Today() - Rec."Order Date"
To get the number of days between two dates, subtract the earlier date from the later one. Days overdue from a due date:
Today() - "Cust. Ledger Entry"."Due Date"
Set the field Type to Integer.
Note the quoting: a data item name containing spaces must itself be in double quotes — "Cust. Ledger Entry"."Due Date", not Cust. Ledger Entry."Due Date".
Formatting a Date That Renders as Date/Time
A Date field placed in a Word layout can render as a Date/Time value with a 0:00:00 time stamp. This is a Word layout quirk.
Workaround: create a Text-type report calculated field that formats the date:
FORMAT(Header.Posting_Date)
Or with a standard format number:
FORMAT(Header.Posting_Date,0,4)
which produces output like 5. April 2021.
Note that these references use the report element / data item name (Header) and the report column name (Posting_Date), which differ from the Rec."Field Name" syntax used elsewhere. Adjust both to match the actual report — the data item may not literally be called "Header".
Microsoft's standard date formats are documented under the FORMAT property in the Business Central developer documentation.
Why You Can't Simply Renumber Line No. Fields
A common request is turning Business Central's internal line numbers into a clean 1, 2, 3 sequence. A naive expression dividing Line No. by 10000 does not work.
Business Central assigns line numbers in increments — 10000, 20000, 30000. When a user inserts a line between two existing lines, BC does not renumber; it picks a value in between. Inserting between 10000 and 20000 gives 15000; inserting again gives 12500; then 11250, 10625, and so on.
Because the values are not evenly spaced, dividing by 10000 yields 1.5, 1.25, 1.12, 1.06 — not 1, 2, 3. (BC can also run out of available numbers between two lines surprisingly quickly.)
And since report calculated fields compute per row and cannot count across rows, a per-row expression cannot produce a true running sequence number by itself. See Limitations.
Data Item Scope
Understanding Scope
Your expression can only reference fields from:
- The selected data item
- Related tables through lookups
Working with Multiple Data Items
If a report has multiple data items (e.g., Header and Lines):
- Create separate calculated fields for each
- Header calculations belong to Header data item
- Line calculations belong to Lines data item
Totals and Summaries
For report totals:
- Use RDLC grouping and sum functions in the layout
- Or create FlowFields on the source table
- Report calculated fields work per-row, not for totals
You cannot total a line calculated field inside a header calculated field. A calculated field defined on a child/line data item — a line total on Purch. Rcpt. Line, say — cannot be summed into a calculated field on the parent/header data item. Referencing it as LineTotalCalc() from a header expression does not aggregate: it evaluates per row and returns only the first line's value. This is confirmed as not possible with current functionality.
Alternative: create a FlowField on the header table that aggregates the line values, then add that FlowField to the report dataset. See Field Settings and Add Fields to Reports.
Publishing and Testing
After Creating Fields
- Publish your extension
- Export the report layout
- Add the calculated field to the layout
- Import the updated layout
- Run the report to test
Verifying Calculations
Test with known data:
- Manually calculate expected values
- Run the report
- Compare results
- Adjust expression if needed
Troubleshooting
Expression Errors
"Field not found"
- Check field name spelling
- Verify field is on the correct data item
- Use exact field name including spaces
"Type mismatch"
- Ensure operation types match
- Use conversion functions if needed
"Invalid syntax"
- Check for missing operators
- Verify string quotes
- Check parentheses matching
Data item name contains spaces
- The data item portion of a field reference must be double-quoted:
"Cust. Ledger Entry"."Due Date" - Without the quotes, Verify Expression fails, and date fields can silently evaluate to a blank date (
0D)
Calculation Wrong
Check:
- Expression logic
- Operator precedence
- Null/zero handling
Field Not in Layout
Check:
- Is extension published?
- Is layout refreshed?
- Is field name correct?
Best Practices
Keep Expressions Simple
- Break complex calculations into steps
- Use readable field names
- Add comments in documentation (not in expression)
Handle Edge Cases
- Check for division by zero
- Handle null values
- Consider negative numbers
Test Thoroughly
- Test with various data scenarios
- Include boundary cases
- Verify with known calculations
Performance Consideration
- Complex expressions run for every row
- Very complex calculations may slow reports
- Consider pre-calculated FlowFields for heavy calculations
Limitations
What Calculated Fields Can't Do
- Access other data items directly
- Aggregate across rows (use layout for this)
- Total a line data item's calculated field from the header data item
- Call complex business logic
- Access tables not in the report
They cannot look up values from a related table
A report calculated field expression can only reference fields from its own data item. It cannot fetch a value from a related table — retrieving a field from the Salesperson/Purchaser table based on the Purchaser Code on a document header, for instance.
The correct approach is a FlowField with Calculation Type = Lookup on the source table, added to the report dataset afterwards. See Field Settings and Add Fields to Reports.
Alternative Approaches
For complex scenarios:
- Use Lookup FlowFields to bring related-table values into the dataset
- Use Sum FlowFields on the header table for line totals
- Create intermediate tables
- Extend the report with custom code