Got this question recently - and figured to do a blog post on it.
How to include the all members as part of a report's prompt and get the results out of it?
This is basically a followup question from what
Diethard Steiner blogged about some years back. But still very useful. And all is done with some MDX query magic.
The reportSo here's what we'll have in the end:
And this is built in a way that if I select a different level in the hierarchy, for instance, classic cars, the output will intermediately reflect that:
The editorThis sounds like a very complex report, with a few subreports for the inner queries, right?
Well, no. Here's the report:
Sorry, but I can't imagine something simpler! Now, how do we get from here to the report I showed before?
Step 1 - The parametersIt all starts with how we pass the parameters. The trick is to make sure we get the fully qualified member name (that is,
[Products].[Classic Cars].[Gearbox Collectibles] instead of just
Gearbox Collectibles) .
Here's the query I used:
with
member [Measures].id as Product.currentMember.uniqueName
member [Measures].[name] as Product.currentMember.Name
select {Measures.id, Measures.[name]} on Columns,
Descendants([Product].[All Products],2,SELF_AND_BEFORE) on Rows
from [SteelWheelsSales]
This will populate the prompt with all the members. The trick here is to use the
descendants function in conjunction with the
uniqueName property.
Step 2 - The queryNow we need to prepare the query to receive those arguments:
With
member [Measures].[Name] as [Product].currentMember.Name
member [Measures].[Level] as [Product].currentMember.Level.ordinal
select {Measures.[Name],Measures.[Level],Measures.Sales, Measures.Quantity} on Columns,
Descendants(Parameter("territory",[Product],[Product].[All Products]),
[Product].[Vendor],SELF_AND_BEFORE
)
on Rows
from [SteelWheelsSales]
I could shape this query anyway I'd like - in here I want my parameter to select not a single aggregated row but every children member as well. The special mdx function
parameter allows me to have a query that not only will work in design time but will also correctly receive the parameter. I could have used ${territory} as well, but honestly forgot how to use it without losing the preview / design time ability :)
You'll see some (not so) minor details here:
- I'm explicitly asking for the name: that's because PRD would give me different cells for the different levels, and I just want the name. This way I can drag to my report just that field and will always show me the name. In CDE / CDA this wouldn't be needed, as we have a different way to parse the mdx resultset by default there
- I'm using a slightly different syntax of the Descendants, where instead of specifying how many levels down we need to go, we specify the destination level
- I'm also getting the level number so I can use it to conditionally change the layout - add the indent and change the font size
Step 3 - the layoutAs shown before, the layout is very simple; just the 3 fields in there:
Step 4 - the conditional formattingTwo extra things that I did. On the
Measures.[Name] I conditionally formatted the font size and the left padding, respectively:
- =10+ 3-["[Measures].[Level]"] (font size)
- =["[Measures].[Level]"]* 10 (left padding
All this joined together, we get the full report!
Have fun!
More...