Copying filters from one Revit document to another

Hello everyone!!!

I am trying to create a tool with pyrevit that copies the filters from one project to another, but I run into this error and I can not figure it out. Maybe you could find the mistake and you can point it out.
This is the error:


This is the script:

import pyrevit
from pyrevit import revit,DB
from pyrevit import forms,script


doc = revit.doc

doc_from = forms.select_open_docs(title='Select a document',
                                    button_name='Select',
                                    width= 500,
                                    multiple=False)

if not doc_from:
    forms.alert("No Revit document selected", exitscript=True)
elif doc_from.IsFamilyDocument:
    forms.alert("Must choose a non-family document", exitscript=True)
    
# Get all filters from the document

all_views = DB.FilteredElementCollector(doc_from).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()

views_with_filter = [v for v in all_views if v.GetFilters()]



filter_ids = [v.GetFilters() for v in views_with_filter]

filters = [doc_from.GetElement(f_id) for f_id in filter_ids]
print(filters)


selected_filters = forms.SelectFromList.show(filters,
                                            title='Select the destination view/viewtemplates',
                                            multiselect=True,
                                            button_name='Select source View/ViewTemplate')

if not selected_filters:
    script.exit()

Try this:

Greets

Hey @Manuel486
I have tried that tutorial and it works perfectly when I have to copy the filters from one view/view template to another, but know I want to copy the filters from one opened project to another.

Then you have to use this tool first.
image

That may work. I was wondering if there could work by copying only the filters with it overrides

I think your line 30 refers to this line

filters = [doc_from.GetElement(f_id) for f_id in filter_ids]

I think filter_ids is a list of lists (more accurately a list with a list of ids for each view’s filters), not a list of ids like you’re expecting with this code.

I have managed to solve the error. :slightly_smiling_face:
Now after I copy the filter to another project and try to apply to a selected view, this error comes out

The code is this:

import pyrevit
from pyrevit import revit,DB
from pyrevit import forms,script
from System.Collections.Generic import List


doc = revit.doc

doc_from = forms.select_open_docs(title='Select a document',
                                    button_name='Select',
                                    width= 500,
                                    multiple=False)

if not doc_from:
    forms.alert("No Revit document selected", exitscript=True)
elif doc_from.IsFamilyDocument:
    forms.alert("Must choose a non-family document", exitscript=True)
    
# Get all views from the document
all_views = DB.FilteredElementCollector(doc_from).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()

# Get all views with filter	

views_with_filter = [v for v in all_views if v.GetFilters()]
dict_views_with_filters = {i.Name:i for i in views_with_filter}

selected_src_view = forms.SelectFromList.show(sorted(dict_views_with_filters),
                                            title='Select the source view/viewtemplates',
                                            multiselect=False,
                                            button_name='Select source View/ViewTemplate')

# Select the filters from the source view
src_view = dict_views_with_filters[selected_src_view]

filters = sorted([doc_from.GetElement(f_id) for f_id in src_view.GetFilters()])

selected_filters = forms.SelectFromList.show(filters,
                                            title='Select source filters',
                                            multiselect=True,
                                            button_name='Select filter',
											name_attr = "Name")
if not selected_filters:
	script.exit()

# Select the destination views
dest_views = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
dict_dest_views = {v.Name:v for v in dest_views}

selected_dest_view = forms.SelectFromList.show(sorted(dict_dest_views),
                                            title='Select the destination view/viewtemplates',
                                            multiselect=True,
                                            button_name='Select destination View/ViewTemplate')

selected_dest_views = [dict_dest_views[v] for v in selected_dest_view]

# Copy the filters to another project

transform = DB.Transform.Identity
opts = DB.CopyPasteOptions()

ids = [e.Id for e in selected_filters]
ids_copy = List[DB.ElementId](ids)

print(ids_copy)
with revit.Transaction('Copy filters'):
	DB.ElementTransformUtils.CopyElements(doc_from,ids_copy,doc,transform,opts)

for view_filter in selected_filters:
	filter_overrides = src_view.GetFilterOverrides(view_filter.Id)
	for view in selected_dest_views:
		view.SetFilterOverrides(view_filter.Id, filter_overrides)

I found the solution. :blush: :blush:
The exception was raised because the copied filter had another elementId, so when it had to apply the graphics from the filter from the source project, it could find the same filter in the destination project.

So you just modified the last few lines to reflect the new element id of the filter in the target project?