Ask:
Any assistance is appreciated. I am willing to research any references someone can provide. I have looked through several examples but seem to be missing something. Thank you to anyone willing to offer help!
import clr
import tempfile
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
# Get the Revit application and document
doc = DocumentManager.Instance.CurrentDBDocument
uiapp = DocumentManager.Instance.CurrentUIApplication
app = uiapp.Application
uidoc = uiapp.ActiveUIDocument
# Inputs
parameter_name = "WallFunction" # Name of the parameter to create
group_name = "Wallz" # Name of the parameter group to create
spec_type = SpecTypeId.String.Text # Data type of the parameter to create
group_type = "PG_DATA" # Group type of the parameter to create (BuiltInParameterGroup Enumeration, i.e. PG_DATA)
instance = True # Instance or type parameter
# Start a new transaction
TransactionManager.Instance.EnsureInTransaction(doc)
try:
# get current shared parameter file
original_shared_parameter_file = doc.Application.SharedParametersFilename
# Create a temporary shared parameter file
temp_shared_parameter_file = tempfile.NamedTemporaryFile(suffix=".txt").name
open(temp_shared_parameter_file, 'w').close()
doc.Application.SharedParametersFilename = temp_shared_parameter_file
# Apply the Walls category to the parameter
category = Category.GetCategory(doc, BuiltInCategory.OST_Walls)
binding = InstanceBinding(category)
# Create the parameter and apply the binding
group = doc.Application.OpenSharedParameterFile().Groups.Create(group_name)
options = ExternalDefinitionCreationOptions(parameter_name, spec_type)
options.ParameterGroup = group_type
parameter = group.Definitions.Create(options)
doc.ParameterBindings.Insert(parameter, binding, group_type)
# Revert to the original shared parameter file
#doc.Application.SharedParametersFilename = original_shared_parameter_file
# Commit the transaction
TransactionManager.Instance.TransactionTaskDone()
except Exception as e:
# Rollback the transaction on error
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.ForceCloseTransaction()
raise e
OUT = binding, group, options, parameter
Yep. you need ForgeId’s for everything now.
I’d start with Jeremy’s site and go from theer. Not that difficult. Just different. The Building Coder (typepad.com)
Not understanding how to go from BuiltInParameterGroup Enumeration to ForgeTypeId…
If this was not there what would one do to get it? I asume as it says this may not be there in 2024.
public static BuiltInParameterGroup GetBuiltInParameterGroup(
ForgeTypeId groupTypeId
)
Also just tried unsuccessfully: doc.ParameterBindings.Insert(parameter, binding, BuiltInParameterGroup.PG_DATA)
it all changed in 2023. 2022 was the last of not using Forge.
ParameterType dies with 2022.
If you look at the parameters with Snoop you can get some insight.
You’ll need to create a ForgeTypeId with the ForgeTypeId constructor and pass that to the method for the parameter.
@aaronrumple Thank you so much for the help. I am still to inexperienced at this point to get this done. I will have to revisit it later as I have used my dedicated time and then some on this issue today.
@c.poupin Thank you so much for the time you spent posting! I have tried your code directly with the ForgeTypeId GroupTypeId.Data that is an example of just the binding of a shared parmater that exist. I need to study this and and work it into my code as my first pass did no work. I will repost tomorrow with my results. Thanks again @c.poupin !
@c.poupin, thank you so much for your help! With your guidance, I was able to write working code and gain a better understanding of the topic. I will definitely put this knowledge to the test in future endeavors.
Here’s the code I ended up with, which is a combination of the community’s efforts. I’ve added comments to make it easier for future learners to understand. If anyone has suggestions for improvements, please feel free to comment.
For those who are new to this, I just want to note that I’ve used internally defined parameters, which can be changed to external parameters using the IN[0] syntax. This particular code only processes a single parameter and category, so loops would be necessary if multiple parameters need to be processed.
Once again, thank you for your time and for helping the community!
"""
Create a new shared parameter for Revit walls.
Inputs:
parameter_name (str): Name of the parameter to create.
group_name (str): Name of the parameter group to create.
spec_type (str): Data type of the parameter to create (e.g. "Text", "Integer").
group_type (str): Group type of the parameter to create (BuiltInParameterGroup Enumeration, i.e. PG_DATA).
instance (bool): If True, create an instance parameter. If False, create a type parameter.
Returns:
ExternalDefinition: The created shared parameter definition.
Process:
The reason for creating a temporary file is to ensure that the parameter is created in the correct file with the desired configuration. By creating a temporary file, the script can control the exact path and name of the file, which is necessary for the next steps. The code imports the temporary file and adds the shared parameter to it, then retrieves it and applies it to the desired element type. Once the parameter has been created and bound, the temporary file can be removed, and the original shared parameter file can be reverted to its previous state. Overall, creating a temporary file ensures that the parameter is created as desired and then added to the correct shared parameter file.
"""
# Import required modules
import clr # Common Language Runtime module to interface with .NET libraries
import tempfile # Library for working with temporary files
# Add references to the required Revit modules
clr.AddReference('RevitAPI') # Revit API (Application Programming Interface) module
clr.AddReference('RevitAPIUI') # Revit API User Interface module
from Autodesk.Revit.DB import * # Import Revit's database objects
from Autodesk.Revit.UI import * # Import Revit's User Interface objects
# Add reference to the RevitServices module
clr.AddReference('RevitServices') # Add a reference to the RevitServices module to access its functionality
import RevitServices # Import the RevitServices module to access its classes and functions
from RevitServices.Persistence import DocumentManager # Import the DocumentManager class from the RevitServices.Persistence module
from RevitServices.Transactions import TransactionManager # Import the TransactionManager class from the RevitServices.Transactions module
# Get the current document and Revit application
doc = DocumentManager.Instance.CurrentDBDocument # Current Revit document
uiapp = DocumentManager.Instance.CurrentUIApplication # Current Revit application UI
app = uiapp.Application # Current Revit application
uidoc = uiapp.ActiveUIDocument # Active Revit UI document
# Inputs
parameter_name = "WallFunction" # Name of the parameter to create
group_name = "Wallz" # Name of the parameter group to create
spec_type = SpecTypeId.String.Text # Data type of the parameter to create
group_type = "PG_DATA" # Group type of the parameter to create (BuiltInParameterGroup Enumeration, i.e. PG_DATA)
instance = True # Instance or type parameter
# Start a new transaction
TransactionManager.Instance.EnsureInTransaction(doc)
try:
# get current shared parameter file
original_shared_parameter_file = doc.Application.SharedParametersFilename
# Create a temporary shared parameter file with a .txt suffix
temp_shared_parameter_file = tempfile.NamedTemporaryFile(suffix=".txt").name
open(temp_shared_parameter_file, 'w').close() # Create an empty file with the given name in the previsously defined temp_shared_parameter_file
doc.Application.SharedParametersFilename = temp_shared_parameter_file # Set current document's shared parameter filename to newly created temp file
# Apply the Walls category to the parameter
category = Category.GetCategory(doc, BuiltInCategory.OST_Walls) # Retrieve the Walls category enum to specify the type of element to which the parameter should be bound.
binding = InstanceBinding(category) # Instance binding associates the parameter with specific instances of the chosen element category.
# Create the parameter and apply the binding
group = doc.Application.OpenSharedParameterFile().Groups.Create(group_name) # Create the parameter group with the specified name
options = ExternalDefinitionCreationOptions(parameter_name, spec_type) # Create options for the external definition with the specified parameter name and spec type
options.ParameterGroup = group_type # Set the parameter group type for the external definition
parameter = group.Definitions.Create(options)# Create the external definition (parameter) within the specified group using the given options
# Open the shared parameter file
spf = app.OpenSharedParameterFile()
# Get the groups from the shared parameter file
spfGroups = spf.Groups
# Get the specific shared parameter definition
myExtdef = spfGroups.get_Item(group_name).Definitions.get_Item(parameter_name)
# Create a CategorySet containing the walls category
catSet = CategorySet()
catSet.Insert(Category.GetCategory(doc, BuiltInCategory.OST_Walls))
# Create an instance binding using the CategorySet
binding = InstanceBinding(catSet)
# Add the shared parameter definition to the walls category
doc.ParameterBindings.Insert(myExtdef, binding, GroupTypeId.Data)
# Revert to the original shared parameter file
doc.Application.SharedParametersFilename = original_shared_parameter_file
# Commit the transaction
TransactionManager.Instance.TransactionTaskDone()
except Exception as e:
# Revert to the original shared parameter file
doc.Application.SharedParametersFilename = original_shared_parameter_file
# Rollback the transaction on error
TransactionManager.Instance.TransactionTaskDone()
TransactionManager.Instance.ForceCloseTransaction()
raise e
OUT = myExtdef