FilterIntegerRule and Int64 (long)

FilterIntegerRule and Int64 (long)

martin.leonhartsberger
Participant Participant
483 Views
5 Replies
Message 1 of 6

FilterIntegerRule and Int64 (long)

martin.leonhartsberger
Participant
Participant

Hi everyone, hi @jeremytammik !

 

Currently I am collection Floors where a parameter contains the "element id" of a specific room.

The id is saved in a shared parameter with data type / storage type "Integer".

Filter Integer Rule:

FilterIntegerRule fsr = new FilterIntegerRule(pvp, new FilterNumericEquals(), room.Id.IntegerValue);

Now, while time has passed, the "ElementId.IntegerValue" got deprecated and the replacing method "ElementId.Value" deliveres long instead of int.

But the FilterIntegerRule constructor does not accept long as datatype and I can't find any suitable replacements for the FilterIntegerRule.

 

Any suggestions on how to solve this dilemma?

 

Kindly,

Martin

0 Likes
484 Views
5 Replies
Replies (5)
Message 2 of 6

jeremy_tammik
Alumni
Alumni

The solution is super simple: do not convert the ElementId to an integer for comparison purposes.

 

Use the FilterElementIdRule instead:

  

https://www.revitapidocs.com/2024/4675442b-8c75-4e20-ba18-71df13b86896.htm

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 6

martin.leonhartsberger
Participant
Participant

Thank you for your quick answer.

 

In this case, the rule evaluation fails, because the StorageType of the (shared) parameter ist Integer.

 

martinleonhartsberger_0-1691418657066.png

 

I looked for a way to replace it with another parameter with StorageType ElementId, but could not find the right ForgeTypeId / SpecTypeId.

0 Likes
Message 4 of 6

RPTHOMAS108
Mentor
Mentor

I think the point above still stands 

 

Use FilterElementIdRule not FilterIntegerRule

The constructor for FilterElementIdRule takes FilterNumericRuleEvaluator and the ElementId directly.

 

Specifically for the FilterNumericRuleEvaluator argument use FilterNumericEquals. There is no Int32 or Int64 in any of that. If you want to store a long you can do that and create a new ElementId from it but for filtering use the FilterElementIdRule. Your main issue is you are deciding to store the number not the Id and there may be a reason for this but it is usually a bad idea since it is not updated when the id changes.

 

Also the parameters themselves do not support Int64 anyway do they? No they don't according to below.

 

Unless you are reporting the above isn't working, I'm yet to encounter an actual ElementId of long value so can't easily check that.

 

btwbtw

 

Message 5 of 6

martin.leonhartsberger
Participant
Participant

I already tested the FilterElementIdRule with FilterNumericEquals as suggested by Jeremy, and it fails, as stated in my first reply.

The reason why it fails has to be the FilterElementIdRule taking the value to compare from Parameter.AsElementId.

As you can see in the screenshot (in my first reply), AsElementId deliveres -1 instead of the wanted value 322892.

So it seems quite logical to me, that this just has to fail.

 

As you already point out, Parameters do not support Int64, although the string behind SpecTypeId.Int.Integer is "autodesk.spec:spec.int64-2.0.0".

So that would be a problem at some point anyway.

That is just disappointing...

 

Yes, another way to solve this problem could be storing the value as ElementId.
But as already stated in my first reply, I could not find a suitable SpecTypeId for a new Shared Parameter, which can hold an ElementId (eg the Id from a room).

Any ideas on that?

0 Likes
Message 6 of 6

RPTHOMAS108
Mentor
Mentor

Yes it fails because it is not a parameter of ElementId storage type it is an integer storage type that you created. Still your issue really is that you equated ElementId and Int32 as being the same thing to compare. In the past you got away with doing that but now you can't. 

 

To solve the issue you can either use a string parameter to hold the value or use extensible storage. I doubt you'll be able to create an ElementId parameter even if you could it would have to always refer to an object or it would revert to -1 as soon as the object it referred to ceased to exist. If you are using a string parameter you would have to use FilterStringRule to compare it. If you are using extensible storage you can store the ElementId and compare that via FilterElementIdRule. 

 

I'm not sure why the SpecTypeId refers to Int64. Could be due to it being part of a larger APS system where elsewhere outside of Revit Int64 can be (or is anticipated to be) used, could be they plan to increase the storage of such parameters, could just be an oversight.

 

If ElementId internally changes to Int128 or GUID in the distant future you can still be using ElementId and let the development team worry about what it is internally. If you reduce it to a Int32 you'll always be stuck with that limitation. Likewise if you now reduce it to Int64 you'll be stuck with that limitation, it isn't sustainable or necessary. Consider the box instead of the thing in the box.

 

Converting to string seems like your quick short term solution, long term you should perhaps consider extensible storage. Even with ES you can't create your own isolated ElementIds they always have to refer to something or they'll just turn to -1 as soon as you reopen the file.

 

Another option is to store your Int64 as two Int32's and use a logical and filter on two integer parameters. Storing an Int64 as two Int32's was quite common in extensible storage before it supported Int64. So there will be an example somewhere of how to split the Int64 into high and low bits and then put it back together again (you can use bit shift operators or rely on structure layout with field offsets).

0 Likes