Showing posts with label Power Pivot. Show all posts
Showing posts with label Power Pivot. Show all posts

Monday, September 28, 2015

Dynamic Chart Axis with Slicer!!! - Switching between Year/Quarter/Month/Week views

OH MY GOODNESS!!!!!

I've been looking for this for so long it's ridiculous...  I've always wanted to be able to simply use a slicer to change the row values on my pivot tables/charts from Year to Quarter to Month without needing multiple tables/charts. 

This guy is brilliant and very kind to share with all of us.  Please check his article.  It's awesome.


Oh man, my job is so much easier now... :)

Monday, May 18, 2015

How to show all dates in a powerpivot pivot table even when there is no data...

So, I've heard about this issue for a while now, but I never had to actually deal with it myself - until now, that is..

We have a system that records when a specific significant event occurs - we'll call this Event A.
Well, Event A doesn't always happen and frankly, we NEVER want it to happen.  So, when reporting month-to-month numbers, there are some times when a month shows "0" for the denominator and "0" for the numerator.  In a typical Excel pivot table, this isn't really a big deal you simply go into the properties and set the "Show items with no data on rows/columns" option to TRUE.




Unfortunately, with my particular power pivot model, it wasn't so simple.

My online investigation took me to this forum.  It was a lengthy conversation where multiple people offered the "easy" solution that ultimately didn't work.  However, there was one contributor that was spot on in understanding the issue.  It took me a while to pick through the conversation and get past the suggestions that still resulted errors to finally get at the solution I was looking for. So, I am going to attempt to explain what I did to save time:

The solution is this formula:

# of Event A:=sumx(filter(DimDateEvent,DimDateEvent[Months from Current]>0),0+Event[#ID])

I have two tables involved:

  • DimDateEvent - Date dimension table that consists of only monthly data - I will only ever report Event A on a monthly basis so no need to get more granular that Monthly.
    • Note - I have a column in my table to measure the number of months from current month.  The results are both positive and negative.  
    • =(YEAR(TODAY())-YEAR([@[Beginning of Month]]))*12+MONTH(TODAY())-MONTH([@[Beginning of Month]])
  • Event - My fact table that has the Event information.

Formulas Used in the Solution:
  • Sumx(<table>, <expression>)

