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:
Get All Views and Filters
Find Used View Filters (iterate through views)
Find all Unused View Filters(set_A - set_B)
Ask User Which ones to Delete (pyrevit.forms)
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.
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:
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.
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]
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:
filters_to_del = forms.SelectFromList.show(unused_filters,
multiselect=True,
name_attr='Name',
button_name='Select Unused View Filters To Delete.')
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.
__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"""
from Autodesk.Revit.DB import *
from pyrevit import forms
doc = __revit__.ActiveUIDocument.Document
uidoc = __revit__.ActiveUIDocument
all_param_filter_ids = FilteredElementCollector(doc).OfClass(ParameterFilterElement).ToElementIds()
all_views_and_vt = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Views).WhereElementIsNotElementType().ToElements()
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)
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]
if not unused_filters:
forms.alert('There are no Unused View Filters in the project. Please try again',title=__title__, exitscript=True)
filters_to_del = forms.SelectFromList.show(unused_filters,
multiselect=True,
name_attr='Name',
button_name='Select Unused View Filters To Delete.')
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()