BRApi.Finance.Metadata.GetMembersUsingFilter returns null in Cube View Extender

RobbSalzmann
Valued Contributor

OS Version 7.4.1. GolfStream v44
When calling BRApi.Finance.Metadata.GetMembersUsingFilter in a Cube View Extender rule I'm getting a null return. e.g.:
List<MemberInfo> members = BRApi.Finance.Metadata.GetMembersUsingFilter(si, "Account", "a#16999.children", false);
I'm following the method signature:

RobbSalzmann_1-1683903017349.png

Is there a better/alternate way to get the output of a memberFilter in a CV Extender Rule?

Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"
14 REPLIES 14

db_pdx
Contributor III

Did you mean to put this into a Finance Business Rule to return a custom member list?  Typically I think of Cube View Extenders as modifying the formatting of the PDF version of a CV.

RobbSalzmann
Valued Contributor

I wish I could use a finance rule.   The event launching this logic is the click of the Report button in a Cube View.  I think that limits me to a Cube View Extender.

RobbSalzmann_0-1683904578621.png

 

Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"

The report button is definitely Cube View Extender territory. Nothing comes to my mind immediately how you would accomplish that in a CV-Extender as we've not done much more than the basic logo or color change type stuff.  That doesn't mean its not possible though.  Maybe others have thoughts here?

 

Else, my next thought would be: is there another way to achieve a similar result via a slightly different avenue. Is the expansion different from what is displayed on screen?  Or is it that what will be displayed is based on the cell intersection a user has selected?  There might be some ways to do this with the new TreeExpansionLevel feature from 7.3; or by using Linked Cube View / Dashboard Drilldowns

Michel_Sabourin
Contributor II

What's the use case? I would tend to think you want an XFBR based off parameters to return the list you want dynamically, but you mentioned it running only on Report. What is it you're trying to accomplish. It might help us troubleshoot

The use case is to get the member names for the first row of the report:

private List<string> GetFirstRowMembers(SessionInfo si, CVExtenderArgs args)
{
   List<String> rowMembers = new List<string>();
   CubeViewRow row = args.Report.CubeView.Rows.First();
   List<CubeViewMemberExpansion> rowMemberExpansions = row.MemberExpansions;
   foreach(CubeViewMemberExpansion rowMemberExpansion in rowMemberExpansions)
   {
      string[] memberFilters = rowMemberExpansion.MemberFilter.Split(new char[]{',', ' '});
      foreach(string memberFilter in memberFilters)
      {
         //This call returns null
         List<MemberInfo> members = BRApi.Finance.Metadata.GetMembersUsingFilter(si, rowMemberExpansion.PrimaryDimTypeName, memberFilter, false);
         //Returns null even with known, hard coded arguments
         //List<MemberInfo> members = BRApi.Finance.Metadata.GetMembersUsingFilter(si, "Account", "a#16999.children", false);
         foreach(MemberInfo member in members)
         {
            string nameAdDesc = member.Member.NameAndDescription;
            rowMembers.Add(nameAdDesc);
         }
      }
   }
   return rowMembers;
}



Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"

It's still not clear what you are trying to accomplish:

"The use case is to get the member names for the first row of the report"  to do what with them?  Standard functionality can toggle displaying of member names and description.  Is it that you want to change what is displayed when running the PDF report?  Meaning, display Member Name and Description when in the native view, but only display Description when in the PDF report?

Or are you trying to do some sort of drill-down expansion when running the PDF?  Or are you trying to create a custom member expansion?

Michel_Sabourin
Contributor II

Does this need to be dynamic to work with multiple dimensions? will the expansions always be children? I think I could get this to work with a Dashboard XFBR string.

yes it does need to be dynamic, the dimension(s) could be any, and the expansions could be any member script.  Your approach sounds interesting!

Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"

Ok. When I have time I'll put it together

ChristianW
Valued Contributor

Is your account dimension‘s name really „Account“ or do you use the Dimtype Name?

