How to generate Level Codes in Revit with PropertyWizard

It’s useful if your Revit Levels have a Level Code as well as a Level Name. That way, you can use the Level Code in your formulas for door numbers, room numbers, etc:

Level NameLevel Code
Level 000
Level 101
Level 202
Level Names and Level Codes

You could type the level codes in, level by level. But if you have PropertyWizard, you can just generate them. This post walks through a couple of different ways of generating the level codes from the level names. And on the way, it explains two of the text functions in PropertyWizard: substr() and strlen().

Method 1: Simple substr()

The substr() function extracts a number of characters from a text value. It has three inputs:

substr(<text value>, <start character>, <number of characters>)

The <text value> is the text you want to extract characters from. In this case it will be the value of the Level’s Name parameter.

The <start character> is the character number to start at, with the first character in the text being number 0. In these level names, the digit is character number 6.

The <number of characters> is how many characters you want to extract. In this simple case, you would use 1 to extract just one digit.

So the substr will look like this:

substr(Name, 6, 1)

Finally, to generate the full level code, you prefix the extracted digit with a “0”:

"0" + substr(Name, 6, 1)
PropetyWizard Formula Window showing simple Level Code formula using substr

Method 2: substr() with strlen()

Method 1 will work for levels up to 9, but will fail with two-digit levels, 10 and up. How can you fix that?

Since the two-digit levels are longer than the one-digit ones, you can use an if() function and a strlen() function to choose between two different options.

The strlen() function simply returns the number of characters in the input text value:

strlen(<text value>)

The if() function chooses between two alternatives. It has three inputs:

if(<test>, <output if true>, <output if false>)

The <test> is an expression that evaluates to true or false. In this case, if the level name is 7 characters long you know that it is a one-digit level. Otherwise it will be a two-digit level:

if(strlen(Name) == 7, <one-digit level>, <two-digit level>)

If it is a one-digit level, you would use the function from Method 1, but if it is a two-digit level, you would just need something like:

substr(Name, 6, 2)

So the completed formula will be something like this:

if(strlen(Name) == 7, "0" + substr(Name, 6, 1), substr(Name, 6, 2))
PropetyWizard Formula Window showing simple Level Code formula using strlen and substr

Creating Revit Parameters to use with Groups and PropertyWizard

If you are creating parameters in projects that have Groups, and you are using PropertyWizard, you should be aware of this setting in the Parameter Properties dialog:

Revit Parameter Properties dialog, highlighting the group settings

What does the setting do? Well, it only has an effect if you’re using groups, and it’s only active for instance parameters. For example, imagine you add a new instance parameter to the Doors category. Each door in your project now has the new parameter, and since it’s an instance parameter you can set the value differently on every door.

But what happens if you create a Group, add a door to it, and then place several instances of the group? Can you still change all the parameter values independently?

That depends on this setting.

Group Settings from Revit Parameter Properties dialog

If you chose the first option ‘Values are aligned per group type’, then the doors will have the same parameter value in all the group instances – and you can only edit the value in Group Edit mode.

On the other hand, if you chose the second option, you can still freely edit the parameter values on each of the doors – you’re not restricted when they are part of a group.

How does this affect your PropertyWizard formulas?

This matters because PropertyWizard cannot enter Group Edit mode to edit parameter values. So if you choose the first option for your parameter, add some of the relevant elements to groups, and then try to drive the parameter with PropertyWizard, you will get a ‘editing while not in group edit mode’ error:

Revit Warning dialog showing a 'Changes to groups are only allowed in group edit mode' error

This error dialog cannot be bypassed or ignored – it only has a Cancel button. So it will stop and undo whatever you are doing. Which can be awkward.

So you have to use the second option ‘Values can vary by group instance’ for all parameters that you want to control with PropertyWizard.

A Few Awkward Types of Parameter

You will notice that the setting is sometimes greyed out, even for some Instance parameters. Why is this?

Well, for some reason Autodesk have chosen to lock the setting to the first option for these values of ‘Type of Parameter’:

Type of Parameter dropdown from the Parameter Properties dialog, highlighting the values that lock the group settings - which are: Integer, Angle, Length, Number, Slope, Yes/No, and Family Type

It is only locked for these few types of parameter in the ‘Common’ discipline, and not for any of the types in the ‘Structural’, ‘HVAC’, ‘Electrical’, etc. disciplines. It is unfortunate that the affected types include some of the most-used types of parameter in PropertyWizard.

How to access Coordinates with PropertyWizard

Coordinates are vital, but Revit does not give you many ways to access them. To show them on sheets, you have the Spot Coordinates tool, but if you want to schedule them you are out of luck.

Fortunately, PropertyWizard makes it easy to access coordinates. This is a quick walkthrough.

Elements in Revit have a Location property in the Revit API. For a normal family that’s placed using a single point, this Location property will contain a LocationPoint object (shown here in Revit Lookup):

