Hi, I am working on a routine for my plumbing department that would allow the users to make sure worksets are correct based on the piping system that has been applied to the element. This is set up with a form that allows the user to select the workset and the piping system Name. I have verified that the form is reading the correct information for both the system and the workset and that the applying the workset is working correctly. My problem is the filtering the piping elements based on the system. I have tried filtering with the filteredelementcollector and using an if statement to filter and neither has been working. Any help would be greatly appreciated.
List<Element> elements = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_PipeCurves).Where(a=>a.LookupParameter("System Type").AsString()==system).ToList(); if (elements == null) return; using (Transaction tx = new Transaction(doc, "Change Workset")) { tx.Start(); foreach (Element e in elements) { try { Parameter wsparam = e.get_Parameter(BuiltInParameter.ELEM_PARTITION_PARAM); //set workset to Shared Levels and Grids wsparam.Set(worksetid); } catch (Exception) { } } tx.Commit(); }
Solved! Go to Solution.
Solved by will.wydock. Go to Solution.
Dear William,
Thank you for your query.
Calling LookupParameter is not recommended if you can avoid it, since it might return the wrong parameter, if more than one are defined with the same display name.
Are you sure there is just one parameter on each element with a display name equalling "System Type"?
A better way to retrieve that parameter would be to use a built-in parameter enumeration value. That would make it uniquely identifiable.
Furthermore, I wonder about the AsString accessor. I would have expected the underlying system type parameter value to be an ElementId, not a string.
In that case, it would be more reliable to compare the element id and not the system type name.
Can you provide a minimal reproducible case to explore, containing just a handful of pipes and a very few systems, and a macro or complete add-in project demonstrating how you try to retrieve the pipes belonging to a specific system, and the expected results?
https://thebuildingcoder.typepad.com/blog/about-the-author.html#1b
Thank you!
I hope this helps.
Best regards,
Jeremy
Here is a rather illuminating discussion by The Building Coder that throws some light on pipe system types as well:
https://thebuildingcoder.typepad.com/blog/2014/01/final-rolling-offset-using-pipecreate.html
I have attached the macro that I was working this out in. I had tried using get_Parameter with the builtin parameter and was getting the same results.
According to RevitLookup asvaluestring should work with this
For testing purpose i was using the rme_advanced sample project.rvt from the sample project as my testing ground with just making it worksharing and adding some pipe worksets.
It would probably take me half an hour at least to figure out how to "just make it worksharing and addisome pipe worksets"... so could you share that as well, please? Remember, I am not a Revit user. Thank you!
I was able to get this to work using the ElementParameterFilter
//FilteredElementCollector created FilteredElementCollector fec = new FilteredElementCollector(doc); //Identify the parameter to be filtered by ParameterValueProvider pvp = new ParameterValueProvider(new ElementId(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM)); //set string evaluator so that it equals strig FilterStringRuleEvaluator fsre = new FilterStringEquals(); //Create a filter rule were string value equals SystemName FilterRule fr = new FilterStringRule(pvp, fsre, SystemName, true); //Create Filter ElementParameterFilter epf = new ElementParameterFilter(fr); //Apply filter to Filteredelementcollector fec = fec.WherePasses(epf);
That looks like exactly what I was hoping for!
Well done!
Thank you very much indeed!
I added it to The Building Coder samples for posterity:
Cheers,
Jeremy