I am working on a code to be able to utilize Dynamo/Python to push a value to an element that contains a parameter value from a CSV, I have it working for some elements, but I have a set of elements that are nested that end up causing the last section of the code to fail due to them being mapped to the host, so it changes the first element, then it flops for the remainder instead of continuing onto the next item that it can do.
the code in question is lines 145-159
Also I have another section that I dont think is a good workflow but I cannot seem to get to work without doing it this way otherwise it messes up my list numbering. basically I am opening the CSV getting a count of the columns to a variable, then deleting out that parameter and closing the CSV, then opening it again so I can read the content…
Here is the entire code:
#portion of script covering find element containing parameter value taken from MEPover FilterStringEquals node.
import clr
import sys
pyPath = r"C:\Program Files (x86)\IronPython 2.7\Lib"
sys.path.append(pyPath)
import os
import System
import System.Collections
#Access to Revit Document
clr.AddReference("RevitServices")
import RevitServices
#To Get Doc, UI and Application Objects
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument
uidoc = DocumentManager.Instance.CurrentUIDocument
app = DocumentManager.Instance.CurrentUIApplication.Application
#Needed to make any changes in Revit
from RevitServices.Transactions import TransactionManager
clr.AddReference("RevitNodes")
import StringIO
from System.IO import FileInfo
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
import Autodesk
from Autodesk.Revit.DB import *;
clr.AddReference("RevitAPIUI")
from Autodesk.Revit.UI import *
from System.Collections.Generic import List
import csv
from System.IO import FileInfo
#Get CSV Path, Param Row Letter, ParamVal Column Number
filePath = IN[0]
paramName = IN[1].lower()
pNToInt = ord(paramName)-97#lowecase a starts at 97 in ASCII
paramValCell = int(IN[2])-1#subtract 1 to normalize numbers (Revit lists start with 0 not 1)
#get CSV Info
with open(filePath) as csvCountFile:
delReader = csv.reader(csvCountFile, delimiter=',')
columns = len(next(delReader))-1
del delReader
csvCountFile.close()
csvData = []
with open(filePath) as csvFile:
csvReader = csv.reader(csvFile, delimiter=',')
for row in csvReader:
csvData.append(row)
#find Elements with Value from CSV
search = csvData[pNToInt][0]
string = csvData[paramValCell][pNToInt]
case = IN[3]
bips = System.Enum.GetValues(BuiltInParameter)
bm = doc.ParameterBindings
bmlist = bm.ForwardIterator()
paramId = None
testout = []
while bmlist.MoveNext():
binddef = bmlist.Key
testout.append(binddef.Name)
if binddef.Name == search:
paramId = binddef.Id
break
param = None
if paramId == None:
biplist = []
for bip in bips:
try:
name = LabelUtils.GetLabelFor(bip)
except:
continue
if name == search:
biplist.append(bip)
sharedparamrule = SharedParameterApplicableRule(search)
evaluator = FilterStringEquals()
parameter = None
if paramId == None and len(biplist) == 0:
coll = FilteredElementCollector(doc)
sharedparams = coll.OfClass(ParameterElement)
for param in sharedparams:
name = param.GetDefinition().Name
if name == search:
parameter = param
if parameter != None:
ruleslist = List[FilterRule]()
provider = ParameterValueProvider(parameter.Id)
filterrule = FilterStringRule(provider, evaluator, string, case)
ruleslist.Add(filterrule)
ruleslist.Add(sharedparamrule)
paramFilter = ElementParameterFilter(ruleslist)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
elif paramId == None:
filterList = List[ElementFilter]()
for param in biplist:
provider = ParameterValueProvider(ElementId(param))
filterrule = FilterStringRule(provider, evaluator, string, case)
paramFilter = ElementParameterFilter(filterrule)
filterList.Add(paramFilter)
orFilter = LogicalOrFilter(filterList)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(orFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(orFilter)
collector2.UnionWith(collector)
else:
ruleslist = List[FilterRule]()
provider = ParameterValueProvider(paramId)
filterrule = FilterStringRule(provider, evaluator, string, case)
ruleslist.Add(filterrule)
ruleslist.Add(sharedparamrule)
paramFilter = ElementParameterFilter(ruleslist)
collector = FilteredElementCollector(doc)
collector.OfClass(FamilyInstance).WherePasses(paramFilter)
collector2 = FilteredElementCollector(doc)
collector2.OfClass(HostObject).WherePasses(paramFilter)
collector2.UnionWith(collector)
if parameter == None and paramId == None and len(biplist) == 0:
OUT = "Does not work with non-shared family parameters"
else:
elements = collector2.ToElements()
elemsChanged = []
TransactionManager.Instance.EnsureInTransaction(doc)
try:
for e in elements:
i = 0
while i < columns:
param = csvData[0][i]
val = csvData[paramValCell][i]
e.LookupParameter(param).Set(val)
i += 1
elemsChanged.Add(e)
except:
OUT = "Try Again"
TransactionManager.Instance.TransactionTaskDone()
OUT = paramValCell, param, val, search, string, elemsChanged, elements
MM - Python - WIP Set Parameters if value contained in CSV.dyn (13.4 KB)