A guide for anyone typing an expression into Simplebim. No programming needed — if you have written a formula in Excel, this will feel familiar. The differences from Excel are collected in If you know Excel, and they are worth reading before you start.
Contents
- What an expression does
- Referring to a property
- Writing values
- Separating arguments — always use
; - Operators
- Functions
- How each property type behaves
- Empty and missing values
- Text comparison is case-sensitive
- Recipes
- If you know Excel
- Things that do not work
- Troubleshooting
What an expression does
An expression is evaluated once for every object. Each object gets its own answer, because the properties in the expression are read from that object.
There are two ways an expression is used, and they expect different kinds of answer:
| Use | The expression must produce | Example |
|---|---|---|
| Calculating a property value | any value — a number, a text, a date, a yes/no | [Height] / 1000 |
| Selecting or filtering objects | true or false | [Height] > 3000 |
When an expression is used to select objects, only the objects whose answer is true are picked. An answer of 1, or of a non-empty text, does not count — the answer has to be genuinely true/false:
[Height] > 3000 selects the tall ones [Load Bearing] selects the load bearing ones — a yes/no property is already true/false [Name] selects nothing at all — a name is text, not true/false [Name] = "Basic Wall" this is what you meant
The last pair is the common mistake: to select on a text property you have to compare it with something.
Referring to a property
Put the property name in square brackets:
[Name] [Load Bearing] [Gross Floor Area]
A few conveniences:
-
Capitalisation of the property name does not matter.
[name],[Name]and[NAME]all find the same property. -
Extra spaces just inside the brackets are ignored.
[ Name ]is the same as[Name]. - Spaces inside the name are part of the name, so
[Load Bearing]needs its space.
Asking for a different unit
If the property is a measurement, you can ask for it in the unit you want by adding the unit symbol in curly brackets inside the square brackets:
[Length {m}] the length in metres
[Gross Floor Area {m2}]This is the safest way to work with units, because you know exactly which unit the number is in. Without it, you get the property in whatever unit the model is using.
If the unit symbol is not one Simplebim recognises, it is quietly ignored and you get the unconverted value. Check your result if you are unsure.
Writing values
Numbers
12 3.5 -40
Write the decimal point as a dot. A comma between two digits also works (3,5), so keyboards and habits from comma-decimal countries are fine — but see the warning under Separating arguments, because commas and decimals can collide badly.
Text
Text goes in double quotes:
"Basic Wall" "Concrete" "" empty text
To put a double quote inside text, put a backslash in front of it:
"a \" inside the text"
This is one of the places Simplebim differs from Excel. Excel doubles the quote (
"") — that does not work here and will make the expression fail. Use\".
Yes and no
TRUE FALSE
Capitalisation does not matter — True, true and TRUE are all fine. TRUE() and FALSE() with empty brackets also work, if you prefer the Excel spelling.
Dates
A date property is a real date, so it compares and sorts like one. There are three ways to write a date, and the one you pick decides whether the expression means the same thing on somebody else's computer.
1. The DATE function — always safe
[Created] = DATE(2024; 3; 4) year; month; day [Created] > DATE(2023; 12; 31)
2. An ISO date in quotes — also safe
YYYY-MM-DD, year first, with dashes. This is read the same way on every computer:
[Created] = "2024-03-04" [Created] > "2023-12-31" [Stamp] > "2024-03-04 13:45:00" with a time, when the property has one
3. A date the way you normally write it — convenient, but only for your own use
[Created] = "4.3.2024" read using your Windows date settings
⚠ This one is not portable. A date written this way is read using your computer's Windows regional settings. On a computer set up differently,
04/03/2024may be read as 4 March instead of 3 April. The expression will not report an error — it will simply select different objects. If the expression will be shared, or saved into a template that others use, stick toDATE(...)or the ISO form.
Dates compare properly in every direction, including across a year boundary:
[Created] > "2023-12-31" true for any date in 2024 [Created] >= DATE(2024; 1; 1) [Created] < TODAY()
And you can pull a date apart:
YEAR([Created]) = 2024 MONTH([Created]) = 3 HOUR([Stamp]) >= 12 for a property that has a time
Separating arguments — always use ;
When a function takes more than one argument, separate the arguments with a semicolon:
IF([Height] > 3000; "tall"; "short") ROUND([Area]; 2) MAX([Width]; [Height])
A comma also separates arguments, but do not use it. Here is why:
IF([Height] > 1,5,6)
You probably meant "if height is greater than 1.5, then 5, else 6". But the two commas are ambiguous — the first one is read as a decimal point and the second as an argument separator, so this becomes IF([Height] > 1.5, 6), which is a different formula with a missing argument. With semicolons there is no ambiguity:
IF([Height] > 1,5; 5; 6) clear: compare with 1.5, then 5, else 6 IF([Height] > 1.5; 5; 6) clearer still
Rule of thumb: semicolons between arguments, dots for decimals. Then nothing can go wrong.
Semicolons and dots inside quoted text are left completely alone, so [Name] = "Wall;Type" and [Code] = "1.5" behave exactly as you would expect.
Operators
| Operator | Meaning | Example |
|---|---|---|
= |
equal to | [Name] = "Basic Wall" |
<> |
not equal to | [Material] <> "Concrete" |
> >=
|
greater than, greater or equal | [Height] >= 3000 |
< <=
|
less than, less or equal | [Area] < 10 |
+ - * /
|
add, subtract, multiply, divide | [Width] * [Height] |
^ |
to the power of |
[Side] ^ 2 — but see the warning below |
& |
join two texts together | [Type] & " - " & [Name] |
& happily joins a number to a text: [Height] & " mm" gives 3000 mm.
Careful with
^after a plain number.2^3fails, because the^3is mistaken for a unit attached to the2. Put the number in brackets:(2)^3works. After a property this is not a problem —[Side]^2is fine.
There is no AND or OR written between two things. [A] = 1 AND [B] = 2 does not work. Use the functions instead — see below.
Functions
Function names are not case-sensitive: IF, If and if all work.
Logic
| Function | What it does | Example |
|---|---|---|
IF(test; then; else) |
Chooses between two answers | IF([Height] > 3000; "tall"; "short") |
AND(a; b; ...) |
True when all are true | AND([Height] > 2000; [Load Bearing] = 1) |
OR(a; b; ...) |
True when any is true | OR([Type] = "A"; [Type] = "B") |
NOT(a) |
Reverses true and false | NOT([Load Bearing] = 1) |
IFERROR(a; fallback) |
Uses the fallback if a fails |
IFERROR([Area] / [Count]; 0) |
ISBLANK(a) |
True when the text is empty | ISBLANK([Comment]) |
ISNUMBER(a) / ISTEXT(a)
|
Tests the kind of value | ISNUMBER(SEARCH("wall"; [Name])) |
The else in IF may be left out — IF([Height] > 1; "yes") is accepted.
Text
| Function | What it does | Example |
|---|---|---|
LEN(t) |
Number of characters | LEN([Name]) |
UPPER(t) / LOWER(t)
|
Change capitalisation | UPPER([Name]) |
LEFT(t; n) / RIGHT(t; n)
|
First / last n characters |
LEFT([Code]; 3) |
MID(t; start; n) |
n characters from position start (starts at 1) |
MID([Code]; 4; 2) |
FIND(needle; haystack) |
Position of text, case-sensitive; fails if not found | FIND("Wall"; [Name]) |
SEARCH(needle; haystack) |
Position of text, ignores capitalisation; fails if not found | SEARCH("wall"; [Name]) |
REPLACE(t; start; n; new) |
Replaces n characters |
REPLACE([Name]; 1; 5; "Fancy") |
TRIM(t) |
Removes surrounding spaces | TRIM([Name]) |
CONCATENATE(a; b; ...) |
Joins texts (same as &) |
CONCATENATE([Type]; " "; [Name]) |
TEXT(number; format) |
Formats a number as text |
TEXT([Area]; "0.00") — see the warning below |
VALUE(t) |
Reads a number out of text | VALUE([Code]) |
TEXTcannot be used on text that looks like a date.TEXT("03/04/2024"; "yyyy")is refused with an error, and so isTEXT([Some Text Property]; ...)when that property happens to hold something like2024-03-04.TEXTalso cannot reformat a real date — it ignores the format you give it. To get at the parts of a date useYEAR,MONTHandDAYinstead.
Numbers
| Function | What it does |
|---|---|
ROUND(n; digits) |
Round to a number of decimals |
ROUNDUP(n; digits) / ROUNDDOWN(n; digits)
|
Round up / down |
INT(n) / TRUNC(n)
|
Drop the decimals |
CEILING(n; step) / FLOOR(n; step)
|
Round to a step |
ABS(n) |
Remove the minus sign |
MOD(a; b) |
Remainder of a division |
SQRT(n) / POWER(a; b)
|
Square root / power |
MAX(...) / MIN(...)
|
Largest / smallest |
SUM(...) / COUNT(...) / AVERAGE(...)
|
Total / count / average of the listed values |
Dates
| Function | What it does |
|---|---|
DATE(year; month; day) |
Builds a date |
DATEVALUE("2024-03-04") |
Turns an ISO date in quotes into a date |
TIMEVALUE("13:45:00") |
Turns a time in quotes into a time |
YEAR(d) / MONTH(d) / DAY(d)
|
The parts of a date |
HOUR(d) / MINUTE(d) / SECOND(d)
|
The parts of a time |
TODAY() / NOW()
|
Today's date / the current date and time |
The function library is the Excel-style one, and there are more functions than are listed here. A function name that does not exist simply makes the expression fail, so try it and see.
How each property type behaves
This is what a property turns into when the expression is worked out. It explains why some comparisons look the way they do.
| Property type | Becomes | So you compare it like this |
|---|---|---|
| Text | the text | [Name] = "Basic Wall" |
| Number, measurement | the number, converted to the unit you asked for | [Height] > 3000 |
| Yes/no |
1 or 0
|
[Load Bearing] = 1 — or = TRUE, which also works |
| Date | a real date |
[Created] > DATE(2023; 12; 31) or [Created] = "2024-03-04"
|
| Date and time | a real date and time | as above; HOUR, MINUTE, SECOND also work |
| Time of day | a real time | HOUR([Shift Start]) >= 12 |
| Empty text |
empty text ""
|
[Comment] = "" |
Note the yes/no row. Because the value arrives as 1 or 0, comparing it with the text "TRUE" never matches:
[Load Bearing] = "TRUE" never true — this compares with the word TRUE [Load Bearing] = TRUE correct [Load Bearing] = 1 correct [Load Bearing] correct on its own, it is already a yes/no
Empty and missing values
This is the single most common surprise, so it gets its own section.
If a property has no value on an object — or the object does not have that property at all — the object drops out of the result entirely. It does not come back as false, or as zero, or as an error you can catch with IFERROR. The object is simply not there.
IF([Width] > 1; "wide"; "narrow")
Objects with no Width get no answer at all — not "narrow". If you are filtering, they are not selected; if you are calculating a property, they get no value.
There is one exception:
-
Empty text is a real value. A text property with nothing in it becomes
"", and you can test it:[Comment] = "",LEN([Comment]) = 0orISBLANK([Comment])all work, and the object stays in the result.
For numbers, dates and yes/no properties there is no way to test for emptiness inside an expression — the object is gone before your test runs. To find the objects that are missing a value, select the ones that have it and invert the selection in the user interface.
Text comparison is case-sensitive
[Name] = "Basic Wall" true for "Basic Wall" [Name] = "BASIC WALL" FALSE for "Basic Wall"
This is different from Excel, and it catches people out constantly. If you want to ignore capitalisation, force both sides to the same case:
UPPER([Name]) = "BASIC WALL" LOWER([Name]) = "basic wall"
(Property names in brackets are a separate matter — those are always matched ignoring capitalisation. It is only the comparison of text values that is strict.)
Recipes
Exact match, ignoring capitalisation
UPPER([Name]) = "BASIC WALL"
Contains some text — SEARCH ignores capitalisation, and ISNUMBER turns "not found" into a clean false instead of a failure:
ISNUMBER(SEARCH("wall"; [Name]))Does not contain some text
NOT(ISNUMBER(SEARCH("wall"; [Name])))Starts with / ends with
LEFT([Name]; 5) = "Basic" RIGHT([Name]; 4) = "Wall"
Two conditions at once
AND([Height] > 2000; [Load Bearing] = 1)
One of several values
OR([Type] = "A"; [Type] = "B"; [Type] = "C")
Convert millimetres to metres
[Height] / 1000
...or better, let Simplebim do it and avoid the arithmetic altogether:
[Height {m}]Classify into bands
IF([Height] < 2000; "low"; IF([Height] < 3000; "medium"; "high"))
Build a label
[Type] & " - " & [Name]
Round to two decimals
ROUND([Gross Floor Area {m2}]; 2)Guard against dividing by zero
IFERROR([Area] / [Count]; 0)
Objects created before 2020
[Created] < DATE(2020; 1; 1)
Objects created in a given year
YEAR([Created]) = 2024
Objects created between two dates
AND([Created] >= "2024-01-01"; [Created] <= "2024-06-30")
Objects created in the last 30 days
[Created] > TODAY() - 30
If you know Excel
Most of what you know carries over. These are the differences that will bite you:
| Excel | Simplebim | |
|---|---|---|
| Argument separator |
, (or ; depending on locale) |
always ;
|
| Comparing text | ignores capitalisation |
case-sensitive — use UPPER() on both sides |
| Quote inside text | "" |
\" |
AND / OR
|
functions | functions only — no A AND B between two things |
| Referring to a value | cell address A1
|
property name [Name]
|
| Yes/no values |
TRUE / FALSE
|
TRUE/FALSE work, and so does 1/0
|
| Empty cells | can be tested with ISBLANK
|
the object disappears instead (except for text) |
| Dates | typed into a cell |
DATE(2024;3;4) or "2024-03-04"; other forms depend on your Windows settings |
TEXT on a date |
reformats it | refused on date-like text, ignores the format on a real date |
2^3 |
works | fails — write (2)^3
|
Things that do not work
Verified traps, so you do not have to discover them yourself:
| You might write | What happens | Write instead |
|---|---|---|
2^3 |
fails | (2)^3 |
1e5 |
fails | 100000 |
12 m2 |
fails |
12, and put the unit on the property: [Area {m2}]
|
10 xyz |
silently becomes 10
|
drop the unknown unit |
"a""b" |
fails | "a\"b" |
[A] = 1 AND [B] = 2 |
fails | AND([A] = 1; [B] = 2) |
IF([H] > 1,5,6) |
wrong formula, silently | IF([H] > 1.5; 5; 6) |
EXACT(a; b) |
not available |
UPPER(a) = UPPER(b), or = for case-sensitive |
SUBSTITUTE(...) |
not available | REPLACE(...) |
PROPER(...) |
not available |
UPPER / LOWER
|
TEXT("03/04/2024"; "yyyy") |
refused with an error |
YEAR(...), MONTH(...), DAY(...)
|
[Created] = "03/04/2024" |
depends on your Windows settings |
[Created] = "2024-03-04" or DATE(2024;3;4)
|
Troubleshooting
Some objects are missing from my result. They are almost certainly missing a value for one of the properties you used. See Empty and missing values. Try the expression with just one property at a time to find which one.
My text comparison never matches. Check the capitalisation — comparison is case-sensitive. Wrap both sides in UPPER(). Also check for stray spaces in the data: TRIM([Name]) = "Basic Wall".
My yes/no filter never matches. You are probably comparing with "TRUE" in quotes. Drop the quotes, or compare with 1.
The whole expression fails. Work through these in order:
- Are all the arguments separated with
;? - Is every
[matched by a], and every"matched by another"? - Is there a bare number followed by
^or by letters? Put the number in brackets. - Is the property name spelled correctly? Capitalisation does not matter, but the spelling and the spaces do.
- Does the function exist? Check the Functions tables.
My date filter picks the wrong objects, or works for me but not for a colleague. You have probably written the date the way you normally write it, for example 4.3.2024, which is read using your Windows regional settings. Use "2024-03-04" or DATE(2024; 3; 4) instead — those mean the same date on every computer.
My number came out in the wrong unit. Ask for the unit explicitly: [Length {m}] rather than [Length].
The result is a number where I wanted true/false. IF(...; 1; 0) gives a number. For selecting objects you want true/false — either compare something ([Height] > 3000) or use IF(...; TRUE; FALSE).
Related to
Comments
0 comments
Please sign in to leave a comment.