Jun 23, 2024

How To Purge View Filters with pyRevit

Learn how to purge View Filters in your Revit project with pyRevit.

Purge View Filterswith EF-Tools

Before we dive into the code, I want you to know that you can use this tool in EF-Tools. You can even inspect the code by holding ALT and clicking on the button to open the location of the source code.

👀But Now let's look at the code.

Brainstorming

For this tool we need to get all unused View Filters and ask the user which ones to purge.

Here are the steps we will go through:

  1. Get All Views and Filters

  2. Find Used View Filters (iterate through views)

  3. Find all Unused View Filters(set_A - set_B)

  4. Ask User Which ones to Delete (pyrevit.forms)

  5. Purge View Filters

Get Views and Filters

Firstly, get all you View Filters and Views+ViewTemplates.

Also keep in mind that Parameter filters and Selection filters have different classes. You can use FilterElement class to get them both together. But for my example, I will only get ParameterFilterElements.

# 1️⃣ Get Views and Filters
# all_filter_ids     = FilteredElementCollector(doc).OfClass(FilterElement).ToElementIds() #Parameter + Selection
# all_sel_filter_ids = FilteredElementCollector(doc).OfClass(SelectionFilterElement).ToElementIds()
all_param_filter_ids = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElementIds()
all_views_and_vt     = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()

Find Used View FIlters

Now, let's iterate through all views and view templates and see what kind of filters they have with GetFilters. Create a set or a list of unique ViewFilter Ids.

Here is the code:

#2️⃣ Find Used ViewFilters
used_filter_ids = []

for view in all_views_and_vt:
    view_filter_ids = view.GetFilters()

    for view_filter_id in view_filter_ids:
        if view_filter_id not in used_filter_ids:
            used_filter_ids.append(view_filter_id)

Find Unused View Filters

Now we can get unused view filters by substracting a set of used_filters from a set of all_filters.

💡Also, it's a good idea to ensure you have unused filters in the project.

#3️⃣ Get Unused ViewFilters
unused_filter_ids = set(all_param_filter_ids) - set(used_filter_ids)
unused_filters    = [doc.GetElement(f_id) for f_id in unused_filter_ids]

#✅ Check if Unused Filters in Project
if not unused_filters:
    forms.alert('There are no Unused View Filters in the project. Please try again',title=__title__, exitscript=True)

Select View Filters To Purge

Now we need to create a UI form for user to select View Filters. Using pyrevit.forms.SelectFromList is the simplest and quickest way to do that. Also ensure that user has selected something to avoid errors later in the code.

Here is the code:

#👉 Select View Filters to Delete
filters_to_del = forms.SelectFromList.show(unused_filters,
                                multiselect=True,
                                name_attr='Name',
                                button_name='Select Unused View Filters To Delete.')


#✅ Check Selection
if not filters_to_del:
    forms.alert('No Unused View Filters were selected. Please try again',title=__title__, exitscript=True)

Purge View Filters

Lastly, let's delete all desired View Filters by using doc.Delete.

💡Also it's a good idea to use try/except statements here, in case someone has the rights on view filters.

with Transaction(doc, 'Purge Unused ViewFilters') as t:
    t.Start()  #🔓

    for fil in filters_to_del:
        try:
            f_name = fil.Name
            doc.Delete(fil.Id)
            print('✔️ Deleted ViewFilter: {}'.format(f_name))
        except Exception as e:
            print("✖️ Couldn't Delete View Filter: {}".format(f_name))
            print('----- Error Message: {}'.format(e))

    t.Commit() #🔒

✨Full Code

Here is the final code together to avoid any confusion.

# -*- coding: utf-8 -*-
__title__ = "5 - Purge Unused View Filters"
__doc__ = """Version = 1.0
Date    = 24.06.2024
_____________________________________________________________________
Description:
Purge Unused View Filters from your Revit Project.
_____________________________________________________________________
How-To:
- Click the Button
- Select unused View Filters to purge
_____________________________________________________________________
Last update:
- [24.06.2024] - V1.0 RELEASE
_____________________________________________________________________
Author: Erik Frits from LearnRevitAPI.com"""

# ⬇️IMPORTS
# ==================================================
from Autodesk.Revit.DB import *

# pyRevit
from pyrevit import forms

# 📦VARIABLES
# ==================================================
doc    = __revit__.ActiveUIDocument.Document
uidoc  = __revit__.ActiveUIDocument

#🎯 MAIN
# ==================================================
# 1️⃣ Get Views and Filters
# all_filter_ids     = FilteredElementCollector(doc).OfClass(FilterElement).ToElementIds() #Parameter + Selection
# all_sel_filter_ids = FilteredElementCollector(doc).OfClass(SelectionFilterElement).ToElementIds()
all_param_filter_ids = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElementIds()
all_views_and_vt     = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()


#2️⃣ Find Used ViewFilters
used_filter_ids = []

for view in all_views_and_vt:
    view_filter_ids = view.GetFilters()

    for view_filter_id in view_filter_ids:
        if view_filter_id not in used_filter_ids:
            used_filter_ids.append(view_filter_id)

#3️⃣ Get Unused ViewFilters
unused_filter_ids = set(all_param_filter_ids) - set(used_filter_ids)
unused_filters    = [doc.GetElement(f_id) for f_id in unused_filter_ids]

#✅ Check if Unused Filters in Project
if not unused_filters:
    forms.alert('There are no Unused View Filters in the project. Please try again',title=__title__, exitscript=True)

#👉 Select View Filters to Delete
filters_to_del = forms.SelectFromList.show(unused_filters,
                                multiselect=True,
                                name_attr='Name',
                                button_name='Select Unused View Filters To Delete.')


#✅ Check Selection
if not filters_to_del:
    forms.alert('No Unused View Filters were selected. Please try again',title=__title__, exitscript=True)


with Transaction(doc, 'Purge Unused ViewFilters') as t:
    t.Start()  #🔓

    for fil in filters_to_del:
        try:
            f_name = fil.Name
            doc.Delete(fil.Id)
            print('✔️ Deleted ViewFilter: {}'.format(f_name))
        except Exception as e:
            print("✖️ Couldn't Delete View Filter: {}".format(f_name))
            print('----- Error Message: {}'.format(e))

    t.Commit() #🔒

Join Newsletter

📩 You will be added to Revit API Newsletter

Join Us!

which is already read by 7400+ people!

Ready to become Revit Hero for your office? Learn Revit API!

Join this comprehensive course that will guide you step by step on how to create your dream tools for Revit that save time.