I’m trying to replicate data shape’s node to add shared parameters from a txt file, I have created a code with the help of GPT but I’m stuck on this one error :
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.UI import *
# Get the current Revit document and application
doc = DocumentManager.Instance.CurrentDBDocument
app = doc.Application
# Inputs
parameter_names = IN[0] # List of parameter names (strings)
parameter_category = IN[1] # Revit category object (e.g., "Generic Models")
parameter_group = IN[2] # ParameterGroup as ForgeTypeId or other valid type
is_instance = IN[3] # Boolean value for instance or type parameter
# Validate parameter_category
if not isinstance(parameter_category, Category):
OUT = "Invalid parameter category object."
raise ValueError("Input 2 should be a valid Category object.")
# Convert parameter_group to ForgeTypeId if it's not already
if not isinstance(parameter_group, ForgeTypeId):
try:
# Assuming parameter_group is an integer or enum value
parameter_group = ForgeTypeId(parameter_group)
except Exception as e:
OUT = f"Error converting parameter group: {e}"
raise ValueError("Input 3 should be a valid ForgeTypeId or convertible to ForgeTypeId.")
# Create CategorySet for parameter binding
catset = app.Create.NewCategorySet()
catset.Insert(parameter_category)
# Start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)
# Determine parameter binding type
if is_instance:
bind = app.Create.NewInstanceBinding(catset)
else:
bind = app.Create.NewTypeBinding(catset)
# Add parameters to the project
bindmap = doc.ParameterBindings
added_params = 0
failed_params = []
for param_name in parameter_names:
try:
# Create a new ExternalDefinitionCreationOptions object
param_def_options = ExternalDefinitionCreationOptions(param_name, parameter_group)
# Check if parameter already exists
existing_param = None
for param in bindmap:
if param.Name == param_name:
existing_param = param
break
if existing_param:
OUT = f"Parameter '{param_name}' already exists."
continue
# Add the parameter to the document
if not bindmap.Insert(param_def_options, bind, parameter_group):
failed_params.append(param_name)
else:
added_params += 1
except Exception as e:
failed_params.append(f"{param_name}: {e}")
# Commit the transaction
TransactionManager.Instance.TransactionTaskDone()
# Output the results
if failed_params:
OUT = f"{added_params} shared parameters added. Failed to add: {', '.join(failed_params)}"
else:
OUT = f'{added_params} shared parameters added to the project.'
`
This specific data shape node takes only 4 above inputs and I wanted to replicate the same, this exact script has worked without any issue but now I’m getting this issue. I would like to learn what’s the issue here is.
Why not update your Datashapes to the latest build and make sure you have the correct Python dependencies for your Dynamo environment instead of rebuilding someone else’s code? Note that I believe that Datashapes is distributed using an MIT license so you need to maintain that if you’re passing along the code in the graph itself which is added effort you likely want to avoid.
this node returns null, causing the final node to also fail. I have tried getting a ParameterGroup List by my self which outputs “Autodesk.Revit.DB.ForgeTypeId” values, and I believe final node requires some different type of input?? (unless the nodes are absolutely alright and I’m the issue here lol)
Thank you, I have been able to make it almost work, the issue is it only adds first parameter from the list to the project, throws ‘InstanceBinding’ object has no atrribute ‘name’ error for remainings in the list.
I was finally able to do it, Thanks everyone for your insights and help.
import clr
import traceback
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
clr.AddReference("RevitServices")
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Get the current Revit document and application
doc = DocumentManager.Instance.CurrentDBDocument
app = doc.Application
# Inputs
parameter_names = IN[0] # List of parameter names (strings)
parameter_category_input = IN[1] # Revit category objects or Dynamo wrappers
parameter_group_name = IN[2] # String or list of strings (e.g., "General", "Dimensions")
is_instance = IN[3] # Boolean for instance or type parameter
# If parameter_group_name is passed as a list, use the first element
if isinstance(parameter_group_name, list):
parameter_group_name = parameter_group_name[0]
# Fetch all group IDs and names
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import ParameterUtils, LabelUtils
# Get group type IDs and names
group_ids = ParameterUtils.GetAllBuiltInGroups()
group_names = [LabelUtils.GetLabelForGroup(g) for g in group_ids]
# Function to convert parameter group name to BuiltInParameterGroup
def get_parameter_group_id(group_name):
if group_name in group_names:
group_index = group_names.index(group_name)
return group_ids[group_index] # Return corresponding group type ID
return None
# Validate and convert the parameter group name
parameter_group_id = get_parameter_group_id(parameter_group_name)
if not parameter_group_id:
OUT = f"Invalid parameter group name: {parameter_group_name}. Available groups: {', '.join(group_names)}"
raise ValueError(OUT)
# Process categories
try:
categories = [UnwrapElement(cat) for cat in parameter_category_input]
except:
raise ValueError("Invalid categories provided.")
# Create CategorySet for binding
catset = app.Create.NewCategorySet()
for cat in categories:
catset.Insert(cat)
# Access the shared parameter file
shared_param_file = app.OpenSharedParameterFile()
if shared_param_file is None:
raise ValueError("No shared parameter file is loaded. Please load a shared parameter file.")
# Start the transaction
TransactionManager.Instance.EnsureInTransaction(doc)
# Add parameters
added_params = 0
failed_params = []
for param_name in parameter_names:
try:
# Refresh the bindmap in each loop iteration
bindmap = doc.ParameterBindings
# Check if the parameter already exists in the document
existing_param = bindmap.ReverseIterator()
exists = False
while existing_param.MoveNext():
if existing_param.Key.Name == param_name:
exists = True
break
if exists:
print(f"Parameter '{param_name}' already exists, skipping.")
continue
# Look for the parameter in the shared parameter file
param_def = None
for group in shared_param_file.Groups:
param_def = group.Definitions.get_Item(param_name)
if param_def:
break
if param_def is None:
failed_params.append(f"{param_name}: Not found in shared parameter file.")
continue
# Re-create the binding for each parameter
bind = app.Create.NewInstanceBinding(catset) if is_instance else app.Create.NewTypeBinding(catset)
# Attempt to bind the parameter
if bindmap.Insert(param_def, bind, parameter_group_id):
added_params += 1
else:
failed_params.append(param_name)
except Exception as e:
failed_params.append(f"{param_name}: {str(e)}")
# Commit the transaction
TransactionManager.Instance.TransactionTaskDone()
# Output results
if failed_params:
OUT = f"{added_params} shared parameters added. Failed to add: {', '.join(failed_params)}"
else:
OUT = f"{added_params} shared parameters added to the project."