“Where does he get such WONDERFUL toys???”
-Kasper de Jonge
(To be honest, Kasper probably looks nothing like this. I’ve never been to the Netherlands, but based on the fashions in Sweden, I am fairly certain that the Dutch don’t dress like that, at least not when they visit Sweden).
Poor Kasper, though. The mystery of how the parameterized, sliced, auto-sorting report was built has simply been too much for him to bear, so the other day I sent him an advanced preview of the workbook. I’ll share the same workbook (without the underlying data, which is licensed) with all of you, but first, some explanation.
Two posts back, I showed you the functions CUBEMEMBER and CUBEVALUE. Think of CUBEMEMBER cells as composing the axes of a report, and CUBEVALUE cells as composing the numerical data in the report.
But CUBEMEMBER does not easily lend itself to dynamically-sorted reports. Each CUBEMEMBER function fetches a fixed value (an NFL player, in my case) from the database. To get a nifty auto-sorting report, we need to introduce…
As far as Excel functions go, CUBESET is a strange one. It’s 100% useless by itself, but forms the foundation for some very interesting things. Let’s look at its syntax:
CUBESET(connection, set_expression, , [sort_order],
- Connection – the name of the connection, from Excel’s perspective. In CTP3 Adaptive builds, this is always “Sandbox” for PowerPivot connections. This, BTW, is the first argument to every cube function.
- Set_expression – rather than return a single “member” like CUBEMEMBER, CUBESET returns a whole “Set” of values. There are many different syntaxes for representing a set, but the one you will use most often is <ColumnName>.children, which returns all unique values of that column.
- Caption (optional) – there is no way for Excel to display all values of a set in a single cell, so you generally make up your own caption. “” is a common caption, since it doesn’t clutter your report, but you can return any string you want, like “All NFL Players”.
- Sort_order (optional) – an integer from 0 to 7, representing “No Sorting,” “Sort Ascending,” “Sort Descending,” “Alpha Ascending,” “Alpha Descending,” “DB order ascending,” “DB order descending.”
- Sort_by (optional) – the MEASURE you want to sort by. (Must be a measure, not a column!) This argument is ignored unless you specify 1 or 2 for sort_order (ascending or descending).
Using CUBESET() in the football report
In my football report, I use CUBESET behind the scenes, with the following arguments:
Ignoring the connection and caption arguments, what this formula means is: “Return all unique values from the [FullName] column in the [CleanPlayers] table, sorted descending by the Rushing Yards measure.”
(Note that in Cube formulas, table names are wrapped in square brackets, whereas in DAX they are wrapped in single quotes. It would be nice if cube functions could use single quotes for tables to distinguish them from columns as DAX does, but there’s an excellent historical reason for that.)
Fetching values from that set using CUBERANKEDMEMBER()
This is where it gets fun 🙂
The cell that contains the CUBESET formula only displays a caption, but behind that cell, the entire set is stored, invisibly. CUBERANKEDMEMBER is how you fetch values from that set.
(Whether you chose to specify a sort order or not, that set IS ordered, even if the database decided to return the values in somewhat random order. Hence the “RANKED” in its name.)
The syntax for CUBERANKEDMEMBER is quite simple:
For set expression, just give it the cell address of the CUBESET formula. For rank, give it any integer: 1 to return the first member of the set, 2 for the second, etc.
In my football report, this is:
The syntax for CUBERANKEDMEMBER is quite simple:
B3 is the address of my CUBESET formula, but I used the absolute reference syntax $B$3 because I plan to copy this CUBERANKEDMEMBER formula down a column, and I don’t want Excel adjusting B3 to B4, B5, etc., since that won’t reference the right cell anymore.
OK, what the heck is ROW(A1)???
It’s an Excel trick. If I just enter 1 for this argument, that will NOT increment to 2, 3, etc. when I copy this formula down a column.
And the whole reason to copy down a column is so that I get the 2nd, 3rd, 4th, etc. members of the set as I go down the column.
If I use ROW(A1), that will return 1 for the first instance of the formula. And when I copy down the column, Excel increments that to ROW(A2), ROW(A3), etc., which return 2, 3, etc. – just what I want!
Comparison to the Named Set Method
Denny Lee’s [link removed due to 404] series of posts on Top N reports goes a different direction than what I have here. He defines a Named Set in the Excel UI (using the MDX language), then uses a PivotTable to return that top N set.
In comments on the first post, Colin Banfield asked how to order that set. Neither Denny nor Colin have an answer at the time of this writing. And if Denny and Colin are stumped on MDX, well, there’s no WAY that I am going to figure it out 🙂
But with CUBESET, you can see that the Sort_order and Sort_by params give me a simple method for ordering the set by a variety of criteria. Then CUBERANKEDMEMBER lets me fetch any number of those sorted items, in whatever precise order I’d like.
So… no MDX required, (except for the .children trick I used in CUBESET, which technically is MDX), AND a simple solution to the ordering problem.
The Named Set feature is a good one, and it definitely has its uses, but for custom Top N reports, I’ll take CUBESET and stay away from that MDX madness.
And what about Top N filters in pivots?
Actually, if Top N is all you want, a Pivot is gonna be your best bet at least 90% of the time. Remember, the only reason I went down the Cube Formulas path is that I wanted custom formatting in my report, and parameterization.
I’ll post again shortly about how pivots might even be better than you expect at Top N reports.
Don’t worry if I am losing you, this is not required… nor easy
This whole topic of cube formulas is pure gravy, take-it-or-leave-it kind of stuff. It took me several attempts to get comfy with it myself, and I was part of the team building the feature!
Think of this as a 200-level topic. I’m including it for the handful of you who consider yourselves hardcore, to test your mettle and stretch your Excel skills 🙂 Everyone else, just file this away for later and come back some day when you find yourself needing precisely these tricks.
When it comes to building PowerPivot reports, I’d break things out like this:
100 Level Topics
- PivotTables, PivotCharts, and Slicers
- Converting a PivotTable to formulas and then custom arranging/formatting the report
- Customizing CUBEVALUE cells to do custom arithmetic and parameterization
- Writing CUBESET and CUBERANKEDMEMBER formulas
- Dynamic sorting using CUBESET and CUBERANKEDMEMBER
- MDX-Driven Named Sets, as Denny demonstrated
…which means that my next post on cube formulas is even more optional/ignorable than this one 🙂
Wake up Denny!
Denny, of course, well… Denny HAS to pay attention, because I challenged his geek-hood in my last post.
Some of you might say that wasn’t fair, since I have more Excel background than Denny and he has more SQL background than I. Sun Tzu once suggested that choosing the field and terms of battle was more important than the fighting itself, and I do love me some Sun Tzu 🙂
Are you like Kasper? Want to skip ahead? Download the workbook!
I have not covered every technique yet, but if you are getting anxious like Kasper and can’t wait any longer, you can download the workbook here and inspect every last formula.
Remember, the source data itself is licensed, so I’ve removed that from the workbook. You won’t be able to fetch fresh values from the PowerPivot db if you try to refresh, or modify formulas. I’m sharing this so that you can see all the formulas and understand how the report is built.
And no, Kasper didn’t get the source data, either 🙂