Taking a Return Trip From Revit to Excel Using Dynamo

Last week I wrote about using note block schedules to create specification sheets and I explained how you can use addins such as BIMLink, custom macros or C# addins or Dynamo to get the data out to Excel so that it can be edited by an engineer and then re-imported to Revit from Excel.

Problem is, you don’t have a BIMLink licence, you don’t know how to code in C#, the most accessible method for you to achieve this workflow is Dynamo but you don’t even know where to start; never fear! In this post I explain how to create a bi-directional link between Revit and Excel using Dynamo using the as the note blocks from my previous post as an example.

I’ll be using Dynamo 0.80 which can be found on the Dynamo BIM download page.

Exporting from Revit to Excel

The export to Excel process is pretty simple, you just need to think about the logical steps that you need to take. You want to select the family you wish to export data from, select the parameters to export, organise them in a list and then write it to the Excel file itself.

To step through the process, first select the family type and push that into an All Elements of Family Type node.



From there we start our first step in taking care of the family unique identifier by using the Element.UniqueId node, this will export the family’s GUID. Simply link the All Elements of Family Type node to this one. You need to export each individual family’s unique identifier as well, if you don’t, as the BIM Troublemaker discovered you may end up importing the wrong data to the wrong family.

Next, you need to select each of the parameters you want to export, for this you need to use the Element.GetParameterValueByName node. Link the All Elements of Family Type node through to this node and you will also need to add a String node which is where you input the name of the parameter. Because I’m using the annotation family from my note block post, the parameters that I will be exporting are NUMBER, NOTE, CATEGORY and REGION. Note that the value that you enter into the string is case sensitive and that you need to repeat this for each parameter you are wanting to export.


Now you need to push the output of each of our Element.GetParameterValueByName nodes through to the List.Create node. This will actually create a list that will run the parameters across the page with each parameter being spread across a row instead of being arranged in columns. If you exported the data to Excel at this point, you would end up with something that looks like this:



However this isn’t how we want to work, we like our data arranged in columns. To do this, use the List.Transpose node which swaps the rows and columns in the created list.


To finish off we need to use the Excel.WriteToFile node in which we pass through a File Path node, a String which names the Excel sheet and a few Numbers which gives the starting row and column of our excel sheet.

The result is a nice, easy to read export of all the data relevant to our note block schedules ready to be modified by an engineer.



At this point you can use the Sort function in Excel to sort your Excel file into a usable list. In this instance I have chosen to sort by Column D and then Column B so that I am sorting first by category and then by note number.


Importing back into Revit from Excel

Once the engineer has finished modifying the Excel sheet, we’re ready to bring the data back into Revit from Excel. This process is slightly more cumbersome but overall not a whole lot more difficult than the export process.


First we need to pick up our Excel file, start with the File Path node that we used before, before we go to the Excel.ReadFromFile node though we need to pass the file path through the File.FromPath node otherwise it will not work. We also need to add a String so we can tell Dynamo which sheet to read. Next, pass the data back through the List.Transpose node to get the data back into a format that Dynamo and Revit are happy to work with.



Remember earlier I mentioned during the export process that to make sure we’re writing the correct information to the correct family we need to index our list and the families by their GUID? Thanks to the BIM Troublemaker, we know how to select each element from our Excel file based on the GUID. First, start with a List.GetItemAtIndex node and connect the List.Transpose node to it. Next, add a Code Block node and enter the text 0; this passes through the number 0 as our row index. Finally, add a Code Block node and insert the code  ElementSelector.ByUniqueId(id, true); this is case sensitive, so make sure that you enter it correctly or it will not work!



Finally, we need to push the data through to each parameter for each individual family. To do this, use an Element.SetParameterByName node. We need to feed the ElementSelector Code Block that we created into our node, along with a String node that matches our parameter name, remember this value is case sensitive and finally we need to link up our value via a List.GetItemAtIndex node.

The List.GetItemAtIndex node needs to be told which row to use to pull it’s data from, this is as simple as adding a Number node. Don’t forget though that the first row is at index 0, which is where we are pulling our GUID from, so we want to pull our first series of parameters from the row which is at index 1.

