Newbie can't get transaction to close

I’ve been going in circles with this for far too long.

I am developing a script based on a Dynamo script I developed that automates the visibility of keyplan areas. I am struggling with learning to work with the Revit API and have outpaced my capabilities.

Here’s my pyRevit pushbutton script so far:

# AUTO KEYPLAN AREA tool

# Initial imports
from pyrevit import revit, forms
from Autodesk.Revit.DB import FilteredElementCollector, FamilySymbol, ElementCategoryFilter, BuiltInCategory, Parameter

# New imports for adding a parameter
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

# Initialization
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document

# Fetch all Titleblock families
def get_titleblock_families():
    collector = FilteredElementCollector(doc)
    titleblock_filter = ElementCategoryFilter(BuiltInCategory.OST_TitleBlocks)
    titleblocks = collector.WherePasses(titleblock_filter).WhereElementIsElementType().ToElements()
    
    return titleblocks

# Get Titleblock families from the project
titleblock_families = get_titleblock_families()

# Prepare data for the dropdown menu (family names and family IDs)
family_options = {}
for titleblock in titleblock_families:
    family_symbol = titleblock  # Since we're dealing with FamilySymbols, not Families directly
    family = family_symbol.Family  # Access the Family object
    family_name = family.Name  # Now access the Family name
    family_id = family_symbol.Id
    family_options[family_name] = family_id

# If there are families to choose from, display the dropdown menu
if family_options:
    # Using SelectFromList for dropdown-style selection
    selected_family_name = forms.SelectFromList.show(list(family_options.keys()), title="Select Titleblock Family")
    
    if selected_family_name:
        selected_family_id = family_options.get(selected_family_name)
        selected_family = doc.GetElement(selected_family_id)
        
        # Check if the selected titleblock contains the parameter "KeyplanAreaToggle"
        parameter = selected_family.LookupParameter("KeyplanAreaToggle")
        
        if parameter:
            print("The selected titleblock contains the 'KeyplanAreaToggle' parameter.")
        else:
            print("The selected titleblock does not contain the 'KeyplanAreaToggle' parameter.")
else:
    forms.alert("No titleblock families found in this project.", exit=True)
    
# Add the KeyplanAreaToggle parameter
    
# Define the shared parameter file path
shared_param_file_path = r'P:\STL\TB\pyRevit Shared Parameters\pyRevitSharedParameters_byTB.txt'

# Open the shared parameter file
app = doc.Application
app.SharedParametersFilename = shared_param_file_path
shared_param_file = app.OpenSharedParameterFile()

# Get the shared parameter definition
param_def = None
for group in shared_param_file.Groups:
    if group.Name == "Graphics":
        for definition in group.Definitions:
            if definition.Name == "KeyplanAreaToggle":
                param_def = definition
                break

# Create a category set and add the family category
category_set = app.Create.NewCategorySet()
category_set.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_TitleBlocks))

# Create an instance binding
instance_binding = app.Create.NewInstanceBinding(category_set)

# Start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)

try:
    # Add the shared parameter to the family
    if param_def:
        doc.FamilyManager.AddParameter(param_def, BuiltInParameterGroup.PG_GRAPHICS, True)
    # Commit the transaction
    TransactionManager.Instance.TransactionTaskDone()
except Exception as e:
    print("An error occurred: {}".format(e))
    TransactionManager.Instance.ForceCloseTransaction()


Thank you in advance for your advice!

Well - at a quick glance you are mixing Dynamo and pyRevit references. Not the way to go.
Dump RevitServices (Dynamo) and just use the api for your transactions and documents.

1 Like

Use with revit.Transaction("scriptname"): when in need for a transaction. This eliminates everything else (start, close etc)

with revit.Transaction("My script"):
    doc.FamilyManager.AddParameter(param_def, BuiltInParameterGroup.PG_GRAPHICS, True)

that’s enough.

1 Like

For Reference:
https://pyrevitlabs.github.io/pyRevit/reference/pyrevit/revit/db/transaction/

2 Likes

Thank you all for your responses. I have researched your recommendations and implemented them to the best of my ability.

