Hi,
A quite unique workflow is required where I need to extract element information from multiple different documents.
This is the current method mass opening document is using Orchid:
Instance information works perfectly. However, when I try and extract any type of information it returns nulls/errors:
From some googling, the extraction of parameter information uses the current document as a field. As the instance parameter information is stored within the element, not the family/type, they work. This is not the case for the type information as its needs to know what Document to look at the type.
I can see two ways of solving this:
- Tell the script to work with one document at a time
- When extracting type data, tell what document to extract from. There is an Orchid node that does this for Family data but not per document.
Currently, I’ve failed to get both working. Any ideas/tips would be greatly appreciated.
Many thanks
Joe
Hi Joe,
How about posting on the Orchid github for an enhancement?
A 3rd option would be to use Python to extract the information, but that will probably be a bit of work. I think there might be some Clockwork nodes which would give you example code.
Hope that helps,
Mark
2 Likes
This would be the way I’d go, as you can open, extract, and close each file subsequently. This means you don’t have N files open concurrently sucking RAM from the system.
2 Likes
Hey Mark and @jacob.small
Thanks both for the suggestion. How complicated would that python script be? I’ve only really used python for data management, I’m wondering if it would be within my ability.
Joe
1 Like
Hi Joe,
If you’re happy in Python I don’t think it wouldn’t be too bad.
The problem with parameters is they can take varying types… String, Double, Yes/No, Parameter etc. etc. so you need a cascade of statements to test each parameter and return the value if successful…
I tend to start these things by grabbing some code from a node which is similar and tweak it in your active document, then when it works, adjust it to iterate through the list of documents you’re feeding it.
I’d quickly strip out some RVT files for testing, otherwise the task time taken will mainly be you opening and shutting Revit files 
Hope that helps,
Mark
2 Likes
To @Mark.Ackerley’s point, the complexity of this task will vary depending on scope and consistency of the ask. The parameter storage type is just one of a few complications, each of which will reveal itself in time as your workflow scales up.
For now look to learn how to open a .rvt file (model path utilities class will help here), and close the .rvt file. I haven’t tested this, but something like it may be a good place to start:
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import * #this should be reduced to just what you need
app = DocumentManager.Instance.CurrentUIApplication.Applicaton #gets the current application
##### note that I am not declaring the 'doc' variable as you usually might in the boilerplate code, this means you can loop over the files and get the content as needed #####
listofPaths = IN[0]
paramName = IN[1]
paramVals = []
for path in listofPaths: #iterates over the list of files in the listofPaths variable - make sure you have a list there or this will have some issues
mp = ModelPathUtils.ConvertUserVisiblePathToModelPath (path) #converts the path from what we undertsasnd to what Revit understands
doc = app.OpenDocumentFile(mp) #opens the document
wallCat = BuiltInCategory.OST_Walls #needed something to help collect stuff, looked like you were doing wall things, so I figured I'd use the wall category in the FEC
fec = FilteredElementCollector(doc).Ofcategory(wallCat).WhereElementIsElementType().ToElements() #gets all the wall category types as elements so we can get info from them
for e in fec: #for every item in the list of #for every wall type found
paramVals.append(e.GetParameters(paramName).AsString()) #appends the value as a string to the paramVals list
doc.Close(False) #closes the document
OUT = paramVals #returns the paramVals list to the Dynamo environment
Haven’t tested this, just typed it up so sorry in advance for any typos.
2 Likes
Sorry for the late response @jacob.small, I was off on holiday.
Thanks you for the above, I really appreciate it. I’ve never had to work with this kind of code so was quite a learning experience.
I couldnt get the code working straight away, most notable I found disabling the ModelPathUtils and adding the .Application to line 17 and not 8 worked for some reason. Not sure if I fixed something or just broke it in a way that didnt produce errors in the below set-up:
Unfortunately I couldnt get the code to Run with the below error occuring:

I see that error as .AsString can’t operate as its been given a List not a Parameter. Which to me doesnt make sense as its a method or reading a single parameter.
Even so, I attempted to Loop through paramVals as it seemed to be a list:
for path in listofPaths: #iterates over the list of files in the listofPaths variable - make sure you have a list there or this will have some issues
#mp = ModelPathUtils.ConvertUserVisiblePathToModelPath(path) #Not sure if needed, doesnt seem to work when enabled
#test.append(mp)
doc = app.Application.OpenDocumentFile(path) #opens the document
ceilingCat = BuiltInCategory.OST_Ceilings #Test Category
fec = FilteredElementCollector(doc).OfCategory(ceilingCat).WhereElementIsElementType().ToElements()#gets all the ceiling category types as elements so we can get info from them
for e in fec: #for every item in the list of #for every wall type found
paramVals.append(e.GetParameters(paramName))
for parameterList in paramVals:
for Parameter in parameterList:
test.append(Parameter.AsString())
#paramVals.append(e.GetParameters(paramName)) #appends the value as a string to the paramVals list
doc.Close(False) #closes the document
This just bought me this error instead:

I’ve tried different methods of calling and reading parameters Values such as .GetOrderedParameters with not luck, but the the errors are consistant.
I’m not too sure if this my bad coding or something funny is going on with what I’m trying to do. I’m going to try and stick with it but if anyone has any ideas please let me know.
Thanks again for the starter code Jacob!
Joe
Can’t see what one 29 is, but try restarting the CPU. Because the file is open after the previous error you may be getting a hang up on the open.
1 Like
Thanks for replying, I gave it a restart and no luck.
I end up getting it working with the below code. I think the problem was the way I was looping through the list. Thanks again for the help
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *
app = DocumentManager.Instance.CurrentUIApplication
listofPaths = IN[0]
paramVals = []
for path in listofPaths: #Interates over paths
doc = app.Application.OpenDocumentFile(path) #Opens Document
ceilingCat = BuiltInCategory.OST_Ceilings #Cat to Open
fec = FilteredElementCollector(doc).OfCategory(ceilingCat).WhereElementIsElementType().ToElements() #Select All Elements
for e in fec: #Interates over elements
for p in e.GetOrderedParameters(): #Iterates over parameters
paramVals.append(p.AsString()) #Appends as string
doc.Close(False) #Closes Document
OUT = paramVals