You’ve done it. After some development, your Power Pivot model has some awesome-sauce, has a slicer for the day/month/year, and is ready to do some serious data insight. You set your slicer to the current moment in time, deploy it to a Power Pivot gallery in SharePoint, and start using your model. But then…tomorrow happens. And now your slicer is out of date. Every time a new day happens, the slicer gets farther and farther away. Your users don’t want to click the latest date every time they want to use the model, you’d like to make it dynamic so that you don’t have to click on the latest day every time. Rob Collie does an excellent introduction into this topic in his new book, and gives a good background on using a latest date slicer. I was recently reviewing this concept with a class when they went through all the different scenarios that this might apply in. (You know who you are! :)) I thought this would be a good opportunity for a blog post, to show the different levels and ways that this concept could be applied:
DATE TABLES THAT GO INTO THE FUTURE, FACT TABLES THAT GO UP TO TODAY
The first scenario we might run into is that our fact table has dates of that go up to today’s date, but our date dimension pulls dates that go into the future. Facts like this usually surround performance or actually happened metrics. Consider a date dimension that goes out 10 years into the future. Do we really need to pull the maximum date of the date dimension? No, as our slicer will be unusable until that end date happens, 10 years away! A neat trick to get around this is to pull the maximum date from the fact table, thereby only pulling the most recent date from our fact. We create a calculated column in our date table, with the below syntax:
=IF(MAX(‘Internet Sales'[OrderDateKey])=[DateKey],”Latest”,FORMAT([FullDateAlternateKey],”mm-dd-yyyy”))
This gives us a slicer that looks like the below, and allows us to select “Latest” as our default value, ensuring that we always have the most recent data selected in our visualizations:
Now this is awesome, but I don’t know if I’d call it awesome sauce. Let’s try and modify our date slicer a little:
CREATING A SLICER AT THE MONTH LEVEL
Slicers are really built to be views of our data, right? Because of this, slicers should generally contain pieces of data that have less distinct values than other pieces of our model. I can modify my query above to pull the current month of data, thereby limiting my my “Latest” value slicer to only months, making it easier and less overwhelming for a user:
=IF(LEFT(MAX(‘Internet Sales'[OrderDateKey]),6)=LEFT([DateKey],6),”Latest”,[CalendarYear]&”-“&[EnglishMonthName])
I’ve highlighted my changes in red. I want to make sure I preserve the integer portion of the keys, in order to keep performance up. I’ve taken the 6 left of the max of the fact table, and joined it to all of the days that fall in the month in my date table. This way, my slicer will return all of the facts that happened in that month.
Resulting in the following slicer on screen:
One really quick modification I could make to this is to change number 6 in the number of characters argument of the LEFT function to 4, to return only the year. Change the last portion of the IF statement to return all of the days that fall in the current year, and I could get a “Latest” Year slicer.
Awesome Sauce! I could end this post here, but I wanted to present two other scenarios you might run into.
MAP THE LAST UPDATE FIELD IN YOUR MODEL TO THE LAST DATE OF THE SLICER
Another technique Rob has detailed over at powerpivotpro is how to use a “LastUpdated” date in your model to show the date/time you data is current as of. By changing a quick part of the statement, we can utilize that field as our “Latest” date:
=IF(INT(FORMAT(MAX(LastUpdatedDateTime[LastUpdatedDateTime]),”YYYYMMDD”))=[DateKey],”Latest”,FORMAT([FullDateAlternateKey],”mm-dd-yyyy”))
Again, I’ve highlighted my changes in red. This time, we’re pulling the LastUpdatedDateTime into our model as a datetime. In order to compare it to what our datekey is, we need to convert our date returned into a value that matches the format of our date key, which is why we have the format function included. By default, format returns the result back as text, so we wrap the whole function in an INT function to convert the result of our format as an integer.
DATE TABLES THAT GO INTO THE FUTURE, FACT TABLES THAT GO INTO THE FUTURE
Another common modeling issue we might see when we want to implement something like this is when BOTH the date table and the fact table go into the future, as we might commonly see in budgeting, project planning, and construction. Pulling the max date from our date table is going to give us date really far in the future, as will the fact table! A common joke I tell my students during class is “Do as I mean, not as I say”. We need to tell DAX the same thing. DAX has a built in function to return today’s date, called TODAY(). By changing the other side of our IF condition test, we can tell DAX that the record we want to tag with the “Latest” annotation is today:
=IF([DateKey]=INT(FORMAT(TODAY(),”YYYYMMDD”)),”Latest”,FORMAT([FullDateAlternateKey],”mm-dd-yyyy”))
All we did there was move our INT(FORMAT( function from the left side of the equation to the right! This breaks my earlier statement of having a lot of slicers at the day level, though, so I want to create one more to return the current month and year as my slicer value:
=IF(INT(LEFT([DateKey],6))=INT(FORMAT(TODAY(),”YYYYMM”)),”Latest”,[CalendarYear]&”-“&[EnglishMonthName])
The workbook is available for download here. (no size issues this time, I checked. :))