In this instance our index 1 is our number list which you may not need to import this so you could skip this step, but if you do need to populate the number data and you try to feed the parameter from the List.GetItemAtIndex node directly to the Element.SetParameterByName node Revit will throw back an error stating that “The parameter storage type is not a number”. Originally I tried to overcome this by using the node String from Object but this gives a number to 3 decimal places and we don’t want to see this on our specification sheet. The solution in this instance was to first use the Math.RoundDownToPrecision node from the Clockwork package which you can download from within Dynamo itself or from We need to pass a number to the Math.RoundDownToPrecision node to indicate the precision we want, which in this case we want a precision of 1.

The number conversion is the only oddball of the parameters that we’re working with, the rest of the parameters simlpy feed the List.GetItemAtIndex node directly to the Element.SetParameterByName node. Repeat for each parameter that you want to populate.



And to finish up, our results:


Using Note Blocks for Project Specifications

Quite a while ago I was looking for a solution for specification drawings, they crop up from time to time on small jobs when a separate specification document isn’t required.

The problem with these specification drawings though is that the content of the text usually started life in AutoCAD, then it’s imported and roughly tidied up in Revit, it’s usually copied and pasted from one job to the next and you end up with text that is cumbersome to modify and information irrelevant to the current project.

The answer to the problem is note blocks, in my opinion a brilliantly clean solution. The annotations can be placed neatly on a drafting view, the content of the annotations is then scheduled and you end up with a series of schedules that are easily arranged on your specification sheets. Modifying can be as simple as the modeler editing the text within the annotations or  the content can be exported using BIMLink, Dynamo, custom C# macros or addins ready to be modified by the engineer and re-imported to Revit.

I was working at another company when I put together a demonstration project, did a short presentation on how it works and was flat out told “No. This solution is too difficult for the average user.” And that was the end of that. We continued trundling on with cumbersome, incorrect and generally backward methods of creating and maintaining specification drawings.

I briefly mentioned this method for specification sheets in a Reddit post and I was asked how this works, so with that glimmer of hope that someone might find it useful, this is how you go about it.

First, start with a generic annotation. This is simply for display on your drafting view and of course to hold the data in for your schedules. Mine simply looks like this


Each of these labels are a simple instance family parameter.


The parameters I used were

  • Number – Used to order the notes
  • Note – The note itself
  • Category – This is used for each heading in the specification sheet. For example in hydraulics this could be Stormwater, Hot & Cold Water, Drainage etc. or for electrical it could be Lighting, Power, Lightning Protection etc.
  • Blank Spacer Left and Right – These are to give a cleaner look to the note blocks on the sheet, they’re personal preference only.
  • Region – I had to deal with region specific notes both within Australia and also internationally.

Once you have the family loaded into a project, create a drafting view to arrange your annotation symbols. Mine looked like so



I manually typed in the headers that you can see just for my own reference, the headers aren’t required though as all the required information for scheduling is contained within the families themselves.

The next step is to create the schedule itself. If you’re not aware, the note blocks can be found under the schedule drop down on the ribbon.



You will then be prompted to select the annotation that you want to schedule.


From there, select all the parameters associated with the annotation that you need for your schedule.



Filter out the annotations you need for this particular block of notes, in this instance I am working with hydraulics acoustic notes for Queensland.



Sort by the number, formatting and appearance is obviously up to you and your documentation standards.



Rinse and repeat for your remaining categories. My project ended up looking like so


It takes a little bit of time to setup, but once you’re done future modification is simple and if you don’t need to modify the notes, even better! If you’re worried about template clutter, the schedules don’t need to live in your base template either, they can be located in a separate *.RVT file where all the standard notes and schedules are kept and can then be imported to the project as required.

The result is a clean, easy to organise specification sheet. If you don’t want a particular section, it’s quick to remove and re-align the remaining parts. If you don’t want a certain note to show up, you can filter it out by changing the number to xx or delete it from your drafting view. Engineers can confidently take responsibility for what is on their drawings without worrying about typos, misreading of hand markups or information hanging over from previous projects.


And finally, you can see here how the blank left and right parameters affect the schedule. As mentioned previously these are entirely optional, I just liked the resulting layout of the notes.


To get you started, you can download my example annotation family here

Creating Pipework Drop/Rise Hexagons

If you’re located in Australia or New Zealand, chances are you use these lovely hexagons or some other variation of them to annotate pipework dropping or rising.


But how do you create them in Revit? It’s quite simple actually. For this example I’ll assume you have not created an annotation family before and therefore is aimed at beginners.

First, start by creating a new annotation symbol using the generic annotation template.


In the Family Category and Parameters dialogue, change the family type to a Pipe Tag