The LocationPoint object has a Point property that contains an XYZ, which actually contains the X, Y and Z coordinate values:

So this simple formula will push a text representation of the whole XYZ into the Comments parameter of my elements. In this case, I’m using Structural Foundations, but this would apply to any Category where you have point-placed elements:

And here is a coordinate showing up in the Comments parameter:

Now, these coordinates are in Revit’s Internal coordinate system, not in Shared coordinates. So you need to use PropertyWizard’s internaltoshared() function:

To access the X-component, we just add .X:

Finally, these values are in Revit’s internal units, which are feet, but they are just stored as a number not as a proper length value. You can multiply by 1 ft to convert from a ‘number of feet’ to a proper ‘length’, so that PropertyWizard can format the value using your current Revit Units setting:

Just set up three formulas, one each for X, Y and Z, and you can then schedule the coordinates of all your elements:

And of course, being PropertyWizard, these values are kept up-to-date all the time as you edit your model. There’s no need to remember to run a script to update anything:

Joining texts in PropertyWizard – an alternative function

The third tutorial in PropertyWizard Help shows you how to join text values together using the ‘+’ operator:

PropertyWizard Formula window showing string concatenation formula using the '+' operator
Joining texts with the ‘+’ operator

As an alternative, you can use the strcat() function to join text values. This formula will have the same results as the one above:

PropertyWizard Formula window showing string concatenation formula using the strcat() function
Joining texts with the strcat() function

To use strcat(), you put the text values you want to join inside the parentheses, separated by commas.

Why strcat?

Why would you use one rather than the other? You might find strcat() more readable for large or complex formulas?

Why are there two ways of joining texts? I implemented strcat() very early in the development of PropertyWizard, and it was simpler at that time to create a dedicated ‘string concatenation’ function than to parse out two different meanings for the ‘+’ operator. I added text joining to the ‘+’ operator later, and didn’t remove strcat() in case people were using it. I always try to avoid making changes to PropertyWizard that will break your existing formulas.

How to use the ‘+’ operator in PropertyWizard

The third tutorial in PropertyWizard Help shows you how to join text values together using the ‘+’ operator:

PropertyWizard Formula window showing string concatenation formula
Joining texts with the ‘+’ operator

The ‘+’ operator works differently depending on whether the values either side of it are numeric (numbers, lengths, areas, etc.) or text.

If the values are both numeric

The ‘+’ acts as a plus sign and adds the numbers together.

Of course, the numbers have to have the same units, e.g. both can be Areas, or both can be simple numbers. You cannot add 2 feet to the number 4, for example. Just as with Revit family formulas, if you try to add incompatible values, you will get a ‘Type Mismatch’ error like this:

PropertyWizard Result Check dialog showing a Type Mismatch error
Type Mismatch error

If the values are both text, the ‘+’ joins the texts together.

Note that ‘+’ doesn’t introduce any ‘joining character’ in between the texts, so if you need to introduce spaces or commas you need to type them in the formula.

You can see how in this formula, I’ve included a space after ‘is’ and a space before ‘long’, so that I get a space before and after my wall’s Length value.

"This wall is " + Length + " long."

The old post ‘How to use PropertyWizard for Sheet Numbers‘ has another example of using the ‘+’ operator to join text values together. The BS 1192 numbering it shows is somewhat outdated, but the principle is sound.

If one value is text and the other is numeric

PropertyWizard converts the numeric value to text and then joins the two texts together. I covered how Revit does this numeric-to-text conversion in yesterday’s post.

How PropertyWizard generates text values

The previous post explains how to use the ‘+’ operator to join text values together in PropertyWizard. But it doesn’t explain how PropertyWizard generates text values from the Revit properties that you use in your formulas.

For example, in this formula what determines how the Length value is formatted?

"This wall is " + Length + " long."

The answer depends on whether the Revit property is a parameter or an API property.

Formatting Revit parameter values

Revit parameters know what type of data they represent, which enables PropertyWizard to format the value correctly to match your current Units settings.

So, if you are using Millimetres for length, a six metre long wall will generate this result:

Revit properties box, showing a value formatted in millimetres

While if you are using Feet and Fractional Inches (to the nearest 1/2″), you will get this result:

Revit properties box, showing a value formatted in feet and fractional inches

Note that if you change your Units setting, you need to run PropertyWizard’s Update All command. The Revit API does not have any facility to notify an add-in that the Units settings have changed.

Formatting Revit API values

Revit API values do not know what kind of value they represent, so it isn’t possible for PropertyWizard to format them for you. For example, if you use the Location.Point.X property on the Columns category, you will get results like this:

Revit properties box, showing a raw Revit API value

Which is showing the raw data from the Revit API, the same as is shown by Revit Lookup:

Revit Lookup box, showing raw values for Point data

You will need to use formula expressions to format this raw data to match your current Units settings. I will cover some techniques in a future post, but please comment below if you have specific questions.

Using properties in formulas

