Retrieving Workset Name Property from RuleBased Filter

Retrieving Workset Name Property from RuleBased Filter

jagostinho74
Collaborator Collaborator
899 Views
6 Replies
Message 1 of 7

Retrieving Workset Name Property from RuleBased Filter

jagostinho74
Collaborator
Collaborator

Hello.

 

I was attempting to retrieve the Workset name property that was used in a RuleBased filter to find that it is using the FilterIntegerRule Class and returning a RuleValue of 0. This is, sadly, not the WorksetId which I could use to access the Workset and get its name.

 

Is this intended behaviour?

Any ideas on how can I access the Workset name property used in the RuleBased filter?

 

Thank you in advance.

 

jagostinhoCT_0-1685548155630.png

 

jagostinhoCT_1-1685548280536.png

 

Assistant BIM/CAD Manager

Manchester, UK


0 Likes
Accepted solutions (1)
900 Views
6 Replies
Replies (6)
Message 2 of 7

RPTHOMAS108
Mentor
Mentor
Accepted solution

You may be wrong with the assumption 0 isn't Workset1, since Workset1 is perhaps the first such created upon activating work sharing:

 

Workset1, 0

Cost Report Settings, 1
Area and Volume Computations, 2
Schedule Keys, 3
Project Info, 4
Render Settings, 5......

 

Shared Levels and Grids, 182...

 

Family : Planting : Planting_RPC_Tree_Deciduous, 325
Family : Windows : Windows_Sgl_Plain, 326
Family : Detail Items : Detail_Items_Suspended_Ceiling_Tile_Sec, 327
Family : Structural Framing : UB-Universal Beams, 328
Family : Structural Columns : UC-Universal Columns-Column, 329
Family : Title Blocks : Title_Blocks_A1_Metric, 330

 

 Private Function Obj_230531(ByVal commandData As Autodesk.Revit.UI.ExternalCommandData,
ByRef message As String, ByVal elements As Autodesk.Revit.DB.ElementSet) As Result
        Dim UIApp As UIApplication = commandData.Application
        Dim UIDoc As UIDocument = commandData.Application.ActiveUIDocument
        If UIDoc Is Nothing Then Return Result.Cancelled Else
        Dim IntDoc As Document = UIDoc.Document

        Dim WSF As New WorksetKindFilter(WorksetKind.ViewWorkset, True)
        Dim FEC As New FilteredWorksetCollector(IntDoc)
        Dim WS_Lst As List(Of Workset) = FEC.WherePasses(WSF).ToWorksets

        For i = 0 To WS_Lst.Count - 1
            Dim WS As Workset = WS_Lst(i)
            Dim NM As String = WS.Name
            Dim Id As Integer = WS.Id.IntegerValue

            Debug.WriteLine($"{NM}, {Id}")
        Next
        Return Result.Succeeded
    End Function

 

 

Message 3 of 7

jagostinho74
Collaborator
Collaborator

you are correct! Thank you for looking into it.

the integer does represent the worksetId. I was able to retrieve it after converting it into a WorksetId Object.

 

But this now make me think about in which other cases other types of elements might be using the FilterIntegerRule differently? and how can I process these in a method that is returning the rule values as strings. Method below.

