Filter elements in which a parameter exists

Im trying to create a filter that collects all element that own a shared parameter.
I have managed to find all elements that have this parameter (i passed an id) by only because im comparing its contents. So basically if value of parameter = something. (i found an example online)

import clr
# Adding the RevitServices.dll special Dynamo module to deal with Revit
clr.AddReference('RevitServices')
import RevitServices  # Importing RevitServices
# From RevitServices import the Document Manager
from RevitServices.Persistence import DocumentManager
# Adding the RevitAPI.dll module to access the Revit API
clr.AddReference('RevitAPI')
import Autodesk  # Here we import the Autodesk namespace
# From the Autodesk namespace - derived down to the Revit Database
# we import only the required classes
from Autodesk.Revit.DB import \
FilteredElementCollector, BuiltInParameter, \
ParameterValueProvider, ElementId, FilterStringBeginsWith, \
FilterStringContains, FilterStringEndsWith, FilterStringEquals, \
FilterStringGreater, FilterStringGreaterOrEqual, FilterStringLess, \
FilterStringLessOrEqual, FilterStringRule, ElementParameterFilter
# to import all classes use the wildcard '*'
# this will marginally slow down dynamo/python and may cause errors if
# multiple classes are identically named
# from Autodesk.Revit.DB import *

sharedparam=UnwrapElement(IN[0])

doc = DocumentManager.Instance.CurrentDBDocument

fec = FilteredElementCollector

provider = ParameterValueProvider(sharedparam.Id)

# this is for testing
evalBegins = FilterStringBeginsWith()
evalCon = FilterStringContains()
evalEnds = FilterStringEndsWith()
evalEq = FilterStringEquals()
evalGreat = FilterStringGreater()
evalGoEq = FilterStringGreaterOrEqual()
evalLess = FilterStringLess()
evalLoEq = FilterStringLessOrEqual()

#contains
evaluator = evalCon
# string that it is testing agianst
test = 'New'

caseSensitive = False

rule = FilterStringRule(provider, evaluator, test, caseSensitive)

filter = ElementParameterFilter(rule)

items = fec(doc).WherePasses(filter).ToElements()


OUT = items

So how would i do this to check if the parameter (string) is not emtpy?
Or is there a way to construct the rule so it just check for existance of parameters?

so far what i found are Double,Numer,Integer,Boolean and String rules, but non of them have a check to see if the parameter is emtpy (no value) or has any value.

1 Like

1 Like

I’m a little confused on exactly what you’re trying to filter. You mention both a non-empty value or the existence of the parameter. Which one do you want?

If you just want the existence of the parameter then checking for the parameter ID should be it. If you just want instances where the parameter has a value then you can use something like param.AsValueString() != "".

Hello
a solution using SharedParameterApplicableRule

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *

clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *

clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
doc = DocumentManager.Instance.CurrentDBDocument


fRule = SharedParameterApplicableRule("nameOfSharedParameter")
filter = ElementParameterFilter(fRule)
fec = FilteredElementCollector(doc).WherePasses(filter).ToElements()
OUT = fec
5 Likes

Ultimately I want to get all elements that just have that parameter.
I didn’t know how to achieve this so I tried to at least get the collector to fetch me all the parameters with some value (To learn how this filter collector works).
My goal is to get all the elements that have that parameter from the collector, without doing any preselection first.

That worked like a charm, thanks alot :smiley:
Im looking at the doc for this class
https://www.revitapidocs.com/2015/64d80468-27ac-8acb-25f1-48bc3597ab87.htm

I cant really connect the dots. How did you figure out you need this one?

What would you do if you wanted to collect for just Project parameter instead of Shared?
I dont see anything like that in here
image

I think the best way is to filter the collection after the constructor

1 Like