2

I have a powerpivot table that looks like this... all "facts" are in a single table with the Information column used to segregate:

Information | Year | Amount
Expense       2010   1000000
Units Sold    2010   50000
Expense       2011   2000000
Units Sold    2011   125000

I would like to be able to calculate various ratios. This seems like a straightforward need, but I've not been able to figure it out or find a solution online.

For example...

  • Expense / Units Sold for 2010, 2011 or combined (based on filters applied in Excel)
  • ..... 2010 = 1000000/50000 = 20; 2011 = 2000000/125000 = 16; all time = 3000000/175000 = 17.14 ETC.

In reality there are many more dimensions (region, location, month, etc.) and other Information types (headcount, square footage, etc.), but only three or four denominators, so I am hopeful the solution will scale out.

How can I do that in Powerpivot? I can calculate the denominator using (as an example) CALCULATE(SUM(fact[amount]),fact[information]="Units Sold")), but cannot get that denominator applied against all numerators.

x x x x

Adding follow up based on the answer provided below...

Issue #1: The solution provided below works when I am looking at Total Expenses, but in reality the Expense line will be multiple lines (Salary, Benefits, Rent, etc.) and I need to be able to calculate each per Unit Sold. The solution doesn't seem to allow for this.

Issue #2: The fact table currently has four different information types ... Expenses (broken out as noted above), Units Sold, Headcount and Square Footage. What I would like to be able to do is have Expenses per Until Sold, Headcount per Unit Sold, etc. In other words, a denominator that can be applied against all rows which then can be summed in the pivot table easily. The solution takes everything that is not Units Sold, sums it and then divides by Units Sold... blending Expenses, Headcount and Square Footage.

Thanks again for the assistance.

Joshua
  • 40,822
  • 8
  • 72
  • 132

1 Answers1

1
SumAmt:= SUM( FactTable[Amount] )

UnitsSoldDenominator:=
DIVIDE(
    CALCULATE(
        [SumAmt]
        ,FILTER(
            VALUES( FactTable[Information] )
            ,FactTable[Information] <> "Units Sold"
        )
    )
    ,CALCULATE(
        [SumAmt]
        ,FactTable[Information] = "Units Sold"
    )
)

This will give the behavior you want.

It's worth taking some time to explain why our filter arguments to CALCULATE() are different in the numerator and the denominator.

CALCULATE() with a literal predicate, like we see in the second argument to DIVIDE() is implicitly rewritten to the following:

CALCULATE(
    [SumAmt]
    ,FILTER(
        ALL( FactTable[Information] )
        ,FactTable[Information] = "Units Sold"
    )
)

FILTER() simply iterates over the table passed to it in argument one and returns the rows from that table for which argument two returns true.

With the implicit ALL() there, then there is no context preserved from the pivot table.

VALUES() evaluates the table or column reference in filter context. Thus when we evaluate VALUES( FactTable[Information] ), we get back only the value in context in the pivot table. In any given year, we get back every label that exists in that year, at the grand total we get every label. At the "Units Sold" level, we get back nothing, because we're filtering that out.

Here's an image of a pivot table with the expected behavior based on your sample data and this measure.

enter image description here

Edit for dimension table

UnitsSoldDenominator:=DIVIDE(
    CALCULATE(
        [SumAmt]
        ,FILTER(
            VALUES( DimInformation[Information] )
            ,DimInformation[Information] <> "Units Sold"
        )
    )
    ,CALCULATE(
        [SumAmt]
        ,DimInformation[Information] = "Units Sold"
    )
)

This depends on an active relationship being defined between FactTable and DimInformation. I've defined mine on a numeric [InformationKey].

The image below includes my sample data based on what you provided in the original question, plus a mocked up dimension inferred from the same. The pivot table is shown along with the expanded field list. The relationships in my model are displayed in the manage relationships dialog in the Power Pivot window. I am seeing the same behavior as writing the original measure I provided against FactTable[Information] with the new version written against DimInformation[Information].

