Schedules to Excel and Excel to Revit using Dynamo

Hello everyone,
I’ve exported the schedules to excel. Now I’d like to modify some parameter in Excel and import these to Revit.
I tryed but it does not work.
Somebody knows how?

There are heaps of topics concerning exactly this on the Forum, please have a search and see if it can’t solve your issue.
You might start here:

I’ve already seen that video but it is not working for me…

It looks like you need to think about what your nodes are doing.

Remember that if a node is light grey, it requires more inputs. (Set Parameter Node)

The reason you might be struggling there is because you do not know which elements to change. Currently you’re trying to change schedule values, but you need to remember schedules are just representations of other object’s information. ( You’re trying to modify a set of Material’s ‘Comments’ Parameter.)

You need to select your materials as the elements. You have their names. Perhaps there is a node that will let you select materials from having their names!

Ok I did it but I have a problem.
If I change the parameters in the Excel file Revit assign just the first number (overlined in yellow) at all the materials. Someone can help?





4

I would start off with something simple, then work up from there.

In addition to the previous comments, the main issue is that you need to use something (such as the material ID) to match up the records when importing it back in. You can’t rely on the data being in the same order- which would occur if someone added an extra material, or changed the wall materials around.

For instance, I would start off by exporting the following data:
The graph to import it will probably be a little more complex

I tryed to do it but it still not work


Something wrong?

It looks to me you are trying to write a string value (costo : 10) to a parameter that requires a value. You should try to filter the value from your sheet. And try to show the warning you’re receiving from the set parameter node.


I did it but it have the same problem (it copy the first value to all materials)

Try using list levels, right now you’re choosing the 2nd list (which contain your five 1’s). If you use list levels you could get e.g. all values on the 2nd location in each list.

EDIT:

Firstly you should be careful both reading and writing to the same sheet of excel in the same graph… This can cause issues for large data-sets…
Also what changed from your previous post, where it didn’t assign the same values?

Thank you it works.

How shall i do? What do you think?

The previous post was to ask how to do the whole alghoritm but now I can do it…

Thank you

I would probably have one graph for writing the data and one for reading and assigning data back.

But if it is to be kept in one graph then I would use a codeblock for delaying the data from being read until you are sure that it have been written, the codeblock content could be:

{waitfor,pass}[1]

waitfor is the data that is waited upon, and pass is the data that is passed once both data values have been received.

That’s exactly what I did for my own internal workflow. I previously used BIMLink to accomplish the same thing, but I found it a little tedious to make new links every time I opened a new model, so I instead opted to write a custom Python script to do the same thing. Also, being purely Python-based, it might not apply directly to OP, but other users might find it helpful.


#IMPORTS
import clr
clr.AddReference(“RevitAPI”)
clr.AddReference(“RevitServices”)
clr.AddReference(“RevitNodes”)
import Revit
clr.ImportExtensions(Revit.Elements)
import Autodesk
import RevitServices
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

#Categories to be queried
categories = IN[0]
newData = IN[1]
paramNames = newData[0][1:]
elementsFull =

#Set document to current Revit document
doc = DocumentManager.Instance.CurrentDBDocument
for category in categories:
collector = FilteredElementCollector(doc)
elementsFull.extend(collector.OfCategory(category).ToElements())
#Convert into incoming data into a dictionary
dictUpdate = dict()
for i in range(len(newData)):
line = newData[i]
guidUpdate = line[0]
params = line[1:]
dictUpdate[guidUpdate] = params

“”"
Example key-value pair:
{‘08f706f3-b9d0-4867-95a0-67696ac56ede’:[VAL1, VAL2, FLOOR1, NEW CONSTRUCTION, C1010.10]}
“”"

TransactionManager.Instance.EnsureInTransaction(doc) #Begin Revit document transaction

#Loop through all elements and get their relevant properties
for element in elementsFull:
#Get guid of current element
guid = element.UniqueId
try:
paramsUpdate = dictUpdate[guid] #Retrieves parameter values associated with a GUID
except:
pass
else:
for i in range(len(params)):
try:
param = paramNames[i] #Current parameter in loop
paramValUpdate = paramsUpdate[i] #Parameter value to be updated
paramRevit = element.LookupParameter(param) #Associated Revit parameter, by name
except:
pass
else:
try:
paramRevit.Set(paramValUpdate)
except AttributeError:
pass
TransactionManager.Instance.TransactionTaskDone() #End Revit document transaction


My variable naming could probably be cleaner, but the script itself is fully functional.

It expects two inputs: IN[0] = categories and IN[1] = data to be pushed back into Revit. The script expects IN[1] to have an element’s GUID in the leftmost column and the first row to contain headers corresponding to the parameter’s exact name. Additionally, this is for an itemized schedule, but it could easily be modified to be used with a non-itemized schedule as long as all of the associated GUIDs are still included for each line.

I’m currently using the LookupParameter() method to get the element’s parameter by name. Since I only use this to push and pull custom parameters which don’t share any names with other project parameters, this is fine, but I would caution using this with generic parameters such as “Length” or any other name which might be present for multiple parameters.

1 Like