Third party updater has experienced a problem and its action had to be canceled

I have a script made by another user before leaving the team who was trying to create a parameter linker where if parameter A changes, B changes. I don’t think it was ever finished. I try to run it and get this message
image

but when i make a change to the comments, i’ll get this other message
image

the code itself is a bit hard for me to understand yet.

at one point i got a few messages when i restarted revit about

image

what could cause this?

this is what was started:

import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitServices')
clr.AddReference('System')
from Autodesk.Revit.DB import *
from Autodesk.Revit.UI import *
from Autodesk.Revit.Attributes import *
from System import Guid
from System.Collections.Generic import List

# Custom Updater class
class ParameterLinkerUpdater(IUpdater):
    def __init__(self, addin_id, source_param_name, target_param_name):
        self.addin_id = addin_id
        self.updater_id = UpdaterId(self.addin_id, Guid.NewGuid())
        self.source_param_name = source_param_name
        self.target_param_name = target_param_name

    def GetUpdaterId(self):
        return self.updater_id
    
    def GetUpdaterName(self):
        return "Parameter Linker Updater"
    
    def GetAdditionalInformation(self):
        return "Updates linked parameters dynamically"

    def GetChangePriority(self):
        return ChangePriority.MEPSystems  # Using a valid priority

    def Execute(self, data):
        doc = data.GetDocument()
        for id in data.GetModifiedElementIds():
            element = doc.GetElement(id)
            source_param = element.LookupParameter(self.source_param_name)
            target_param = element.LookupParameter(self.target_param_name)

            if source_param and target_param:
                # Transfer the value from the source parameter to the target parameter
                target_param.Set(source_param.AsString())
                TaskDialog.Show("Parameter Linker", "Updated {} based on {}".format(self.target_param_name, self.source_param_name))

# Function to register the updater
def register_updater(doc, source_param_name, target_param_name):
    app = doc.Application
    addin_id = app.ActiveAddInId
    updater = ParameterLinkerUpdater(addin_id, source_param_name, target_param_name)
    
    # Register the updater with Revit
    UpdaterRegistry.RegisterUpdater(updater)

    # Define filter criteria to track all elements with the specified source parameter
    param_id = ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)  # Use a valid parameter ID
    filter = ElementParameterFilter(ParameterFilterRuleFactory.CreateContainsRule(param_id, "", True))

    # Register triggers (parameter changes) that will activate the updater
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), filter, Element.GetChangeTypeParameter(param_id))

    return updater

# Function to unregister the updater (optional)
def unregister_updater(updater):
    UpdaterRegistry.UnregisterUpdater(updater.GetUpdaterId())

# Main function to create and register parameter links
def main():
    doc = __revit__.ActiveUIDocument.Document
    
    # Define the source and target parameter names
    source_param_name = "Comments"
    target_param_name = "Mark"

    # Register the updater
    updater = register_updater(doc, source_param_name, target_param_name)
    
    TaskDialog.Show("Parameter Linker", "Parameter Linker Updater registered to update '{}' whenever '{}' changes.".format(target_param_name, source_param_name))

main()

Nice code you have there, after a little debbuging I’ve received this error:

global name 'TaskDialog' is not defined

Looks like you need to from Autodesk.Revit.UI import TaskDialog within class function:
Bug is in this section:

    def Execute(self, data):
        doc = data.GetDocument()
        for id in data.GetModifiedElementIds():
            element = doc.GetElement(id)
            source_param = element.LookupParameter(self.source_param_name)
            target_param = element.LookupParameter(self.target_param_name)

            if source_param and target_param:
                from Autodesk.Revit.UI import TaskDialog
                # Transfer the value from the source parameter to the target parameter
                target_param.Set(source_param.AsString())
                # Here's the issue:
                TaskDialog.Show("Parameter Linker", "Updated {} based on {}".format(self.target_param_name, self.source_param_name))

Or just delete/comment this line as after few pop-ups users will hate it.

1 Like

@MarcinTalipski wow, just one little line of code and bam. Thank you. I am curious, is it as simple as changing the “Comments” parameter (built-in)

from here:

# Function to register the updater
def register_updater(doc, source_param_name, target_param_name):
    app = doc.Application
    addin_id = app.ActiveAddInId
    updater = ParameterLinkerUpdater(addin_id, source_param_name, target_param_name)
    
    # Register the updater with Revit
    UpdaterRegistry.RegisterUpdater(updater)

    # Define filter criteria to track all elements with the specified source parameter
    param_id = ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)  # Use a valid parameter ID
    filter = ElementParameterFilter(ParameterFilterRuleFactory.CreateContainsRule(param_id, "", True))

    # Register triggers (parameter changes) that will activate the updater
    UpdaterRegistry.AddTrigger(updater.GetUpdaterId(), filter, Element.GetChangeTypeParameter(param_id))

    return updater

# Function to unregister the updater (optional)
def unregister_updater(updater):
    UpdaterRegistry.UnregisterUpdater(updater.GetUpdaterId())

# Main function to create and register parameter links
def main():
    doc = __revit__.ActiveUIDocument.Document
    
    # Define the source and target parameter names
    source_param_name = "Comments"
    target_param_name = "Mark"

specifically this line
param_id = ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_COMMENTS)
and this line
source_param_name = "Comments"
to a shared parameter"?

i tried doing this but it crashed:

specifically this line
param_id = ElementId(BuiltInParameter.ALL_MODEL_INSTANCE_ID INSTANCE)
and this line
source_param_name = "ID Instance"

my “ID Instance” is a shared text parameter.

I’m afraid that you are mixing two types of parameters. First BuiltInParameters are as name suggests built in Revit, you can use them i.e. to access parametert independently from language. You can find more about them here:

On the other hand shared parameters are (mostly) created by users. It should be fine using it name to find parameter, then retrieve it’s ID number to pass to filter.

However you have to remember that if in one project there are multiple parameters with the same name it will access the parameter with the lowest ID. If you wish to avoid it I think there is a way to retrieve shared parameter by it’s GUID number from shared parameters text file.

2 Likes