Formulas and expressions
Calculate a value, set a condition, format a date or a number, in a Formula field or in a template.
In a template text or in a Formula field, everything between braces is calculated; the rest is printed as is.
Lot {reference}-{serial} → Lot AX-100-000042
Names are written in English, whatever the language; messages and help follow the interface language.
The essentials
- A name on its own prints a value: a field (
{reference}) or a ceelab element ({date},{copy},{language}…). - A function is written with its parentheses:
{upper(reference)}. - A condition is written
if … then … else …, always with itselse:{if quantity > 100 then "Pallet" else "Box"}. - A text is written between straight quotes:
"Box". A number is written with a point:1.2. - To print a brace, double it:
{{and}}.
The Formula field


A Formula field calculates its value from the other fields of the type, even those placed further down. The editor shows the result on the sample values, what the formula uses and what it is used by, and the list of fields and ceelab elements to insert.
On saving, ceelab checks everything: typos, unknown names, impossible or circular calculations. The part at fault is underlined, and Fix is offered when the correction is obvious.
At print time, a formula that fails stops everything without using up a number. Results are kept in the history: a reprint gives back exactly the same document.
The expression editor
In the Formula field as in the lab:
- the text is color-coded: fields, functions, texts, numbers, with unknown names highlighted;
- Ctrl+Space, or typing a name, suggests the fields of the type with their label and sample value, the ceelab elements, the functions and the words expected at that point; typing “poi” suggests
weightif its label is “Poids”; - ↑ ↓ to choose, Enter or Tab to insert, Esc to close;
- inside a function, the help shows what to write at that point, such as the date formats;
- hovering over a name gives its label, its kind and its sample value; Functions and elements opens the help for the whole language.
Examples
Sample type “Product label”, French document dated 7 October 2026: product “Vis inox M4”, reference “AX-100”, quantity 150, packaging “Carton”, serial number 42 (6-digit counter), manufactured the same day.
| Need | Expression | Result |
|---|---|---|
| Packaging by quantity | {if quantity > 100 then "Pallet" else "Box"} |
Pallet |
| Quantity and packaging | {quantity} · {packaging} |
150 · Carton |
| Serial number on 8 digits | N° {pad(serial, 8)} |
N° 00000042 |
| Parcel n of N, only if there are several | {if copies > 1 then "Colis " + text(copy) + "/" + text(copies) else ""} |
3rd copy of 12: Colis 3/12 |
| Date in each language’s format | {format_date(manufacturing_date, "short")} |
07/10/2026 (en Oct 7, 2026, de 07.10.2026) |
| Wording by language | {if language == "de" then "Mindestens haltbar bis" else if language == "en" then "Best before" else "À consommer de préférence avant"} |
À consommer de préférence avant |
| Best-before month and year | {format_date(add_days(manufacturing_date, 365), "mm/yyyy")} |
10/2027 |
| Month in words | {format_date(manufacturing_date, "mmmm yyyy")} |
octobre 2026 (de Oktober 2026) |
| Dated batch code | L{format_date(date, "yymmdd")}-{pad(serial, 4)} |
L261007-0042 |
| Reference prefix | {upper(left(reference, 3))} |
AX- |
With added fields: weight (Number, entered as “12,50”), price (Number, “0.1”), fragile (Yes/No, unchecked), lot (optional Text, empty), expiry (optional Date, empty).
| Need | Expression | Result |
|---|---|---|
| Weight as entered | Net {weight} kg |
Net 12,50 kg |
| Weight class | {if weight > 30 then "Heavy" else if weight > 10 then "Medium" else "Light"} |
Medium |
| Increased weight, 2 decimals at most | {round(weight * 1.2, 2)} |
15 |
| Always 2 decimals | {decimals(weight * 1.2, 2)} |
15,00 |
| Total | {decimals(price * quantity, 2)} € |
15,00 € |
| Unit weight (a division is always rounded) | {decimals(weight / quantity, 3)} kg |
0,083 kg |
| Notice from a Yes/No | {if fragile then "FRAGILE" else ""} |
(nothing) |
| Optional line | {if lot == "" then "" else "Lot " + lot} |
(nothing) |
| Optional date | {if expiry == empty then "" else "À utiliser avant le " + format_date(expiry, "dd/mm/yyyy")} |
(nothing) |
Calculations are exact and the decimal separator follows the document language: decimals(total, 2) writes 37,50 in French.
Reading data from ceelab
lookup reads a piece of information known to ceelab. For example, the name of a document type from its key:
{lookup("document_types", "key", "shipping-label", "name")}
If the information does not exist, nothing is printed and ceelab lets you know.
Common mistakes
| Written | Should be |
|---|---|
{if quantity = 100 then …} |
== to compare |
{reference | upper} or {reference.upper()} |
upper(reference) |
{"Lot " + quantity} |
"Lot " + text(quantity) |
{"Lot " & lot} |
+ to join texts |
{if weight > 30 then "Heavy"} |
add else …: an expression always has a value |
{if weight > 30 alors "a" sinon "b"} |
then and else, in English |
{quantity > 100} |
a condition is not printed: if quantity > 100 then "Oui" else "Non" |
{total / 3} |
round it: round(total / 3, 2) |
{round(12,5)} |
12.5 |
{0 < weight < 10} |
0 < weight and weight < 10 |
{format_date(date, "jj/mm/aaaa")} |
dd/mm/yyyy |
{“Box”} |
straight quotes: "Box" |
in looks for a piece of text: "E" is “in” "FR BE CH". For a list of values, write country == "FR" or country == "BE" or country == "CH".
Quick reference
- Words:
if then else and or not in true false empty. - Operators:
+ - * /(+also joins two texts);== != < <= > >=;in(contained text);and,or,not. - Functions:
upper,lower,left,right,replace,number,text,round,decimals,pad,format_date,add_days,lookup. - Elements:
date,date_long,date_iso,time,year,month,day,copy,copies,document_type,location, and in expressions onlylanguage(document language),app_language(interface language of the computer),label_printeranddocument_printer(printers set). - Date patterns:
yyyy,yy,mmmm,mm,dd; formatsshort,long,iso. - Empty:
x == empty; an empty value cannot be calculated.
Dates: what cannot be written yet
- Day without a leading zero (“7 octobre 2026”):
format_date(date, "long")writes it in each language. - Text inside a pattern:
"dd de mmmm"is refused; build it withformat_date(date, "dd") + " de " + format_date(date, "mmmm"). - Month in a language other than the document’s: not possible yet; use a condition on
month, or a second document type in the other language.