The second tutorial in PropertyWizard Help introduces the idea of using element properties in your formulas:

PropertyWizard Formula window showing a formula for the category 'Walls', Target Property is 'Comments' and the Formula text is 'Length'
Formula using Length property

You can refer to:

Properties of the target element – Use the name shown in the Revit Properties window, as in this example. If the name includes spaces or special characters, then you need to wrap it in square brackets like this: [Sheet Name].

Nested properties – Use ‘dot notation’ like Dynamo. For example, the name of a Door’s Level would be Level.Name. There is no limit to the depth of nesting, but all the properties except the last must be Elements or ElementIDs.

API properties of the target element or nested elements – These are the ‘behind the scenes’ properties exposed in the Revit API, which you can find using the Revit Lookup add-in or the Revit API Help. Use the property name, e.g. Location for an element’s Location property.

Project Information properties – Use ProjectInfo.parametername.

Global Parameters – Use GlobalParameter.parametername.

Your first PropertyWizard formula: ‘Hello Wall’

This is a quick exploration based on the first ‘Getting Started’ tutorial from the PropertyWizard Help.

The tutorials are meant to give you a good introduction to PropertyWizard and what it can do for you.

The first tutorial’s formula is straightforward: It collects all the walls in the project and sets their Comments parameter to say ‘Hello Wall’:

PropertyWizard Formula window showing a formula for the category 'Walls', Target Property is 'Comments' and the Formula text is "Hello Wall"
‘Hello Wall’ formula

This is a very simple formula, and you’d never use it in a real Revit project. But we can use it to explore what PropertyWizard brings to Revit.

So, just for comparison, if you needed to set the walls’ Comments to ‘Hello World’ manually, how would you do it?

I’d probably just try selecting all the walls manually and then typing ‘Hello Wall’ into the parameter in the properties window.

But selecting all the walls in a Revit project can be a bit fiddly. You might ‘Isolate Category’ in a 3D view and then window-select all the walls. Or you could select all the rows in a walls schedule. Or maybe you have another add-in that makes selection easier.

But then if you add any more walls in the future you need to remember to set that parameter value. Or regularly select-all-the-walls again to set any that have been missed.

In contrast, PropertyWizard just sits in the background updating any new walls for you as and when they are created.

Model Speed
You might worry that this background work will put a heavy load on Revit and slow your model down. But the Revit API has a very useful facility where an add-in can ask to be notified only when the model is changed in specific ways. So PropertyWizard asks Revit to wake it up when changes are made that affect your formulas, and it spends the rest of the time asleep and having no impact on model speed.

Similarly, if you set a parameter manually it’s very easy for someone to change it. To be sure that all the walls have the right value, you’d have to check them individually, or just select-all-the-walls-again.

In contrast, if you have a PropertyWizard formula it controls the parameter value. If someone tries to change the value, PropertyWizard changes it back. That can be a surprise if people aren’t aware that PropertyWizard is working in their model – you need to keep your team informed – but no-one can accidentally or misguidedly change a value that you’re controlling with a formula.

And finally, if you want to change the value in the future, with the manual method you have to select-all-the-walls again, while with PropertyWizard you can just change the formula and let PropertyWizard update all the walls.

So those are a few differences between setting property values manually and setting them with PropertyWizard. And they start to illustrate the kinds of problems that PropertyWizard is designed to help with:

  1. You want to control a parameter value on a particular category of elements.
  2. You want to be sure the value is set correctly.
  3. You might want to change the value in the future.

In future posts, I’ll explore other formulas in a similar way.

PropertyWizard – New Version 1-6-0

PropertyWizard 1-6-0 is now live on the Autodesk App Store.

Download from here – with free trial

Help file here

This version includes the top user-requested feature: Import and Export formulas. So you can now transfer your carefully-curated formulas from one Revit project to another!

You simply click the new ‘Export’ button in PropertyWizard’s main window, and choose where to save the formula file. Then click the ‘Import’ button to select the formula file and import the formulas when you’re in the other Revit model.

Screenshot of the PropertyWizard Main Window, highlighting the new Import and Export buttons
New Import and Export buttons in V1-6-0

I’ve also added a new function: round(a, b), which rounds the value ‘a’ to ‘b’ decimal places. So this formula calculates the length of walls in metres, rounded to the nearest millimetre:

Screenshot showing a formula using the new round() function in V1-6-0. The formula is 'round(Length/1m,3) + " m"'
New round() function in V1-6-0
Screenshot showing the Revit properties window, with a wall's Length reformatted in metres.
Reformatting lengths into metres

Bugfixes include improving the accuracy of midpoint rounding in the round(a) and round(a, b) functions. Previously, midpoint values like 1234.5 would occasionally be rounded to 1234 rather than 1235. Now, you should always get 1235.

I’ve also changed the trig functions to use radians not degrees so that they interface properly with the Revit API. Sin, cos and tan now expect their input values to be in radians. The inverse functions asin, acos and atan now return radians.