My script:

# Initial imports
from pyrevit import revit, forms
from Autodesk.Revit.DB import FilteredElementCollector, FamilySymbol, ElementCategoryFilter,\
     BuiltInCategory, Parameter, FamilyManager

# New imports for adding a parameter
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
from Autodesk.Revit.DB import *
#from RevitServices.Persistence import DocumentManager
#from RevitServices.Transactions import TransactionManager

# Initialization
uidoc = __revit__.ActiveUIDocument
doc = uidoc.Document

# Fetch all Titleblock families
def get_titleblock_families():
    collector = FilteredElementCollector(doc)
    titleblock_filter = ElementCategoryFilter(BuiltInCategory.OST_TitleBlocks)
    titleblocks = collector.WherePasses(titleblock_filter).WhereElementIsElementType().ToElements()
    
    return titleblocks

# Get Titleblock families from the project
titleblock_families = get_titleblock_families()

# Prepare data for the dropdown menu (family names and family IDs)
family_options = {}
for titleblock in titleblock_families:
    family_symbol = titleblock  # Since we're dealing with FamilySymbols, not Families directly
    family = family_symbol.Family  # Access the Family object
    family_name = family.Name  # Now access the Family name
    family_id = family_symbol.Id
    family_options[family_name] = family_id

# If there are families to choose from, display the dropdown menu
if family_options:
    # Using SelectFromList for dropdown-style selection
    selected_family_name = forms.SelectFromList.show(list(family_options.keys()), title="Select Titleblock Family")
    
    if selected_family_name:
        selected_family_id = family_options.get(selected_family_name)
        selected_family = doc.GetElement(selected_family_id)
        
        # Check if the selected titleblock contains the parameter "KeyplanAreaToggle"
        parameter = selected_family.LookupParameter("KeyplanAreaToggle")
        
        if parameter:
            print("The selected titleblock contains the 'KeyplanAreaToggle' parameter.")
        else:
            print("The selected titleblock does not contain the 'KeyplanAreaToggle' parameter.")
else:
    forms.alert("No titleblock families found in this project.", exit=True)
    
# Add the KeyplanAreaToggle parameter
    
# Define the shared parameter file path
shared_param_file_path = r'P:\STL\TB\pyRevit Shared Parameters\pyRevitSharedParameters_byTB.txt'

# Open the shared parameter file
app = doc.Application
app.SharedParametersFilename = shared_param_file_path
shared_param_file = app.OpenSharedParameterFile()

# Get the shared parameter definition
param_def = None
for group in shared_param_file.Groups:
    if group.Name == "Graphics":
        for definition in group.Definitions:
            if definition.Name == "KeyplanAreaToggle":
                param_def = definition
                break

# Create a category set and add the family category
category_set = app.Create.NewCategorySet()
category_set.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_TitleBlocks))

# Create an instance binding
instance_binding = app.Create.NewInstanceBinding(category_set)

# Start a transaction
#TransactionManager.Instance.EnsureInTransaction(doc)

"""
try:
    # Add the shared parameter to the family
    if param_def:
        doc.FamilyManager.AddParameter(param_def, BuiltInParameterGroup.PG_GRAPHICS, True)
    # Commit the transaction
    TransactionManager.Instance.TransactionTaskDone()
except Exception as e:
    print("An error occurred: {}".format(e))
    TransactionManager.Instance.ForceCloseTransaction()
"""

# Transaction solution suggestion from pyRevit forum.
with revit.Transaction("AKPA_script"):
    doc.FamilyManager.AddParameter(param_def, BuiltInParameterGroup.PG_GRAPHICS, True)

generates an error:

"P:\STL\TB\BR+A_Tools\BR+A_Tools.extension\BR+A_Tools.tab\BR+A_Tools.Panel\Sheets.pulldown\AutoKeyplanArea.pushbutton\AKPA_script.py", line 106, in <module>
Exception: Document.FamilyManager can only be used in the Revit Family Editor.

Can I continue here or should I start another topic?

Better start a new one: keeps things clutter free.

2 Likes