Set Parameters of Family Elements from Central File

Hey all,

Been working for a few days on a python script to edit parameters (namely, text size) within a group of families from the parent file. Ideally I want to pass a list of file paths (or a directory -> contents all) to the node, have it update applicable parameters, save/update these files within the central file, and save the corresponding families back into a specified folder. I’m very close, but getting one error I don’t quite understand.

The full error is Line 60 - attempt to modify the model outside of transaction. I understand this error, but I’m not sure why it’s popping up. In the python code I call out specific lines before and after opening and closing the transaction - for some reason though, it’s only occurring on the families after the first - i.e. the first family updates correctly (and the transaction succeeds, code works exactly as intended) but all of the future families do not update (hence the line 60 error).

Please see screenshot and python code for further clarification. Apologies if my code is a bit blocky/bad… I am new to python and am trying to learn. I pulled bits of code from various places, so big shouts to @erfajo and @Konrad_K_Sobon for paving the way so I can piece together snippets of their code :slight_smile:

import clr
import sys
clr.AddReference("RevitNodes")
clr.AddReference("ProtoGeometry")
import Revit
clr.ImportExtensions(Revit.Elements)

clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

clr.AddReference("RevitAPI")
clr.AddReference("RevitAPIUI")
import Autodesk
from Autodesk.Revit.DB import *
from Autodesk.DesignScript.Geometry import *

import System
from System.Collections.Generic import *

pyt_path = r'C:\Program Files (x86)\IronPython 2.7\Lib'
sys.path.append(pyt_path)

doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application

paths = IN[0]
par_name = IN[1]
par_value = IN[2]

class FamilyOption(IFamilyLoadOptions):
	def OnFamilyFound(self, familyInUse, overwriteParameterValues):
		overwriteParameterValues = True
		return True
		
	def OnSharedFamilyFound(self, sharedFamily, familyInUse, source, overwriteParameterVlaues):
		return True

try:
	errorReport = None
	outValue = []
	textnotes = []
	for i in UnwrapElement(paths):
		if "rfa" in i:
			famdoc = app.OpenDocumentFile(i)
			ownerFamily = famdoc.OwnerFamily
			collector = FilteredElementCollector(famdoc)
			ofType = collector.WhereElementIsElementType().ToElements()
			for j in ofType:
				output = j.LookupParameter("Type Name").AsString()
				if output == "JQ Label" or output == "JQ - Typical" or output == "JQ - Standard":
					textnotes.append(j)
				else:
					output
			for k in textnotes:
				x = k.LookupParameter("Text Size")
				TransactionManager.Instance.EnsureInTransaction(famdoc)
				x.Set(par_value)
				TransactionManager.Instance.TransactionTaskDone()
			outValue.append(famdoc.LoadFamily(doc, FamilyOption()))
except:
	import traceback
	errorReport = traceback.format_exc()
	
if errorReport == None:
	OUT = outValue
else:
	OUT = errorReport

Why don’t you use the nodes available, instead of re-coding?

Try to see the Orchid package.