T06: Format Strings
Control how every value displays, and use the three-section pattern to turn a numeric measure into Pass or Fail.
What you will build: correct formats across your model, and a status widget that displays Pass or Fail from a numeric measure.
Time: about 20 minutes.
You need: T05 completed.
Step 1 — See the problem#
Find a measure with no format set and look at it on a chart or table. You will see full floating-point precision — something like 3.4179999828338623.
That is what an unset format looks like, and it appears everywhere the measure does: charts, tables, widgets, forms, reports, notifications.
Step 2 — The formats you will actually use#
Infohub passes the format string straight to .NET's number formatting, so the whole standard specification is available.
Set these on your existing measures:
| Measure | Format | Renders 1234.567 as |
|---|---|---|
Steam Flow Hourly |
0.0 |
1234.6 |
Steam Flow Daily |
0.0 |
1234.6 |
Water Used Daily |
#,##0 |
1,235 |
Bottles Daily |
#,##0 |
1,235 |
Energy per 1000 Bottles |
0.00 |
1234.57 |
Production vs Target Daily |
0.0 '%' |
1234.6 % |
Step 3 — 0 and # are different#
This is the distinction that matters for tables.
0forces a digit.0.00renders5as5.00.#omits it when not needed.#.##renders5as5.
Put 0.0 and #.# on two measures and look at them side by side in a table. The 0.0 column has aligned decimal points and can be scanned down; the #.# column is ragged.
Prefer 0 for operational reporting. Use # only where a trailing zero would actively mislead.
Step 4 — The percentage trap#
Try 0.0% on Production vs Target Daily.
It displays something like 9420.0%.
% multiplies by 100. In a .NET format string, % is not decoration — it scales the number. Your measure holds 94.2 meaning 94.2%, so % makes it 9420.
Two consistent options:
- Store the percentage (
94.2) and format with a quoted literal:0.0 '%' - Store the ratio (
0.942) and format with0.0%
Pick one convention for the whole model. Mixing them is a reliable source of wrong dashboards.
Set it back to 0.0 '%'.
Step 5 — The three-section pattern#
A format string can carry three sections separated by semicolons:
positive ; negative ; zero
Ordinary use, accounting style with a dash for zero:
#,##0.0;(#,##0.0);—
1234.5 renders 1,234.5, -1234.5 renders (1,234.5), and 0 renders as an em dash so empty table cells do not clutter.
Step 6 — Now the useful trick#
Because a section can be a quoted literal, a numeric measure can display as text.
Create a quality check. In your Quality folder, add a calculated measure:
| Field | Value |
|---|---|
| Name | Brix In Spec |
| Retrieval type | Calculated |
| Interval | Day(s) — or Shift(s) |
| Unit | ratio |
| Dependencies | Brix |
Expression — returns 1 if in specification, 0 if not:
(Measure_<brixId>.Value ?? 0) >= 10.5 && (Measure_<brixId>.Value ?? 0) <= 12.5 ? 1 : 0
Now set the format to:
'Pass';'Fail';'Fail'
Put it on a Widget. It displays Pass or Fail — no enumeration, no special chart type, no extra configuration.
Add a limit to the measure so the widget also colours itself green or red, and you have a complete status indicator built from a calculation, a format string, and a limit.
Other useful variants:
| Format | Positive | Negative | Zero |
|---|---|---|---|
'Running';'Fault';'Stopped' |
Running | Fault | Stopped |
'Yes';'No';'No' |
Yes | No | No |
'Above';'Below';'On target' |
Above | Below | On target |
Step 7 — Variance with a sign#
For a measure that can go either way, show the sign explicitly.
Add a variance calculation in Efficiency:
| Field | Value |
|---|---|
| Name | Production Variance Daily |
| Interval | Day(s) |
| Unit | bottles |
| Format | +#,##0;-#,##0;0 |
(Measure_<bottlesDailyId>.Value ?? 0) - (Measure_<targetDailyId>.Value ?? 0)
It renders +12,500, -12,500, or 0. On a variance column that is much clearer than relying on the reader to spot a minus sign.
Step 8 — Scaling in the format#
A trailing comma divides by a thousand:
| Format | 1234567 renders as |
|---|---|
#,##0 |
1,234,567 |
#,##0, |
1,235 |
#,##0,, |
1 |
Useful for large numbers on a small widget — and dangerous.
If you scale, change the unit. Displaying kWh divided by a thousand while the measure is still labelled kWh is exactly how a report ends up wrong by three orders of magnitude. If you scale in the format, say so in the unit: MWh, or kWh (thousands).
Step 9 — Test the awkward cases#
For each format you have set, check five values rather than one:
- A normal value.
- Zero.
- A negative value, if the measure can go negative.
- A very large value — does the separator appear where you expect?
- A very small value — does it round to zero and look broken?
Formats are cheap to change and easy to get subtly wrong. Thirty seconds of checking is worth it.
What you have learned#
Formats are .NET format strings. The whole specification is available.
0 forces digits, # omits them. Use 0 for aligned columns.
% multiplies by 100. Use 0.0 '%' for a value already in percent.
Three sections give you positive, negative, and zero — and a quoted literal turns a number into a word.
A trailing comma scales by a thousand. Change the unit if you use it.
Formatting belongs on the measure, not in the expression. A calculation must return a double?; formatting there breaks the contract and defeats the measure's own format.
Try this before moving on#
Audit your whole model's formats. Every measure should have one, and the set should be internally consistent — the same quantity formatted the same way everywhere.
While you are there, check the units too. Infohub stores the unit as free text and validates nothing, so m3 and m³, or t and ton, are different strings to every grouping you will ever run. Pick one spelling per quantity and hold to it.
Next: T07: Event Schemes — capturing what was happening, not just what the value was.