You can either draw up the hexagon manually or you can temporarily insert a DWG file to trace over the top of. Once you’re done, you should have your trusty hexagon sorted.


To add the text to your symbol, you want to use labels. You can find the label tool on the create panel of the ribbon.


When creating the labels, you will need to select the parameters that you want to pull the data from in your model – we will be using Diameter and System Abbreviation. The reason why I use System Abbreviation is that it will automatically propagate to all pipework in the system where as other parameters do not. Don’t forget to adjust the text style of the label to suit your drafting standards.


The next step is to apply a visibility setting on the filled drop and rise indicators. Simply select the triangle and and in the properties window, look for the Visible parameter. Select the small square at the end of the line (marked at 1), you will now have an option to select parameters to apply, yours should be empty.

Select Add Parameter and then create a new parameter with the name RISE. Make it a Type parameter and sort it under Graphics.

Repeat the process for the drop indicator.



Finally open up the Family Types dialogue


Create a new family type called RISE and then check the RISE parameter and make sure that DROP is unchecked. Do the same again creating a family type named DROP and check the DROP parameter, making sure that RISE is unchecked.

If you want to get tricky, you could use a not( ) formula. Simply type in the forumula


in the drop parameter. When RISE is checked, drop will be unchecked and when RISE is unchecked, DROP will be automatically checked.


And that’s it! Once you’re done, save your new family and add it to your template.

When tagging your pipework, you need to manually select if it is a dropper or riser by selecting the family type from the properties window, the size and the service however will be automatically filled out for you.

For the System Abbreviation parameter to be picked up, you will need to have this filled out in your pipe system settings for each service, note that it is simply listed as Abbreviation in the system settings.


If you don’t use systems (you should be using them!) and rather you use pipe types to define your service, the System Abbreviation parameter will not work and you can use a shared parameter instead to populate the label within the annotation.

Clean 2D Pipe Fitting Symbols

One of the gripes that a lot of hydraulic engineers and modellers have with Revit is the representation of pipework bends in 2D views. It’s something that I fixed up pretty early on, but I’ve come to realise when I come across drawings that look similar to the screenshot below that some may still not know how to fix this.


I’d a quick fix per fitting, the problem will be if you have a lot of fittings to modify, it becomes a long repetitive process.

The first thing that you want to do is to edit the family, and switch to the Ref. Level view, you will be greeted by something that looks like this:



In this instance I am modifying the out of the box Revit family Elbow – Soldered – CU.rfa. If you’re  little overwhelmed by what you see on the screen, don’t worry; we’re not touching any of the dimensions or 3D elements. If you need to, you can adjust the scale of the view to change the size of the dimensions, or you can completely turn off the dimensions in Visibility/Graphics (VV / VG shorcuts).

2014-11-25_14-02-40What we are wanting to change is the 2D representation of the fitting, which are model likes of the pipe fitting subcategory. In the screenshot below, I’ve highlighted them in red with the dimensions turn off for clarity.



When modifying the pipe fittings, I like to keep the original linework in the family as a just in case. I usually change the linework to the <Invisible Lines> subcategory or turn the visibility off, you can however remove them if you wish.


To achieve the clean 2D representation that you’re used to, we’re going to create some new linework along with a reference line to control the angle.

First up, find the intersection of the Front/Back and Left/Right reference planes, from the intersection, draw a model line using the Pipe Fitting subcategory on a 45 degree angle (1) and then create an angular dimension between the Front/Back reference plane and your newly created reference line (2)



When you start drawing your line from the intersection of the two reference planes, Revit will automatically lock your line to the intersection point, this is also the point the the fitting is scaled around.

Next, apply the angle parameter to your dimension, the line will snap around to the same direction as the fitting.


You now need to align and lock the endpoint of your line to the reference plane for the outside edge of the fitting.


Now draw the other half of your fitting symbol. You don’t need to apply an angle in this case, just draw the line from the intersection of the Front/Back and Left/Right reference planes to the outer edge of the fitting. Don’t forget to align and lock the line to the outer reference plane.

Once you’re done, flex your fitting within the family editor, changing the diameter and angle. Make sure everything works as expected.



Now load your fitting back into your model or template and check out the difference


For the tee fitting, there is no need to recreate the symbology from scratch, all you really need to do is to remove the ticks by either making them invisible, or changing them to the <Invisible Lines> subcategory.