Workset filter rule

Hi, I’m managing worksets on or off through a filter applied to all categories. However after the filters applied to all views. When you go to check the filters added. Revit crashes. Also if I create the filter in dynamo and add it manually to a view crashes. I think Its how I’m getting the workset parameter?

How are you getting the workset parameter? What categories are you applying it to? Can you do the whole thing manually in Revit without crashing?

Also, you probably want to filter your views. You don’t want that filter for all views and templates in the whole project do you? At the very least you might have some 3D view templates giving you nulls.

Hello! Searching for any element with parameter workset. In this case it grabbed a phase.

It think I need to create a node that applies it using builtin workset but I dont quite understand that. I got a Autodesk.RevitDB.FilterStringRule not Revit.Filter.FilterRule
param_id = ElementId(BuiltInParameter.ELEM_PARTITION_PARAM)

Applying to all categories

Yup manually all good

Want to add to all views and templates.

Ok this takes a list of strings and adds the fitlers I want like shown above. But Revit dies when adding the filter to the view…

import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")

from Autodesk.Revit.DB import (
    BuiltInParameter, ElementId, ParameterFilterRuleFactory,
    ElementParameterFilter, LogicalOrFilter, ParameterFilterElement,
    Transaction, ElementFilter
)
from RevitServices.Persistence import DocumentManager
from System.Collections.Generic import List

doc = DocumentManager.Instance.CurrentDBDocument

# IN[0]: List of string values for "Workset Contains" rules, e.g. ["WorksetA", "WorksetB"]
substrings = IN[0]

# Create a list of ElementParameterFilter objects (each wraps a FilterRule)
epFilters = List[ElementParameterFilter]()
worksetParamId = ElementId(BuiltInParameter.ELEM_PARTITION_PARAM)
for s in substrings:
    rule = ParameterFilterRuleFactory.CreateContainsRule(worksetParamId, s, False)
    epf = ElementParameterFilter(rule)
    epFilters.Add(epf)

# Combine the individual filters using LogicalOrFilter.
# LogicalOrFilter constructor accepts an IList<ElementFilter>
if epFilters.Count == 0:
    compositeFilter = None
elif epFilters.Count == 1:
    compositeFilter = epFilters[0]
else:
    filtersList = List[ElementFilter]()
    for f in epFilters:
        filtersList.Add(f)
    compositeFilter = LogicalOrFilter(filtersList)

# Gather all category ElementIds from the document.
catIds = List[ElementId]()
for cat in doc.Settings.Categories:
    catIds.Add(cat.Id)

# Create a ParameterFilterElement that applies the composite filter to all categories.
t = Transaction(doc, "Create Workset Contains Composite Filter")
t.Start()
pfElement = None
if compositeFilter:
    pfElement = ParameterFilterElement.Create(doc, "Workset Contains Composite Filter", catIds, compositeFilter)
t.Commit()

OUT = pfElement


This seems to work only adding categories with worksets or supports filters. AI just working it all for me :grin:

import clr
clr.AddReference("RevitAPI")
clr.AddReference("RevitServices")

from Autodesk.Revit.DB import (
    BuiltInParameter, ElementId, ParameterFilterRuleFactory,
    ElementParameterFilter, LogicalOrFilter, ParameterFilterElement,
    Transaction, ElementFilter, FilterableValueProvider, 
    BuiltInCategory, Category, FilteredElementCollector,
    SharedParameterElement
)
from RevitServices.Persistence import DocumentManager
from System.Collections.Generic import List

def get_valid_categories(doc):
    """Get only categories that support filters"""
    valid_cats = List[ElementId]()
    for cat in doc.Settings.Categories:
        # Check if category can be filtered
        if (cat.AllowsBoundParameters and 
            cat.CanAddSubcategory and 
            not cat.IsTagCategory):
            valid_cats.Add(cat.Id)
    return valid_cats

def create_workset_filter(doc, substrings, filter_name="Workset Contains Filter"):
    """Creates a workset filter safely with error handling"""
    # Input validation
    if not isinstance(substrings, list):
        substrings = [substrings]  # Convert single input to list
    
    if not substrings or len(substrings) == 0:
        return None
        
    # Create filter rules
    epFilters = List[ElementParameterFilter]()
    worksetParamId = ElementId(BuiltInParameter.ELEM_PARTITION_PARAM)
    
    for s in substrings:
        if s and len(str(s).strip()) > 0:  # Convert to string and check if empty
            try:
                # Create rule directly without provider
                rule = ParameterFilterRuleFactory.CreateContainsRule(
                    worksetParamId, 
                    str(s).strip(), 
                    False
                )
                epf = ElementParameterFilter(rule)
                epFilters.Add(epf)
            except Exception as e:
                print(f"Failed to create rule for '{s}': {str(e)}")
                continue
    
    # Create composite filter
    if epFilters.Count == 0:
        return None
    elif epFilters.Count == 1:
        compositeFilter = epFilters[0]
    else:
        filtersList = List[ElementFilter]()
        for f in epFilters:
            filtersList.Add(f)
        compositeFilter = LogicalOrFilter(filtersList)
    
    # Get valid categories
    catIds = get_valid_categories(doc)
    
    if catIds.Count == 0:
        print("No valid categories found for filtering")
        return None
    
    # Create the filter element
    t = None
    try:
        t = Transaction(doc, "Create Workset Filter")
        t.Start()
        
        # Delete existing filter with same name if it exists
        collector = FilteredElementCollector(doc)
        existing_filters = collector.OfClass(ParameterFilterElement)
        for ef in existing_filters:
            if ef.Name == filter_name:
                doc.Delete(ef.Id)
                
        pfElement = ParameterFilterElement.Create(
            doc, 
            filter_name,
            catIds, 
            compositeFilter
        )
        t.Commit()
        return pfElement
        
    except Exception as e:
        if t and t.HasStarted():
            t.RollBack()
        print(f"Failed to create filter: {str(e)}")
        return None

# Usage
doc = DocumentManager.Instance.CurrentDBDocument
filter_element = create_workset_filter(doc, IN[0])
OUT = filter_element