image by rhshackelford

sheets from excel with dynamo

image by rhshackelford

In this post I will present a quick workflow for getting new sheets into Revit using an Excel spreadsheet. You will ask me: Why in the world would you do that? My answer is that sometimes you have a consultant on a project that works exclusively in AutoCAD (yeah that evil sucker still exists), and you somehow need to get their drawings to show up on a drawing list. In order to do that you need to create placeholder sheets or real sheets if you actually want to assign some properties to them (like I do). So the idea is to get all of these sheets created in less than 10min instead of hours of manual labor (I have been there), and if they send you a new Excel spreadsheet with updated list, get only the new ones in and skip all that already exist. Let’s start with getting the excel into Dynamo:

1. Import an Excel Spreadsheet into Dynamo and extract only two columns of information (sheet number and name):

Once we have  our Excel data parsed we need to determine if sheets already exist in the model or not. I am using a custom Python node for that because when I first wrote it removing white space characters from strings was not available. I think this can be done using Dynamo standard nodes in version 0.7.1. Anyways, here’s the code that will compare sheet numbers from Excel with those already in project to determine if sheets need to be added:

The output of this node will be two lists. One will contain only sheet numbers for new sheets and another only sheet names. Next step is to use that information to create sheets. In order to create them we will need one more piece of information: a Titleblock Type ElementId. Simply use Family Types and ElementId nodes to obtain that:

Now, this part was not mandatory to create the sheet. All we need for a new sheet is really just an Active Document and a Titleblock Type Id (then we assign them Number and Name but Revit will automatically assign a Number on creation and Name as “Unnamed” so technically you only need Document and Id), but I also wanted to make sure that my new sheets get sorted and filtered properly in my Drawing List so I decided to set a few parameters while I was on it. Again this part could be done later using Dynamo nodes, but I figured I will wrap it all up in one transaction which probably makes it faster (not entirely sure). Here it is:

And here’s a Python code for the last custom node:

Again, that last part can be done in Dynamo without use of Python and i will be more than happy to demonstrate that one day, it’s just that today I am posting how I have been using it for a while so its proven to work.

Good luck! Use it if you like but please give credit where credit us due.

Here’s a preview on YouTube:

