Comparing parameters between two elements

Comparing parameters between two elements

PerryLackowski
Advocate Advocate
875 Views
5 Replies
Message 1 of 6

Comparing parameters between two elements

PerryLackowski
Advocate
Advocate

I did some digging on the forums, and I'm not having any luck finding a clear explanation for this one. Specifically, I'm trying to duplicate sheets and transfer all the parameter data with them. I'm having no problems using ViewSheet.Create() to duplicate the sheet, but we have many Shared Project Parameters on the sheet that control the visibility of different parts of the key plan, and I'd like these Yes/No settings to carry over as well. For any parameter in old_sheet, how can I find the parameter in new_sheet? I am trying to avoid using the name property, since duplicate parameter names have been known to occur. I thought I'd be able to compare the definitions, but that hasn't worked:

 

old_sheet_params = old_sheet.Parameters
new_sheet_params = new_sheet.Parameters

param_dict = {}
for param in old_sheet_params:
    if param.StorageType == DB.StorageType.String:
        val = param.AsString()
    elif param.StorageType == DB.StorageType.Double:
        val = param.AsDouble()
    elif param.StorageType == DB.StorageType.Integer:
        val = param.AsInteger()
    else:
        val = None

    param_dict[param.Definition] = param.Definition.Name, val

    print('{} {} {}'.format(param.Definition.Name, val, param.Definition))

print('\nNEW PARAMS\n')

for param in new_sheet_params:
    if param.Definition.Name == 'Sheet Number':
        continue            

    if param.Definition in param_dict:
        print('definition found.')
        new_val = param_dict[param.Definition][1]
    else:
        continue
    
    print('{} {} {}'.format(param.Definition.Name, new_val, param.Definition))

 

Accepted solutions (1)
876 Views
5 Replies
Replies (5)
Message 2 of 6

RPTHOMAS108
Mentor
Mentor

No, definition doesn't implement equality function but the indexed property Element.Parameter takes a Definition object and returns a parameter for that definition.

 

I therefore think the more obvious thing to do is get the definitions from Element1 and use those to get the same parameters on Element2 via Element.Parameter. I don't think storing them in a separate list is required since the elements themselves could act as the lists already. 

 

Note also that some of your parameters may be on the title block element not the sheet. If you have site key plan etc. then that is usually done on the title block in my experience.

Message 3 of 6

PerryLackowski
Advocate
Advocate

Still struggling with this one. I'm guessing it has to do with revit python wrapper? Once it finds a parameter to set, it throws "TypeError: expected BuiltInParameter, got InternalDefinition". It seems like the Element.Parameter property has three optional arguments, Guid, BuiltInParameter, or Definition. For some reason the script is trying to use the incorrect one. Anyway to override this?

# new_sheet_params = new_sheet.Parameters
old_sheet_params = old_sheet.Parameters

for param in old_sheet_params:
    print(param.Definition.Name)
    if param.Definition.Name == 'Sheet Number':
        continue
    
    if param.StorageType == DB.StorageType.String:
        val = param.AsString()
    elif param.StorageType == DB.StorageType.Double:
        val = param.AsDouble()
    elif param.StorageType == DB.StorageType.Integer:
        val = param.AsInteger()
    elif param.StorageType == DB.StorageType.ElementId:
        val = param.AsElementId()
    else:
        continue
    
    print('Value found: {}'.format(val))

    if val:
        new_param = new_sheet.Parameter[param.Definition]
        if new_param:
            new_param = val
            print('Set to: {}'.format(val))
        else:
            print('parameter not found')

t.Commit()

 

0 Likes
Message 4 of 6

RPTHOMAS108
Mentor
Mentor
new_param = new_sheet.get_Parameter(param.Definition)
Message 5 of 6

PerryLackowski
Advocate
Advocate

Almost there. I rewrote as a generic function so I can use it to transfer parameters from sheet to sheet, as well as title block to title block. It also excludes the read-only parameters now. However, I'm having difficulties with all Yes/No parameters that are unchecked turning back on. Using the snoop tool on a Yes/No parameter, it looks like AsDouble returns 0 regardless of the value of AsInteger(), which will be 1 or 0 for Yes or No. I'm guessing the param.Set(0) is assuming I'm trying to pass in a double?

def copy_parameter_values(source,destination):

    for param in source.Parameters:
        print(param.Definition.Name)
        if param.IsReadOnly:
            continue

        exclusions = [DB.BuiltInParameter.SHEET_NUMBER]
        if param.Definition.BuiltInParameter in exclusions:
            continue

        if param.StorageType == DB.StorageType.String:
            val = param.AsString()
        elif param.StorageType == DB.StorageType.Double:
            val = param.AsDouble()
        elif param.StorageType == DB.StorageType.Integer:
            val = param.AsInteger()
        elif param.StorageType == DB.StorageType.ElementId:
            val = param.AsElementId()
        else:
            continue

        print('value is {}'.format(val))
        if val:
            new_param = destination.get_Parameter(param.Definition)
            new_param.Set(val)
            # if new_param:
                # new_param.Set(val)
            # else:
            #     print('param not found on new element')

 

0 Likes
Message 6 of 6

PerryLackowski
Advocate
Advocate
Accepted solution

Mistake on my part - 0 evaluates to False in python, so when I was checking that the parameter existed, my "if val:" was returning false for the Yes/No parameters, so their values weren't even getting set in the first place. Here's the final version of the function. I'll try to remember to post the entire script here once it's done.

def copy_parameter_values(source,destination):

    for param in source.Parameters:
        print(param.Definition.Name)
        if param.IsReadOnly:
            continue

        exclusions = [DB.BuiltInParameter.SHEET_NUMBER]
        if param.Definition.BuiltInParameter in exclusions:
            continue

        if param.StorageType == DB.StorageType.String:
            val = param.AsString()
        elif param.StorageType == DB.StorageType.Double:
            val = param.AsDouble()
        elif param.StorageType == DB.StorageType.Integer:
            val = param.AsInteger()
        elif param.StorageType == DB.StorageType.ElementId:
            val = param.AsElementId()
        else:
            continue

        if val is not None:
            new_param = destination.get_Parameter(param.Definition)
            new_param.Set(val)

 

0 Likes