private string GetFilterRuleValue(FilterRule rule)
		{
			Document doc = this.ActiveUIDocument.Document;
			
			string valueRule = "";
			
			const double feetToMMConverter = 304.8;
			
			if (rule is FilterStringRule)
			{
				FilterStringRule stringRule = rule as FilterStringRule;
				valueRule = stringRule.RuleString;
			}
			else if (rule is FilterNumericValueRule)
			{
				if(rule is FilterDoubleRule)
				{
					FilterDoubleRule doubleRule = rule as FilterDoubleRule;
					double valueInFeet = doubleRule.RuleValue;
					double valueInMM = valueInFeet * feetToMMConverter;
					valueRule = valueInMM.ToString("F2");
				}
				
				else if(rule is FilterElementIdRule)
				{
					FilterElementIdRule eleIdRule = rule as FilterElementIdRule;
					ElementId id = eleIdRule.RuleValue;
					Element element = doc.GetElement(id);
					valueRule = element.Name;
				}
				else if(rule is FilterIntegerRule)
				{
					FilterIntegerRule integerRule = rule as FilterIntegerRule;
					int integerWorksetId = integerRule.RuleValue;
					WorksetId worksetId = new WorksetId(integerWorksetId);
					WorksetTable worksetTable = doc.GetWorksetTable();
					Workset workset = worksetTable.GetWorkset(worksetId);
					valueRule = workset.Name;
				}
			}
			return valueRule;
Assistant BIM/CAD Manager

Manchester, UK


0 Likes
Message 4 of 7

RPTHOMAS108
Mentor
Mentor

That is a tricky one, Yes/No for sure will use it but then there are the built-in parameters with predefined drop down lists that also use it via enum values

0 Likes
Message 5 of 7

jagostinho74
Collaborator
Collaborator

was also trying to start by filtering it when the GetRuleParameter is <null> but that is not working.

It reads <null> in RevitLookUp but it is actually returning some numbers when I use this code.

 

And because it is not <null> it ends up returning the Integer and I never get to extract the workset name using it.

 

else if(rule is FilterIntegerRule)
				{
					FilterIntegerRule integerRule = rule as FilterIntegerRule;
					
					if(rule.GetRuleParameter() == null)
					{
						TaskDialog.Show("getRuleParameter",rule.GetRuleParameter().ToString());
						//working on the assumption that the RuleParameter is null when the integer is representing a WorksetId
						int integerWorksetId = integerRule.RuleValue;
						WorksetId worksetId = new WorksetId(integerWorksetId);
						WorksetTable worksetTable = doc.GetWorksetTable();
						Workset workset = worksetTable.GetWorkset(worksetId);
						valueRule = workset.Name;
					}
					else
					{
						TaskDialog.Show("getRuleParameter",rule.GetRuleParameter().ToString());
						valueRule = integerRule.RuleValue.ToString();
					}

 

jagostinhoCT_0-1685615544174.png

jagostinhoCT_1-1685615555295.png

 

Assistant BIM/CAD Manager

Manchester, UK


0 Likes
Message 6 of 7

jagostinho74
Collaborator
Collaborator

ok.

 

So this one seems to do it.

I am getting the .IntegerValue property of the GetRuleParameter method and comparing it with the BIP for Worksets cast as an integer.

 

It is, however, strange that RevitLookUp is showing the value as <null> instead of showing it's natural value.

I am guessing I can use the same approach for the other parameters that use enumerations like you mentioned. Thank you @RPTHOMAS108 .

 

 

else if(rule is FilterIntegerRule)
				{
					FilterIntegerRule integerRule = rule as FilterIntegerRule;

					if(rule.GetRuleParameter().IntegerValue == (int)BuiltInParameter.ELEM_PARTITION_PARAM) //BIP for Workset
					{
						int integerWorksetId = integerRule.RuleValue;
						WorksetId worksetId = new WorksetId(integerWorksetId);
						WorksetTable worksetTable = doc.GetWorksetTable();
						Workset workset = worksetTable.GetWorkset(worksetId);
						valueRule = "Workset - " + workset.Name;
					}
					else
					{
						valueRule = integerRule.RuleValue.ToString();
					}
					
					
				}

 

Assistant BIM/CAD Manager

Manchester, UK


0 Likes
Message 7 of 7

RPTHOMAS108
Mentor
Mentor

There are 207 built-in parameters that can be used in filters that have an integer storage type.

 

I have a feeling that these types of parameters can also be evaluated with FilterStringRuleEvaluator so that may be easier for you (or add an additional complication).

 

When you compare the possible comparisons for a BIP of Integer storage vs a Shared Parameter of Integer storage you can see there are string comparison options available for the former that don't appear in the latter.

 

RevitLookup has certain quirks not sure why it is doing that but I assume FilterIntegerRule would always have a rule parameter (unless it is not set) i.e. the parameter you are checking the value of. A FilterCategoryRule for example doesn't so should return -1 (ElementId.InvalidElementId) for that. So you should be looking for -1 when not set perhaps (that would still equate to BuiltInParameter.Invalid however).

 

If the value returned from GetRuleParameter is -ve then it indicates a BIP otherwise it indicates a parameter element id or shared parameter element id.

 

So you only have to distinguish:

> 0  = ParameterElement

-1 = Invalid (Also a BIP enum value)

< -1 = BIP