Hi,
Is there any way to modify existing filter used in Revit schedule ?
I have created small dynamo script. But it is adding new filter instead of updating existing filter.
Thanks.
Hi,
Is there any way to modify existing filter used in Revit schedule ?
I have created small dynamo script. But it is adding new filter instead of updating existing filter.
Thanks.
Easier to remove existing filter and add a replacement.
Right, that is the last option.
If youâre set on modifying an existing filter then youâd need to go through the API and make all the changes there.
ScheduleFilter Members (revitapidocs.com)
Hi,
Yes, itâs possible to update an existing schedule filter using Dynamo with a Python script â especially when the filter condition is set to âEqualsâ.
Iâve used a Python approach where the inputs are:
This script identifies the matching filter in the schedule and replaces the filter value, rather than adding a new filter. It works well when the condition is set to Equals.
Here is the Python code
import clr
clr.AddReference(âRevitAPIâ)
clr.AddReference(âRevitServicesâ)
from Autodesk.Revit.DB import *
from RevitServices.Persistence import DocumentManager
scheduleNames = IN[0] # List of strings (schedule names)
filterValues = IN[1] # List of strings or numbers (new filter values)
doc = DocumentManager.Instance.CurrentDBDocument
output =
if not isinstance(scheduleNames, list) or not isinstance(filterValues, list):
output.append(âError: Inputs must be lists of schedule names and filter values.â)
elif len(scheduleNames) != len(filterValues):
output.append(âError: Schedule names and filter values lists must have the same length.â)
else:
# Wrap in a transaction
transaction = Transaction(doc, âUpdateBatchScheduleFiltersâ)
transaction.Start()
try:
# Process each schedule and filter value pair
for idx, (scheduleName, newFilterValue) in enumerate(zip(scheduleNames, filterValues)):
output.append(f"Processing schedule {idx + 1}/{len(scheduleNames)}: '{scheduleName}'")
# Find the schedule by name
schedules = FilteredElementCollector(doc).OfClass(ViewSchedule).ToElements()
targetSchedule = None
for schedule in schedules:
if schedule.Name == scheduleName:
targetSchedule = schedule
output.append(f" Debug: Found schedule '{scheduleName}', ID='{schedule.Id.IntegerValue}'")
break
if targetSchedule is None:
output.append(f" Schedule '{scheduleName}' not found.")
continue
# Get the schedule definition
scheduleDefinition = targetSchedule.Definition
# Debug: List all fields in the schedule
output.append(" Debug: Schedule fields:")
for param in scheduleDefinition.GetFieldOrder():
field = scheduleDefinition.GetField(param)
output.append(f" Field: '{field.GetName()}', FieldId='{field.FieldId.IntegerValue}'")
# Get all filters in the schedule
filters = scheduleDefinition.GetFilters()
# Debug: List all filters and their field names
output.append(f" Debug: Found {len(filters)} filters in schedule.")
for i in range(len(filters)):
schedFilter = scheduleDefinition.GetFilter(i)
field = scheduleDefinition.GetField(schedFilter.FieldId)
fieldName = field.GetName() if field is not None else "Unknown Field"
output.append(f" Filter {i}: Field='{fieldName}', Type='{str(schedFilter.FilterType)}', FieldId='{schedFilter.FieldId.IntegerValue}'")
# Find the filter for BIMSF_Id
bimSFIdParamId = None
for param in scheduleDefinition.GetFieldOrder():
field = scheduleDefinition.GetField(param)
if field.GetName() == "BIMSF_Id":
bimSFIdParamId = field.FieldId
output.append(f" Debug: Found BIMSF_Id field with FieldId='{bimSFIdParamId.IntegerValue}'")
break
if bimSFIdParamId is None:
output.append(f" Parameter 'BIMSF_Id' not found in schedule '{scheduleName}'.")
continue
# Look for the filter using BIMSF_Id
filterFound = False
for i in range(len(filters)):
schedFilter = scheduleDefinition.GetFilter(i)
output.append(f" Debug: Comparing Filter {i} FieldId='{schedFilter.FieldId.IntegerValue}' with BIMSF_Id FieldId='{bimSFIdParamId.IntegerValue}'")
if schedFilter.FieldId.IntegerValue == bimSFIdParamId.IntegerValue:
output.append(f" Debug: Filter type for 'BIMSF_Id' is '{schedFilter.FilterType}' (Expected: '2' for Equals)")
if schedFilter.FilterType != 2: # ScheduleFilterType.Equals = 2
output.append(f" Filter for 'BIMSF_Id' is not an 'Equals' filter in schedule '{scheduleName}'. Current type: {schedFilter.FilterType}.")
continue
# Assume BIMSF_Id is a string (modify to int(newFilterValue) or float(newFilterValue) if different)
try:
value = str(newFilterValue) # Convert to string
schedFilter.SetValue(value)
scheduleDefinition.SetFilter(i, schedFilter)
filterFound = True
output.append(f" Filter for 'BIMSF_Id' updated to '{newFilterValue}' in schedule '{scheduleName}'.")
break
except ValueError:
output.append(f" Invalid filter value '{newFilterValue}' for 'BIMSF_Id' in schedule '{scheduleName}'.")
break
if not filterFound:
output.append(f" No filter found for 'BIMSF_Id' in schedule '{scheduleName}'.")
transaction.Commit()
except Exception as e:
transaction.RollBack()
output.append(f"Error: {str(e)}")
OUT = output