Global Parameters can be renamed, deleted, or added or changed via the Revit API. This is especially useful in office contexts, where it is sometimes necessary to update dozens of parameters across hundreds of files, a task that would take us (or a student) days to finish by hand.
Let's say we want to change the global parameters in our office so they match the following:
- Apple: 10 mm
- Banana: "Example String"
- Cherry: Yes
We'll start by converting that into a python dictionary:
| global_parameters_should_be = { |
| "Apple": { |
| "Type": "Length", |
| "Value": 10/304.8 |
| }, |
| "Banana": { |
| "Type": "String", |
| "Value": "Example String" |
| }, |
| "Cherry": { |
| "Type": "Boolean", |
| "Value": 1 |
| } |
| } |
Now, any parameter whose value does not match our template, we'll overwrite. Any extra parameters, we'll delete. Any parameter that does not exist, we'll create. You can be clever here and combine these steps to save processing time, but for the sake of clarity, I'll take each step individually.
Renaming Parameters
Before we begin, it's worth checking to see if there are any existing parameters that would be better renamed than deleted. Say we have a parameter in all our files called "Old Apple", which is connected to all our wall heights.
It's not in the list above, but we don't necessarily want to delete it because we'd have to reconnect all our walls. It would be better to rename it.
We can start this process by creating a simple dictionary to hold our old and new names:
| global_parameters_to_rename = { |
| "Old Apple": "Apple", |
| "Old Banana": "Banana", |
| "Old Cherry": "Old Cherry" |
| } |
Now, all we need to do is get our existing global parameters and change any that show up in the global_parameters_to_rename dictionary.
| doc = DocumentManager.Instance.CurrentDBDocument |
| |
| existing_global_parameter_ids = GlobalParametersManager.GetAllGlobalParameters(doc) |
| |
| for gp_id in existing_global_parameter_ids: |
| gp = doc.GetElement(gp_id) |
| name = gp.Name |
| if name in global_parameters_to_rename: |
| new_name = global_parameters_to_rename[name] |
| TransactionManager.Instance.EnsureInTransaction(doc) |
| gp.Name = new_name |
| TransactionManager.Instance.TransactionTaskDone() |
Deleting Parameters
Now let's delete all the parameters that do not should up in our global_parameters_should_be dictionary.
| existing_global_parameter_ids = GlobalParametersManager.GetAllGlobalParameters(doc) |
| |
| for gp_id in existing_global_parameter_ids: |
| gp = doc.GetElement(gp_id) |
| name = gp.Name |
| if name not in global_parameters_should_be: |
| TransactionManager.Instance.EnsureInTransaction(doc) |
| doc.Delete(gp_id) |
| TransactionManager.Instance.TransactionTaskDone() |
Adding Parameters
Next, we'll add any missing parameters. This is a little bit trickier because we need to pay attention to the parameter type. I've purposefully tailored this example to include the three most common types. For other types, see the SpecTypeId Members in the Revit API Documentation.
| existing_global_parameter_ids = GlobalParametersManager.GetAllGlobalParameters(doc) |
| |
| existing_global_parameter_names = [] |
| for gp_id in existing_global_parameter_ids: |
| gp = doc.GetElement(gp_id) |
| name = gp.Name |
| existing_global_parameter_names.append(name) |
| |
| for new_parameter_name, new_parameter_sub_dict in global_parameters_should_be.items(): |
| if new_parameter_name not in existing_global_parameter_names: |
| new_parameter_value = new_parameter_sub_dict["Value"] |
| new_parameter_type = new_parameter_sub_dict["Type"] |
| TransactionManager.Instance.EnsureInTransaction(doc) |
| if new_parameter_type == "Length": |
| parameter = GlobalParameter.Create(doc, new_parameter_name, SpecTypeId.Length) |
| parameter.SetValue(DoubleParameterValue(new_parameter_value)) |
| elif new_parameter_type == "String": |
| parameter = GlobalParameter.Create(doc, new_parameter_name, SpecTypeId.String.Text) |
| parameter.SetValue(StringParameterValue(new_parameter_value)) |
| elif new_parameter_type == "Boolean": |
| parameter = GlobalParameter.Create(doc, new_parameter_name, SpecTypeId.Boolean.YesNo) |
| parameter.SetValue(IntegerParameterValue(new_parameter_value)) |
| TransactionManager.Instance.TransactionTaskDone() |
Changing Parameter Values
The names of the global parameters in our file should now match those in our dictionary. The only thing we need to check now is the parameter values. Again, we need to pay attention to the parameter type.
| existing_global_parameter_ids = GlobalParametersManager.GetAllGlobalParameters(doc) |
| |
| for gp_id in existing_global_parameter_ids: |
| gp = doc.GetElement(gp_id) |
| name = gp.Name |
| value = gp.GetValue().Value |
| for parameter, parameter_sub_dict in global_parameters_should_be.items(): |
| if parameter == name: |
| value_should_be = parameter_sub_dict["Value"] |
| if value != value_should_be: |
| parameter_type = parameter_sub_dict["Type"] |
| TransactionManager.Instance.EnsureInTransaction(doc) |
| if parameter_type == "Length": |
| parameter.SetValue(DoubleParameterValue(value_should_be)) |
| elif parameter_type == "String": |
| parameter.SetValue(StringParameterValue(value_should_be)) |
| elif parameter_type == "Boolean": |
| parameter.SetValue(IntegerParameterValue(value_should_be)) |
| TransactionManager.Instance.TransactionTaskDone() |
The names and values of the global parameters in the file should now match those in our global_parameters_should_be dictionary.
Comments
Post a Comment