Try to replace „Account“ with the real dimension name like „CorpAccounts“, „ActAcc“, „BudAccnt“ or however the name of your account dimension is.

Then it should work.

Thank you for your thoughts. I tried this and got better results.  However I can't use hard coded values at runtime.
Are you able to indicate which object can supply the dimension name, as I cannot know it prior to runtime.   I'm probably missing something - I'm only able to see DimTypeName, that seems the closest I can get to looking up the dimname.  Additionally, there are at least 2 dimensions on the rows.

 

 

private List<string> GetFirstRowMembers(SessionInfo si, CVExtenderArgs args)
{
   List<String> rowMembers = new List<string>();
   CubeViewRow row = args.Report.CubeView.Rows.First();
   List<CubeViewMemberExpansion> rowMemberExpansions = row.MemberExpansions;
   foreach(CubeViewMemberExpansion rowMemberExpansion in rowMemberExpansions)
   {
      string[] memberFilters = rowMemberExpansion.MemberFilter.Split(new char[]{',', ' '});
      foreach(string memberFilter in memberFilters)
      {
         //This call returns null
         List<MemberInfo> members = BRApi.Finance.Metadata.GetMembersUsingFilter(si, rowMemberExpansion.PrimaryDimTypeName, memberFilter, false);
         //Returns null even with known, hard coded arguments
         //List<MemberInfo> members = BRApi.Finance.Metadata.GetMembersUsingFilter(si, "Account", "a#16999.children", false);
         foreach(MemberInfo member in members)
         {
            string nameAdDesc = member.Member.NameAndDescription;
            rowMembers.Add(nameAdDesc);
         }
      }
   }
   return rowMembers;
}

 

 

Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"

Fun rabbit hole, I think I cracked it - just turn this VB in your fancy C#:

 

' first, figure out scenario type
 Dim scenarioName As String = args.CubeView.CubeViewPovMembers.Scenario.Name
 Dim scenarioId As String = BRApi.Finance.Members.GetMemberId(si, _
   Dimtype.Scenario.Id, scenarioName)
 Dim scenarioTypeId As Integer = BRApi.Finance.Scenario.GetScenarioType(si, _
   scenarioId).Id
 ' then get the cube
 Dim objCubeViewCube As CubeViewCube = args.CubeView.CubeViewCube
 Dim objCubeInfo As CubeInfo = BRApi.Finance.Cubes.GetCubeInfo(si, _
   objCubeViewCube.Name)
 ' now we can look up any dimension
 Dim accountDimId As Integer = objCubeInfo.Cube.CubeDims.GetDimId( _
   dimtype.Account.Id, scenarioTypeId)
 Dim accountDim As OneStream.Shared.Wcf.Dim = BRApi.Finance.Dim.GetDim(si, _
   New DimPk(dimType.Account.Id, accountDimId))
 brapi.ErrorLog.LogMessage(si, $" {accountDim.Name}")

 

Note: this relies on the Scenario being fixed in the CV Pov. If you have multiple ones, you'll have to get them first (from either cv, rows, columns, etc) and retrieve their scenario types so you can do the lookup. That's because our beloved Extensible Dimensionality ™ allows for dimensions to change not just by Cube but also by Scenario Type.

Michel_Sabourin
Contributor II

While I can figure out how to select the dimension via parameter to feed another parameter to pull the dimension name, the real problem, as I think about it, is setting the dimension type for the row. I don't think there's a way to set that programmatically (or not one that I've found so far). I haven't given up, but that's today's roadblock. 

 

Michel_Sabourin_0-1684171789593.png

 

There are a variety of ways to get the DIm Type for a given row header.  One of them is shown in the code posted above (circled in green below as well).  Its the dim name that we need to pass in to GetMembersUsingFilter that seems to be the mystery.  Dimension name cannot come from a hard coded param, we need it from an object within the CubeView object hierarchy for the  Report currently being parsed.

RobbSalzmann_1-1684172677621.png

 

Software Architect
MindStream Analytics
"Difficult done right away. Impossible takes a bit longer"