Please let me know if your model is configured the same and you are unable to reproduce this.

enter image description here

Edit 2 for hierarchy

UnitsSoldDenominator:=DIVIDE(
    CALCULATE(
        [SumAmt]
        ,FILTER(
            DimInformation
            ,DimInformation[Information] <> "Units Sold"
        )
    )
    ,CALCULATE(
        [SumAmt]
        ,ALL( DimInformation )
        ,DimInformation[Information] = "Units Sold"
    )
)

Here we've added a call to ALL( DimInformation ) in the denominator. This is because we will have filter context in the pivot table from DimInformation[InformationGroup] and DimInformation[Information]. The filter predicate in CALCULATE(), the DimInformation[Information] = "Units Sold", implicitly strips filter context that exists on DimInformation[Information], but when we put DimInformation[InformationGroup] into the pivot table, it provides a new set of filter context (all filter contexts are evaluated in a logical and).

Thus we're looking for (in the example in the image below) DimInformation[InformationGroup] = "Expense" (this is the context which is provided by the pivot table) && DimInformation[Information] = "Units Sold". This is not possible in our data so the denominator would be blank.

Thus we strip the filter context from all of DimInformation, and then evaluate our literal predicate.

enter image description here

greggyb
  • 3,728
  • 1
  • 11
  • 32
  • Thanks for the quick response... I feel like I am getting closer to what I need, but not quite there. I will add a few notes in my original question clarifying the issues I am seeing. – user5708627 Dec 22 '15 at 23:15
  • Did you look at the pivot table in the screenshot I provided? VALUES() evaluates in the filter context. Thus, when a specific value of [Information] is in context (like when it's used as a row label), then the values in amount associated to that specific [Information] are summed. Could you please test the solution provided and tell me if it does not meet your needs? Based on your description, this is what you want. – greggyb Dec 23 '15 at 01:07
  • After trying a bunch of things, I see where my problem is coming in, but am lost as to what is causing it and whether I can address it. In the data model I have, the Information field links to a dimension table. To make the model easier to use, the Fact[Information] field has been made not visible, while the dim_Information[Information] field is used. When I use the dim_Information[Information] field in my pivot, I get nothing but a total (which prompted my initial response). When I unhide the FactTable[Information] field and use that, it works just as you noted. Ideas on how I could address? – user5708627 Dec 23 '15 at 01:32
  • If I can get that one issue addressed, I think I am on my way. Thanks again! – user5708627 Dec 23 '15 at 01:33
  • Updated answer with edits for the measure to be written against a dimension - the logic is unchanged. – greggyb Dec 23 '15 at 02:17
  • This is great... I need to spend some time with the formulas so I understand moving forward though. I hate to ask a follow up question so quickly, but I've got a long flight tomorrow and would love to get some dashboards done on the flight... and since the logic hasn't quite clicked will see if you can help. My model is essentially like yours above and calculates the cost per just as hoped. However, it doesn't calculate for attributes. An example... assume your Information 1 is really Expenses Direct and Information 3 is really Expenses Indirect. Column C would then have them both roll up – user5708627 Dec 23 '15 at 03:12
  • to Total Expenses. This approach only calculates the cost per at the lowest level (column B) and not at the roll up. I don't follow why that is, but would appreciate any thoughts. Thanks. – user5708627 Dec 23 '15 at 03:16
  • If I'm understanding correctly, you want multiple distinct values of DimInformation[Information] to roll up to logical groupings. You can achieve this with a hierarchy. You would have an additional field in DimInformation with the higher level grouping. This would require a minor modification of the measure. See a new edit for this. – greggyb Dec 23 '15 at 03:48
  • I do already have the hierarchy set up. Will look at your solution in the AM and mark as question as answered, but a quick review of the results looks perfect. – user5708627 Dec 23 '15 at 04:36