The use case
In the last (ahem) exciting blog post, I showed how a Scenario text property could be queried by XFMemberProperty for things like aggregating/consolidating the current time period. Ah, the sweet smell of success.
However, over on Linkedin, there were a number of not-entirely-convinced comments. In particular, there was a remark about the hardcoded nature of using a Scenario text field as a driver for much of anything given its static nature. While it’s nice to have one’s work commented on as it means people actually read these posts (sometimes I do wonder), it made me think about how that text property could be programmatically changed. If it can be changed through code an administrative dashboard can drive it. What could possibly be easier?
Running it interactively
This bit is actually pretty easy: use an Extensibility Rule because it can be run interactively:
There are – as it ever was and shall ever be – eleventy million ways to do a given task in OneStream. Running a rule directly in the Business Rule editor instead of through a Data Management Step or via a Dashboard is nice when trying out new techniques. Not all processes make sense (nor can they be directly called) within an Extensibility Rule but some – like this blog post’s subject – absolutely can.
Creating a rule
It’s just like any other one:
As is par for the course, OneStream creates a rule with a series of args.FunctionTypes:
I take perverse pleasure in knowing this code is going to run under args.Unknown. I had no idea how to do what I’m about to show you, so Unknown is apt. If you look at the other two supplied argument types, changing a text property isn’t running a Data Management Sequence nor is it adding new members to a dimension. Unknown it is.
The easy bit
Here’s Transformed_Plan’s Text 1:
Reading a text field is simple(ish) using the brapi.Finance.Scenario.Text method:
The only tricky bit is getting the scenarioId, but that can be done with a BRApi.Finance.Members.GetMemberId:
Don’t lose your mind over the dimTypeId property. Just use DimTypeID.Scenario:
Plop that into the middle of the Scenario.Text method:
And yes, those are crazy line breaks but it’s to make the text readable in this post.
Here we are:
Writing a Scenario’s text field is a bit more complicated. I fear that I had to again prevail on my brother from totally different parents (and isn’t he glad of it), Celvin Kattookaran for this code. There wasn’t an earthly that I was going to figure it out although I knew (well, I thought awfully strongly) that it could be done. But the how? Well, once even he got a bit confused I knew it was good fodder for a blog post. Pinky promise, it’s not all that bad.
It’s then just three steps: MemberInfo, SetStoredValue, and finally SaveMemberInfo. What could possibly be easier?
This is pretty close to GetMemberID so I’m not going to break it down property by property:
Get to Set
This one makes me laugh: use GetScenarioProperties to SetStoredValue. No matter, it does exactly what it says on the tin:
The method is (mostly) straightforward:
- si is SessionInfo – just specify it
- memberInfo was retrieved two lines up
- saveMember is False because this is just a property update
- saveProperties is set to False as that sort of is the whole point
- saveDescriptions is set to False as this is, as noted above, a property update only
- isNew is set to TriState.TrueValue. TriState Booleans are…interesting. I love the fact that a Boolean can have more than two values (hence the “tri”) with an undefined. Undefined, unknown; it’s a .Net/OneStream mystery.
Here it is:
The Whole Shebang
Let’s run it:
Ooooh, I love doing that directly in the IDE. And here’s the result in the Error Log:
And in the dimension itself:
Great, fine, huzzah, ta da, it works. Okay, but so what? We (well, me) care because this means the code can now be put up against a Dashboard with dropdown controls to drive year and month which I shall endeavor to show next time round and not bug Celvin in the process.
And yes, before you note that this could all be done with a literal parameter, XFMemberProperty as noted in the LinkedIn comments in the last post, handles VaryBy properties. Also, it’s just nice to have the code in one’s metaphorical back pocket.
Be seeing you.