Calculated Measure used in Solution:

  • Event[ID#] - this is simply Counta(Event[ID])

Normally, when creating a pivot table, the source data is the table with your event information and you "Look up" the remaining details.  However, for this solution, we are going to use our DimDateEvent Table as the data and "Look Up" the event information.

So, lets walk through the formula:

=Sumx(
Sumx - allows you to apply an expression to the data being added.

=Sumx(Filter(DimDateEvent,DimDateEvent[Months from Current]>0)
Filter - provides the DimDateEvent table filtering it to show only last month and every month before it.

=Sumx(Filter(DimDateEvent,DimDateEvent[Months from Current]>0),0+Event[#ID])
I didn't want the table to show blanks, so I showed 0+ (this guarantees a value of "0") and then the result of the calculated measure Event[#ID] or in other words, the formula "Counta(Event[ID])".



So now we have completed the formula:
=sumx(filter(DimDateEvent,DimDateEvent[Months from Current]>0),0+Event[#ID])


Here is what it looks like in a pivot table: 
Note: No real data is being used here... The fiscal Year resets because I'm not showing the entire pivot table there is a Group A, Group B, Group C



No Demo File will be provided for this example.

Enjoy!

Tuesday, April 21, 2015

Catching those slicer selections: A macro to do the work for you...

I've been working with PowerPivot for some time now and one thing that I've noticed on each of my solutions that I create is that I spend too much time creating the hidden sheet that "catches" each of the slicer selections that are active.  This can sometimes take hours if the project is big enough.

So, this last time, I decided to take 20 minutes out of my day do a little research on the Google and write a macro that would do exactly that for me.  Too much time is now almost no time at all and I have a bit of my work day back.  

Here is what I use. If you have suggestions on how to make it more efficient or just better practice (self-taught here folks!), please share in the comments!

Summary of Macro: 
Create a worksheet called "HiddenFilterCatch".  
Add Cubeset and CubeRankedMember formulas to new sheet (Prompting user for max number of options per slicer to catch)

Please excuse the blog formatting as I use a bit more screen real estate when coding.  Enjoy!

*Disclaimer - this worked for me in my specific scenario. You may/may not need to adjust the code to fit your situation.  :)

Option Explicit
Sub MultiplePivotSlicerCaches()
    Dim oSlicer As Slicer
    Dim oSlicercache As SlicerCache
    Dim oSh As Worksheet
    Dim SlcrName As String
    Dim Col As Integer 'Column Number
    Dim Connect As String, Comma As String, oPrn As String, cPrn As String 'Formula pieces
    Dim i As Integer 'Number of Slicers
    Dim Fmla As String 'Completed Formula
    Dim ws As Worksheet
    Dim x As Integer 'Max # of Filters determined by user
    Dim z As Variant

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    
'Add New Worksheet "HiddenFilterCatch"
    z = MsgBox("Do you have a 'HiddenFilterCatch' Worksheet already?", vbYesNo)
    If z = vbNo Then
        Set ws = Sheets.Add(After:=Sheets(Sheets.Count))
        ws.Name = "HiddenFilterCatch"
    End If

'Count Slicers in Workbook (For Trouble Shooting Code Only)
    'i = 0
    'For Each oSlicercache In ThisWorkbook.SlicerCaches
    'i = i + 1
    'Next
    
'Set Variables for "=Cubeset()"
    Col = 3 'Column Number
    Connect = "=Cubeset(" & Chr(34) & "ThisWorkBookDataModel" & Chr(34) & ","
    Comma = ","
    oPrn = "("
    cPrn = ")"
    
       
'Distribute Cubeset Formulas onto spreadsheet
    Sheets("HiddenFilterCatch").Activate
    For Each oSlicercache In ThisWorkbook.SlicerCaches
            SlcrName = oSlicercache.Name
            Fmla = Connect & SlcrName & Comma & Chr(34) & SlcrName & Chr(34) & cPrn
            Cells(9, Col).Formula = Fmla
            Col = Col + 1
    Next
    
'Set Variables for "=CubeRankedMember()"
    Connect = "=IFERROR(CUBERANKEDMEMBER(" & Chr(34) & "ThisWorkBookDataModel" & Chr(34) & ","
    
'Distribute CubeRankedMember Formulas onto spreadsheet
    Col = 3
    x = InputBox(Prompt:="What is the Maximum Number of filters you would like to show?", Title:="Maximum Number of Filters", Default:="4")

    For Each oSlicercache In ThisWorkbook.SlicerCaches
            'Add formulas for CubeRankedMembers 1 to "x"
                For i = 1 To x
                    Fmla = Connect & Cells(9, Col).Value & ",Row(HiddenFilterCatch!A" & i & "))," & Chr(34) & Chr(34) & ")"
                    Cells(9 + i, Col).Formula = Connect & Cells(9, Col).Value & ",Row(HiddenFilterCatch!A" & i & "))," & Chr(34) & Chr(34) & ")"
                Next
            'Add "More than 'x' Selected..." Text formula
                Cells(10 + x, Col).Formula = "=IF(" & Right(Fmla, Len(Fmla) - 1) & "=" & Chr(34) & Chr(34) & "," & Right(Fmla, Len(Fmla) - 1) & "," & Chr(34) & "More Than " & x & " Selected..." & Chr(34) & ")"
            'Add named Range on Cell below "More Than" formula
                Cells(11 + x, Col).Select
                With Selection
                    .Name = Right(Cells(9, Col).Value, Len(Cells(9, Col).Value) - 7)
                End With
                Col = Col + 1

    Next

    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    
    
End Sub

Tuesday, March 18, 2014

PowerPivot: BLANK() & ISBLANK()

Today I ran into an issue when writing a formula in the calculated column area.  I needed to calculate the difference in minutes between two date/time columns.  However, I first wanted to check to be sure both columns in the row had an entry to avoid some outrageous number appearing as the result of the formula.

In excel I would have simply handled this issue with an If() Statement check to be sure the cell wasn't blank and then returning "" if it was.

The formula in an Excel spreadsheet looks like this:

=if(A1="","",if(A2="","",(A2-A1)*24*60))

Unfortunately, when used in the data model this will return "#Error" for all rows in the column instead of a blank value.

After consulting with a coworker, he showed me how he has resolved this issue:

=If(ISBLANK([Column1]),BLANK(),if(ISBLANK([Column2]),BLANK(),([Column2]-[Column1])*24*60))

The ISBLANK() formula simply checks to see if the value in the column is blank.  If it is, BLANK() returns the value as a blank cell - Much the same as using "" in an Excel Sheet formula.

To Explain the formula, I will write it in words:

If the value on this row of column1 is blank then return blank, otherwise go check if the value on this row of column2 is blank.  If it is, return blank, otherwise calculate the difference between Date2 and Date1.  Multiply the result by 24 to get hours.  Multply the hours by 60 to get minutes.

Hope this helps someone else save some time!

Thursday, January 23, 2014

(SOLVED) Slicer Selection in Chart Title without VBA!!!

So, I've been looking ALL OVER the internet to find a solution to this problem... Everywhere I look I read something like, "No, it's not possible" or "In a word, no".  Well, that's just not good enough for me.  I specialize in interim solutions and work arounds... SOoooo, after much research and trial and error, I've come up with a way to do just what we're all asking about - "How do I show the slicers selected in my Power Pivot chart?"  Since we upload our files to SharePoint and the end users are using Excel Services because they're working with Excel 2007, we can't use VBA for any of our solutions that have a data model.

Here's what we'll need (Remember, I'm using Excel 2013, NOT 2010 with the Add-In):
Data in the Data Model
Pivot Table
Pivot Chart
Slicers (Connected to the Pivot Table)

Formulas:
Cubeset(Connection, Set Expression,[Caption],[Sort Order], [Sort By])
CubeRankedMember(Set)
IfError(Value, Value if Error)

Data:  I'm using World population Data found at: http://www.census.gov/population/international/data/worldpop/table_population.php

I added a Decade column to assist me in quickly grouping the data by decade.


Now, I'm adding this table to the data model simply by:

  • Highlight the dataset
  • Click the PowerPivot Tab at the top
  • In the Ribbon, click "Add to Data Model"
There are multiple ways to add data to the model.  Typically I will connect directly to a data source instead of adding what I already have in the current spreadsheet, but that can be a discussion for another day.

Now that we have our data in the data model, let's stop and discuss a few very important details about the following steps.  It is imperative that we create a pivot table linked to the data model and NOT just a pivot chart.  The issue with linking a chart title or axis label to a cell can be bypassed simply by generating a pivot chart from a pivot table because it is then not directly linked to the data model.  This was probably the BIGGEST issue with the whole process.. I discovered the issue when I right-clicked and selected "Pivot Chart Options" for both a chart based on pivot table and a chart based on the model.  If you do this side-by-side, you will see that the chart connected to the data model has a window titled "PivotChart Options".  However, if you do this with the chart based on the Pivot Table, you will see "PivotTable Options".  Excel sees these charts differently.  To simplify and summarize, you can do all things to a chart based on a pivot table that you could do with the chart based on a dataset in a spreadsheet.  You cannot do this with a chart based on a data model.  

Back to the DataModel:

Within the Data Model window click the following:
  • Home Tab
  • PivotTable > Pivot Table
  • New WorkSheet > OK
Create your pivot table as you need it.  If you're following me using the WorldPop data, I'm using:

  • Rows = Decade
  • Values = Average of Annual Growth Rate (%)
This is what we have:


Let's Add our Slicer. On the Ribbon Click:


  • Insert
  • Slicer (Found in the Filters Group)
If asked, link this to your data model.  Select "Decade" from the column list under the table and click OK


Your slicer will look similar to this:

Link the slicer to the Pivot table by:
  • Right-Click the Slicer
  • Report Connections
  • Check the Pivot Table you want the slicer to control
  • Click OK
Now, Let's create our Pivot Chart:
  • Click somewhere on your Pivot Table
  • Under "PIVOTTABLE TOOLS" On the Ribbon, click "Pivot Chart"
  • Let's choose a Clustered Column Chart
  • Click OK
We now have:

I've selected a few of the slicers to demonstrate that the Slicer is working properly.

Now, to the fun part!  How do we get the slicers selected to show on the chart?

Formulas:
CUBESET(Connection, Set Expression,[Caption],[Sort Order], [Sort By])
CUBERANKEDMEMBER(connection, set_expression, rank, [caption])
IFERROR(Value, Value if Error)

When I build scorecards and dashboards I prefer to have a control sheet that is hidden that contains formulas that I don't want other's to booger up.  So I'm inserting a new sheet titled "ControlSheet" From here, the cell references will be in reference to sheet "ControlSheet"

**The formulas that follow differ slightly if you are using Excel 2010 (PowerPivot v1 and v2)- The "Connection" referred to in the Cubeset formula will always be "PowerPivot Data". "Connection" for Excel2013 is "ThisWorkbookDataModel"

In Cell A1, type the following:
  • =CUBESET("ThisWorkbookDataModel",Slicer_Decade, "Decade")
I simply leave the sort options blank. This will populate Cell A1 with a linked reference to the DOS Quarter Slicer.

Next, In Cell A2, type the following:
  • =IFERROR(CUBERANKEDMEMBER("ThisWorkbookDataModel",$A$1,ROW(Sheet1!A1)),"") - Remember, "Sheet1!" is the name of whatever sheet you're working in
The formula does the following:
  • If no slicers are selected, an error would be returned, so "IFERROR" returns a blank value.
  • Otherwise, if all slicers are selected (no filter) the value will be "ALL"
  • Otherwise, if one or more slicers are selected, the first value in the list of slicers will be returned
Now, since we have  10 decades in our slicer, let's use this formula 9 times (since 10 = "ALL").
  • Validate that your formula in cell A2 has the dollar signs around A1 ($A$1).
  • Copy the formula down to cell A10 (or Auto-Fill).
  • I typically use the "All Borders" Border around the range to indicate that the cells are being used even if they are blank.
Next, test your Slicer by Selecting Multiple Values and see what is returned by the formulas you've just created.

 Now that we are "Catching" our slicers, we can Create a label like "Filters Used: " , concatenate the values and link to our chart. 

Let's do it!

In Cell A12 on ControlSheet, Type "Filters Used - " 

In Cell A13 Copy/Paste the following formula
  • =A2&IF(A3="","",", "&A3)&IF(A4="","",", "&A4)&IF(A5="","",", "&A5)&IF(A6="","",", "&A6)&IF(A7="","",", "&A7)&IF(A8="","",", "&A8)&IF(A9="","",", "&A9)&IF(A10="","",", "&A10)
This formula will always return the value in Cell A2, but will check to see if the following cells are blank before returning the value.  If it's blank, then it returns a blank value.  If it's not, it adds a comma and then the value of the cell.

In cell A14 copy/paste the following formula:
  • =A12&TRIM($A$1)&": "&TRIM($A$13)
You should see:

In cell A15 concatenate your Chart title with the value in Cell A14..  I prefer to add a line between (carriage return).  My formula looks something like this:

="Avg World Population by Decade "&char(10)&A14

*Char(10) will add the carriage return we need

Now, let's return to Sheet1 and our chart...

Click on the chart title and in the formula bar type "=ControlSheet!$A$15"

You will see the this:

As you change the filters in the slicer, the title will change with it!

For the longest time I thought "Let's put the filters in the Title" was the best idea EVER!.. However, once I did it, I realized it wasn't a great Idea.  If you have multiple slicers you've incorporated into your title it becomes WAY oversized and unruly.  You see, when you link the title to the cell, ALL of the text is the same font size - you can't make the filter text smaller than the title text.  For me, the title should be the focus and the filters just there if you need them.

Let's solve this: ADD A HORIZONTAL AXIS LABEL! - Since the data in this case is very self explanatory we don't need the axis label to describe the axis.
  • Click on chart
  • On Ribbon, Click "Design" in PivotChart Tools
  • Click Add Chart Element
  • Axis Titles > Primary Horizontal
  • Click on the Axis Label on the chart
  • Paste "=A12&TRIM($A$1)&": "&TRIM($A$13)" into the formula Bar
  • Change the font size to "8"
  • Change your Chart Title by simply typing the title in "Avg World Population Growth Rate (%) By Decade"
You should now see this:


I hope you all enjoy this!  It's been a royal pain trying to work without this solution, so if you share it, please share some of the credit with me if you reference this.

Thanks!