'Exception shared parameter already in use' when adding it to a nested family

'Exception shared parameter already in use' when adding it to a nested family

floretti
Advocate Advocate
1,431 Views
9 Replies
Message 1 of 10

'Exception shared parameter already in use' when adding it to a nested family

floretti
Advocate
Advocate

Good morning all,

 

I have a library I need to go through fixing some issues with:

  1. A missing shared parameter inside nested families;
  2. The same missing shared parameter in the host families;
  3. The same shared parameter inside nested families not associated to their host's counterpart.

I managed to create all the checks to identify each case but for some reason when I attempt to edit one of the nested families to add the shared parameter I get the exception below.

Autodesk.Revit.Exceptions.ArgumentException: The shared parameter 'Condition' is already in use.

 

I managed to add the parameter to the host family but I get that error when I edit one of the nested families and try to add the parameter. I've been stuck on that for a while and any help would be very much appreciated. Below is some of the code (in Python) I'm using.

 

# Get shared parameter definition
requiredDefinition = []
spFile = app.OpenSharedParameterFile()
dGroups = spFile.Groups
for dg in dGroups:
    if dg.Name == '00_Families_Constraints':
        for d in dg.Definitions:  # There's only one in the group
            requiredDefinition.Add(d)

# Check if the host has the Condition parameter
familyManager = doc.FamilyManager
famPar = familyManager.Parameters
hostCondPar = [par for par in famPar if par.Definition.Name == 'Condition']

t1 = Transaction(doc, 'Add Condition parameter')
t1.Start()
if hostCondPar == []:
    for d in requiredDefinition:
        newCondPar = familyManager.AddParameter(d,BuiltInParameterGroup.PG_CONSTRAINTS,True)
    print('Condition added to host.')
else:
    print('Host already has Condition.')
    pass
t1.Commit()

# Collect all placed instances of nested families
famInstanceCollector = FilteredElementCollector(doc).OfClass(FamilyInstance).ToElements()
famList = list(famInstanceCollector)

# Go through all placed instances of nested families
for famInst in famList:
    fam = famInst.Symbol.Family
    # edit family to collect its Shared status
    if fam.IsEditable == True and famInst.ArePhasesModifiable() == True:
        famdoc = doc.EditFamily(fam)
        thisFamily = famdoc.OwnerFamily
        nestFamManager = famdoc.FamilyManager
        sharedPar = thisFamily.get_Parameter(BuiltInParameter.FAMILY_SHARED)
        sharedValue = sharedPar.AsInteger()
        # if shared, check the Condition parameter is present
        if sharedValue == 1 and famInst.Symbol.FamilyName != None:
            nestCondPar = famInst.LookupParameter('Condition')
            # if present and linked, pass
            if nestCondPar != None and nestCondPar.IsReadOnly == True:
                pass
            # if not present, add it
            elif nestCondPar == None:
                t2 = Transaction(famdoc, 'Add Condition parameter')
                t2.Start()
                for d in requiredDefinition:
                    # THIS IS WHERE THE ERROR HAPPENS
                    newCondPar = nestFamManager.AddParameter(d,BuiltInParameterGroup.PG_CONSTRAINTS,True)
                t2.Commit()
            # if present but not linked, link it
            elif nestCondPar != None and nestCondPar.IsReadOnly != True:
            # Add linking code here

 

0 Likes
Accepted solutions (1)
1,432 Views
9 Replies
Replies (9)
Message 2 of 10

RPTHOMAS108
Mentor
Mentor

Try getting a fresh version of definition 'd' rather than adding the same one multiple times to different objects.

 

External Definitions you get from a file tend to have a certain object scope.

 

I can't see much else wrong but Python always looks like a bit of a letters jumble to me, so I may be missing something more obvious although I have a vague recollection of this behaviour.

0 Likes
Message 3 of 10

floretti
Advocate
Advocate

Good idea, I've tried a million things so far but not that. Thanks, I'll report back soon.

0 Likes
Message 4 of 10

floretti
Advocate
Advocate

I reopened the shared parameters file, collected the definition again but assigned it to a different variable this time but I got the same error.

 

requiredDefinition2 = []
spFile = app.OpenSharedParameterFile()
dGroups = spFile.Groups
for dg in dGroups:
    if dg.Name == '00_Families_Constraints':
        for d2 in dg.Definitions:
            requiredDefinition2.Add(d2)
for d2 in requiredDefinition2:
    newCondPar = nestFamManager.AddParameter(d2,BuiltInParameterGroup.PG_CONSTRAINTS,True)
t2.Commit()

 

0 Likes
Message 5 of 10

RPTHOMAS108
Mentor
Mentor

The real test would be to re-get after the first transaction is committed (and between each subsequent one) that is when the object state could potentially change as a result of being added. This is probably the test I would do but as stated there may be something else more obvious.

 

I usually do these definition getting things as a discreet function call to keep the object lifecycle as short as possible.

 

I'm also assuming the objects assigned to separate variables above are linked by memory reference so what is done to one affects the other (they are the same object in reality perhaps).

0 Likes
Message 6 of 10

floretti
Advocate
Advocate

I actually commented out the entire block of code where the first transaction is just in case. This way there are no other transactions opened/closed in the code apart from the one triggering the error but I still get the error.

 

I also made sure the host doesn't have the parameter in case the Add is trying to re-add it to the host but it doesn't seem to be the issue either as I still get the error.

 

I had enough of going through this code looking for possible issues!!!!  😭

0 Likes
Message 7 of 10

RPTHOMAS108
Mentor
Mentor

There is something slightly more obvious actually.

 

You are collecting and iterating family instances in the main family couldn't you just go through the family symbols to start with i.e. do you have more than one of the same family instance and are adding parameters multiple times to it's family?

 

Filter for symbols, see if there are any placed instances of each, then edit family of that symbol.

0 Likes
Message 8 of 10

floretti
Advocate
Advocate

Yep, I think you are onto something there. The code could be looping through the same family twice trying to add the same parameter since there are two placed instances. I'll change that and report back.

 

Thanks again, @RPTHOMAS108 .

0 Likes
Message 9 of 10

floretti
Advocate
Advocate
Unfortunately that wasn't the problem. The error is coming up in the first iteration of one of the two placed instances of a nested family.
0 Likes
Message 10 of 10

floretti
Advocate
Advocate
Accepted solution
I found the issue. The edited family was not being loaded back into the host and was lingering in the background the entire time, hence the error saying that the parameter was already added into the family from previous runs of the script inside the same instance of Revit.

Once I restarted Revit, added the missing lines to load the family back into the host and close it, I re-ran the script and it all worked.
0 Likes