Python error: document currently modifiable, but not after copy/pasting node

I am trying to set the material-parameter of a freeform object inside a famdoc to “ByCategory” programmatically, using Python API code inside a Dynamo script.

image

I am using this code:

# Enable Python support and load DesignScript library
import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)

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

clr.AddReference("System")
from System.Collections.Generic import *

#get the current document & application
doc = DocumentManager.Instance.CurrentDBDocument
app = DocumentManager.Instance.CurrentUIApplication.Application

class FamilyOption(IFamilyLoadOptions):
def OnFamilyFound(self,familyInUse,overwriteParameterValues):
overwriteParameterValues = True
return True

def OnSharedFamilyFound(self, sharedFamily, familyInUse, FamilySource, overwriteParameterValues):
overwriteParameterValues = True
return True

#inputs
element = UnwrapElement(IN[0])
parameter = "Material"

#outputs
outlist = []

#get family from element
family = element.Symbol.Family

with doc.EditFamily(family) as famdoc:
#go inside family

#fitered element collector for filtering geometry inside famdoc
collector = Autodesk.Revit.DB.FilteredElementCollector(famdoc);
objects = collector.OfClass(Autodesk.Revit.DB.GenericForm).ToElements()

#get first object from list
object = objects[0]

#get all parameters from object
obj_params = object.GetOrderedParameters()
for p in obj_params:
outlist.Add(p.Definition.Name)

for p in obj_params:
if p.Definition.Name == parameter:
p.Set(Autodesk.Revit.DB.ElementId(-1))

#for p in obj_params:
#if p.Definition.Name == parameter:
#parameterValue = p.AsValueString()

famdoc.LoadFamily(doc,FamilyOption())

del(famdoc)

OUT = object

Somehow, when I open the. dyn and run, the first time always fails.

image

Error message: "The document is currently modifiable. Close the transaction before calling EditFamily "

But wait… when I recreate the python node (copy/paste) and run again, then no error comes!

image

You can also check out this short vid I made as a short demo (sorry for bad quality). https://www.youtube.com/watch?v=jxRaRXn9Xpk
In the first run i demonstrate the situation described above. In the second run I copy/paste the node before running, but then still, the first time fails, and after copy pasting again it works.

Question:
Does anyone understand the logic behind this behaviour? Can it be solved to work cleanly?

Second question (less important but still curious):

I am somehow able to succesfully set the parameter inside famdoc without using a transaction (as can be seen in the code). How is this possible?

PS. Might you want to test for yourself: here’s a download link to the files

I did some searching on similar famdoc / EditFamily code snippets. This thread seems interesting. Might be related…

Hi,

Where do you call the transaction.start and end? :slight_smile:

I didnt! Which is why I am surprised that I am able to set the parameter nevertheless (when the code runs). Do you understand how this is possible?

Here’s some ‘proof’ that it worked:

screenshot before running (inside family editor

after running:

I adopted the code snippet by Konrad Sobon in the linked thread and that works.