Copy View Filters between Views

It's very easy to copy view filters between your views.

You just get filters, read their overrides and settings and set the same to new views. However, keep in mind that the simplest step can actually be one of the trickiest ones if you don't pay attention.

Let me show you what I mean.

1 - Get Views

Firstly, let's get some views.

I will keep it simple and get views by name from a collection. And this can be a tricky step. Keep in mind that you might need to filter a few things out to get the right views. I will do the following:

  • Filter Views by ViewType (because we can have same view names across different types)

  • Filter ViewTemplates out.

  • * You could also filter views without View Filters if you want users to select view_from

I will keep it simple for this lesson and use a collector to get views and then match them with view names I need.

# 1️⃣ Get Views From/To
def get_view_by_name(view_name, view_type = ViewType.FloorPlan):
    """Get Views by exact Name."""
    views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
    views = [v for v in views if v.ViewType == view_type]   # Filter by ViewType
    views = [v for v in views if not v.IsTemplate]          # Filter ViewTemplates

    dict_views = {view.Name: view for view in views}

    if view_name not in dict_views:
        print('Could not find view by name: {}'.format(view_name))
    else:
        return dict_views[view_name]


view_from = get_view_by_name('Level 0', ViewType.FloorPlan)  # type: View
view_to   = get_view_by_name('Level 1', ViewType.FloorPlan)  # type: View

💡You can make it more efficient by keeping collector outside, but I keep it simple for tutorial.

2 - Get View Filters

Once we have the view, we need to select some filters.

I don't always want to copy all available filters, so we will use a simple pyrevit.form - SelectFromList, so user can decide what they want to copy.

Here is the code snippet:

#2️⃣ Get and Select View Filters
filter_ids = view_from.GetOrderedFilters()
filters    = [doc.GetElement(f_id) for f_id in filter_ids]

sel_filters = forms.SelectFromList.show(filters,
                                 multiselect=True,
                                 name_attr='Name',
                                 button_name='Select View Filters')

#✅ Ensure Selected Filters
if not sel_filters:
    forms.alert("No View Filters were Selected.\n"
                "Please Try Again.", exitscript=True)
  • GetOrderedFilters()

  • Convert ElementIds to Filters

  • Create SelectFromList form

  • Ensure Filters selected

3 - Copy View Filters

Alright, it's time to do the magic.

To copy filters from view A to B we will need to read a few settings so we can set the same overrides and visibility controls.

Here is the code snippets for that:

#3️⃣ Copy View Filters
with Transaction(doc, 'Copy ViewFilters') as t:
    t.Start()

    for view_filter in filters:

        #🅰️ Copy Filter Overrides
        overrides = view_from.GetFilterOverrides(view_filter.Id)
        view_to.SetFilterOverrides(view_filter.Id, overrides)

        #🅱️ Copy Enable/Visibility Controls
        visibility = view_from.GetFilterVisibility(view_filter.Id)
        enable     = view_from.GetIsFilterEnabled(view_filter.Id)

        view_to.SetFilterVisibility(view_filter.Id, visibility)
        view_to.SetIsFilterEnabled(view_filter.Id, enable)

    t.Commit()

🔓 Use Transaction to make changes

  • For Each Filter:

    • Get Filter Overrides

    • Set Filter Overrides (it will also create it)

    • Get Filter Visibility

    • Get IsFilterEnabled

    • Set these settings to new filter

And that should copy your view filters.

Final Snippet:


#1️⃣ Get Views From/To
def get_view_by_name(view_name):
    """Get Views by exact Name."""
    views = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
    dict_views = {view.Name:view for view in views}  

    if view_name not in dict_views:
        print('Could not find view by name: {}'.format(view_name))
    else:
        return dict_views[view_name]

  

view_from  = get_view_by_name('HG_UG 1_OK FFB')         #type: View
view_to    = get_view_by_name('HG_UG 1_OK FFB Copy 1')  #type: View

#2️⃣ Get and Select View Filters
filter_ids = view_from.GetOrderedFilters()
filters    = [doc.GetElement(f_id) for f_id in filter_ids]

sel_filters = forms.SelectFromList.show(filters,
                                 multiselect=True,
                                 name_attr='Name',
                                 button_name='Select View Filters')

#✅ Ensure Selected Filters
if not sel_filters:
    forms.alert("No View Filters were Selected.\n"
                "Please Try Again.", exitscript=True)

#3️⃣ Copy View Filters
with Transaction(doc, 'Copy ViewFilters') as t:
    t.Start()

    for view_filter in filters:

        #🅰️ Copy Filter Overrides
        overrides = view_from.GetFilterOverrides(view_filter.Id)
        view_to.SetFilterOverrides(view_filter.Id, overrides)

        #🅱️ Copy Enable/Visibility Controls
        visibility = view_from.GetFilterVisibility(view_filter.Id)
        enable     = view_from.GetIsFilterEnabled(view_filter.Id)

        view_to.SetFilterVisibility(view_filter.Id, visibility)
        view_to.SetIsFilterEnabled(view_filter.Id, enable)

    t.Commit()

⌨️ Happy Coding!
Erik Frits