Here’s code mentioned below in the comments that takes only input of names and numbers for the sheets. Please use the View Raw button in the bottom right corner to see the raw code (best for copy/paste):


  1. Junghwo Park says:

    Thanks for your hard work and it is very useful to work out Dynamo.. Keep it up and help us!

  2. Junghwo Park says:

    Hi Konard,

    Thanks for your post. I have been trying to follow your script and Dynamo definition… Unfortuntately, I have some difficulty when it comes to Pyton script node. I have copied your script from the website into script editor… but it is not working. I could send you an email with my workout files.. Otherwise, it will be great to get sample files from you for this topic.
    I look forward to hearing from you as soon as practical.
    Thank you very much.

    Best wishes
    Junghwo Park,

    • Konrad says:

      Junghwo, you can email me your files, but I am not sure where/if i will have time to look at them. Please describe your problem in more detail as well. I will try to help you as time permits.

  3. Dmitry Dronov says:

    I have the same problem with python script.
    line 47
    it is very strange. because it is comment line…

    • Konrad says:

      You submitted a file to me that is in Russian. I do not speak that language nor can I read it. I am guessing that the problem is the same as it was in Junghwo’s case. This script tries to set three parameters that are not built into every Revit template, they were added to the project by me: drawing list filter, drawing list group etc. Before you can run this definition make sure that you have added them to the project, your sheets and set them to be instance parameters.
      Of course I recommend that you just create sheets with a name and number instead. That will be a lot easier i hope. Just delete all of the code pertaining to those three parameters. It should look like the image that I have attached. With that you will only need to input TitleBlock Id, sheet names and numbers.
      Good luck!

      Attachment:  Capture.jpg

  4. ThomK says:

    Greetings Konrad,

    Thank you very much for this code and setup. This is my first try at using Dynamo.

    I attempted to use the items provided to create a series of sheets from an Excel file using only numbers and names and no additional parameters.

    Everything appears to work well until the last custom Python script. Here, I get a warning dialog with the following:

    Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
    File “”, line 42
    #create new sheet

    SyntaxError: expected an indented block

    I’ve attempted to update the script so only the Sheet Number and Sheet Name parameters are being used.

    The only lines I’ve edited are as follows:
    40 sheets = []
    41 for i, j in zip(sheetNames, sheetNumbers):
    42 #create new sheet
    43 newSheet = ViewSheet.Create(doc, titleBlockTypeId[0])

    The files I’m using are in the following Dropbox:

    Any insight you can provide would be much appreciated.

    Thank you!

    -Thom K.

    • From the warning message I can tell you that line 42 has to be indented. Just tab it or hit space 4 times. In python when you start a new function like you are doing in “for i, j in zip(sheetNames, sheetNumbers):” the following line – or everything that happens inside of that function – has to be indented. That’s why “newSheet = ViewSheet.Create(doc, titleBlockTypeId[0])” has to be one “tab” in.

      Good luck!

      • ThomK says:

        Greetings again,

        Thank you for the rapid response. I apologize for bugging you about this. I’ve indented both of the lines at 42 and now get the following:

        Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
        Traceback (most recent call last):
        File “”, line 43, in
        TypeError: ‘int’ object is unsubscriptable

        40 sheets = []
        41 for i, j in zip(sheetNames, sheetNumbers):
        42 #create new sheet
        43 newSheet = ViewSheet.Create(doc, titleBlockTypeId[0])
        44 #set sheet name param
        45 bipName = BuiltInParameter.SHEET_NAME
        46 sheetName = newSheet.get_Parameter(bipName)
        47 sheetName.Set(i)
        48 #set sheet number param
        49 bipNumber = BuiltInParameter.SHEET_NUMBER
        50 sheetNumber = newSheet.get_Parameter(bipNumber)
        51 sheetNumber.Set(j)
        52 #collect all newly created sheets
        53 sheets.append(newSheet)
        54 # “End” the transaction
        55 TransactionManager.Instance.TransactionTaskDone()

        Your response indicates indenting all of the lines inside the function, would that mean just lines 42 & 43 or would that mean lines 42-55 would all have a single, leading indent?

        Looking at things closer: The version of Dynamo that I’m using and does not appear to have the ElementId function that you have in your example. I’ve used the Element.Id in mine. The output from your example shows a list with something that looks like “[0] 414394”. From Element.Id, I only have an ‘int’ output and it’s reporting just a number “11829.000”.

        Once again, pardon my ignorance, I’m just trying to piece these things together.

        Thank you again,

        -Thom K.

  5. ThomK,

    You are correct on both accounts. Everything inside of that “for i, j in …” has to be indented. I didn’t notice but indentation for that particular code went away when i hosted it on Github, i fixed that now. Also, if you install Archi-lab package from the Package Manager you will get the “Element Ids” node that outputs ElementId (Revit object) and not the standard Dynamo node that as you noticed outputs an Integer. This is causing some problems usually, so I will have to build in a check/convert into this code to avoid that in the future (you are not the first person having the same problem). I hope this gets you going. Also, if you are only creating sheets by Name and Number and not setting any parameters this should get you going:

    Good luck!

    • ThomK says:

      Your advice definitely helped me. Looking at the code you provided, it appears to pretty much match my hack-job edits.

      Thank you again, I’m up-and-running!

      -Thom K.

  6. Mamay says:

    Konrad thank you, problem solved

  7. Jamie says:

    Hi Konrad,
    I am pretty new to Dynamo, but following your videos have picked it really quickly. I am trying to improve my python scripting and used this sheet creator as a good way to learn.

    I have followed all your tips above, but I would like to know how I get extra parameters into the sheets. In our titleblocks we have some custom parameters,, say for Revisions and other bespoke things, how can I get Python to grab these from my excel too?

    I have the nodes nicely set up, so the revisions are formatting into a list nicely, but not outputting. This is my script portion (the rest is the same as yours above) Within Dynamo I am referring to it as Revision, and our shared parameter in the titleblock is called AB_Revision. All help gratefully received!

    dataEnteringNode = IN

    titleBlockTypeId = IN[0]
    sheetNumbers = IN[1]
    sheetNames = IN[2]
    revision = IN[3]

    # “Start” the transaction

    sheets = []
    for i, j, k in zip(sheetNames, sheetNumbers, revision):
    #create new sheet
    newSheet = ViewSheet.Create(doc, titleBlockTypeId[0])
    #set sheet name param
    bipName = BuiltInParameter.SHEET_NAME
    sheetName = newSheet.get_Parameter(bipName)
    #set sheet number param
    bipNumber = BuiltInParameter.SHEET_NUMBER
    sheetNumber = newSheet.get_Parameter(bipNumber)
    #set sheet revision
    AB_Revision = newSheet.get_Parameter
    #collect all newly created sheets

    # “End” the transaction

  8. Chris Hildebran says:

    Konrad, my first experience building this Dynamo process has been fun!

    Though I am running into a hurdle in that i clicked on a button to update Dynamo to version 0.8.0 which as you might guess caused some problems.

    I surmounted a few hurdles during the rebuilding process which was easy but now i have a problem at the second Python Script stage.

    This is where im lost.

    Perhaps you’ve already encountered this problem.

    If and when you have a moment can you take a look and comment on my .dyn file (attached in RAR file)?

    • Chris Hildebran says:

      Screenshot of Warning.

      • Chris,

        It looks like your input into the titleblock type id variable is an integer instead of a list. You can either change the line that I highlighted to titleBlockTypeId simply getting rid of [0] or make it a list with a single item on it. Also, i am seeing that you are feeding it an integer which will not work. Please use archi-lab element id node and use Revit Element Id output. You will need a real Revit Element Id object and not just an integer representation of it. Good luck!

  9. Francisco says:

    Hi Konrad,

    I have tried yours but the issue I have is right at the beginning: “Warning: One or more of the input types are not matching, please check that the right variable types are being passed to the inputs. Couldn’t find a version of ReadFromFile that takes arguments of type (string,string).”

    I just can’t get pass this because there is no other option for reading the excel file. Again, I have downloaded archi-lab, lunchbox, steamnodes, clockwork, etc… I have also tried it in Dynamo 0.7.5 with exact same results.

    What am I missing here? This is very frustrating!! I can’t get Dynamo to do anything useful in any version… Please find attached my file, and would love to know what is going wrong.


    • Your first input should be a FilePath and then File.ReadFromFile. I can’t see what is exactly not working but the error states that you are supplying a tuple of strings.

  10. Dongyeop says:

    Hi Konrad,

    Thank you for posting great stuff on your website, and I find it’s very helpful to understand how you use Dynamo in real world situations.
    While I follow your Dynamo script on this post, I can’t make your python node work in the beginning.
    As you can see in the attached file, I get empty lists from the first python node.
    Sheet numbers in my Revit project are named like this, “A-100, A-110,…”.
    Does it have to do with the format of sheet names or something else?
    I know you’re very busy, but I hope I can get some answers from anyone looking at this post.
    Thank you.


    Attachment:  CreatSheet.jpg

  11. Luke says:

    Everything seems right, this is the message I get, have I missed something?

    Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
    Traceback (most recent call last):
    File “”, line 43, in
    TypeError: expected ElementId, got int

    Attachment:  Capture.png

    • Yes, an ElementId is expected and not an integer. So the OOTB Dynamo node returns an integer instead of ElementId. Use archi-lab package node that returns an ElementId as well as integer and it should work.
      Also, if you want placeholder sheets see attached.

  12. Kasper says:

    Hi Konrad,

    You might have heard about this problem a bilion times. But I’ve been through all the comments and tried all the different solutions and it still does not work.

    I don’t know if it is the imported family type or the Python – everything else seems to work fine.

    Python warning:
    Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
    Traceback (most recent call last):
    File “”, line 41, in
    AttributeError: ‘ElementId’ object has no attribute ‘split’


  13. Kasper S. says:

    Hi Konrad

    I’ve tried everything now but i still have no idea why the script does not Work.
    It simply shows null in the end Watch and nothing happens in Revit. Am I choosing a wrong Family type(Title block) or revit file?

    Best regards Kasper

    • Kasper, can you post exactly what your steps are and what code you are using? I can’t help you from just reading the error message. I mean the error is clear. You are asking Python to execute a Split() method on ElementId object and that doesn’t work. Unfortunately I have no idea where, and why you would be doing this. Either post screen shots and i will try to answer your questions (not always possible), or post a file (zip) with troubling definition and i will have a look at my own convenience. Thanks!

  14. stuntedpig says:

    I am trying to create new sheet list with dynamo and add the ‘Series’ parameter but it hasn’t worked.
    I have attached this file. Could you please review and advise me what have been missed in this dynamo file.
    Many Thanks,

  15. Derek W. says:

    Was looking to create a new sheet list similar to Jamie above that has extra parameters but could not get the Python script to work. I followed the extra instructions from the attached response .jpeg but did not succeed. Any suggestions.

    Attachment:  dk2.jpg

  16. Derek W. says:

    Took another shot at trying to figure out how you would add a ‘sheet specific’ parameter that is driven by a third excel column (for my case a Discipline Type parameter). Like many my Python knowledge is lacking but going through these examples have definitely helped.

    I’m assuming that the parameter needs to go through your first python script similar to the excelSheetNumber and excelSheetName. Sorry if this is a novice question but how do I define the third parameter ‘Sheet Discipline’.

    #The inputs to this node will be stored as a list in the IN variable.
    dataEnteringNode = IN

    excelSheetNumber = IN[0]
    excelSheetName = IN[1]
    excelSheetDiscipline = IN[2]

    #get all sheets in the project and their numbers
    collector = FilteredElementCollector(doc)
    sheets = collector.OfCategory(BuiltInCategory.OST_Sheets)
    projectSheetNum = []
    for i in sheets:
    bipNumber = BuiltInParameter.SHEET_NUMBER
    tempSheetNum = i.get_Parameter(bipNumber).AsString()

    #compare excel sheets to project sheets and pass only new sheets
    newNumber, newName = [], [], []
    for i, j, k in zip(excelSheetNumber, excelSheetName, excelSheetDiscipline):
    if “”.join(i.split()) in projectSheetNum:

    #Assign your output to the OUT variable
    OUT = newNumber, newName, newDiscipline.append(k)

  17. Sephlyn Marcano says:

    Craziest thing! I was able to get this script to work previouly and it created sheets and I was able to use our company’s Browser Organization parameters. The script that skips the additional parameters works, however it will be great to get this to work with sorting sheets correctly in the Project Browser. When it worked, I was using Revit 2014 at the time, we have now migrated to Revit 2016 and I have the latest Dynamo update 9.0. Now this script is not working… I am a Dynamo newbie, please explain and possibly help resolve the warning in the last Python script Line 59

    Warning: IronPythonEvaluator.EvaluateIronPythonScript operation failed.
    Traceback (most recent call last):
    File “”, line 59, in
    TypeError: expected Guid, got str

    Also note that once the script manually runs, it creates one sheet and refuses to cycle through until I manually run the script again.

Leave a Comment