Filtering level using it's name - Python

Hi All,
I am trying to filter out levels based on their name.
For example I have 3 levels ‘Level 1’, ‘Level 2’ and ‘Level 3’ and I want to filter out ‘Level 1’ and get only Level 2 and Level 3. The overall idea is to finally get all the furniture from Level 2 and Level 3 only.

But the following code still gives me all 3 levels. Can someone point me in the right direction or point out the mistake?

import Autodesk.Revit.DB as DB
import Autodesk.Revit.UI as UI
import clr
doc = revit.ActiveUIDocument.Document
uidoc = revit.ActiveUIDocument
levelprovider = DB.ParameterValueProvider(DB.ElementId(DB.BuiltInParameter.LEVEL_NAME))
levelname = 'Level 1'
eval = DB.FilterStringEquals()
level_rule = DB.FilterStringRule(levelprovider, eval,levelname, False)
level_filter = DB.ElementParameterFilter(level_rule, True)
levels = DB.FilteredElementCollector(doc).OfCategory(DB.BuiltInCategory.OST_Levels).WhereElementIsNotElementType().WherePasses(level_filter).ToElements()
for item in levels:
print(item.Name)

You are looping, but with no logic to filter the levels you need. After the FilteredElementCollector you could write…

levels = [l for l in levels if not l.Name == "Level 01"]

Or in longhand…

myLevels = []

for l in levels:
    if not l.Name == "Level 01":
        myLevels.append(l)

This is general python functionality which you can find anywhere, not just on this forum.

I know about that list functionality, but this will return a List not a filtered element collector. It will probably lose all the methods and properties of FilteredElementCollector.

So I had to rewrite your entire script because the imports weren’t making sense/not working at all for me but I ran into the same problem you had, where the list shouldn’t include the level with the name used in the FilterStringEquals().

However, it did work when I changed it to use elevation and FilterNumericEquals(), so it makes me believe there is something we cannot see about the string or name variable.

2 Likes

I tried it and Elev works well. But I wan’t to filter it by level name. It is quite possible the elevation of level might change, but the name will remain constant in my case. Also, if it works with level then it might work with the following, where I want o get furniture from just 2 filtered levels:

furn = DB.FilteredElementCollector(doc).WhereElementIsNotElementType().OfCategory(DB.BuiltInCategory.OST_Furniture).WherePasses(level_filter).ToElements()