I just started using powerpivot.
Currently I have slicers that filter based on the values of one variable, but I also want to create a pivotchart where the user can select what variable to graph. Is there a way to populate one slicer with variables from a powerpivot table?
I have a handful of variables that a user might want to look at, and I do not want to have one graph for each variable.
I hope this makes sense. Any suggestions? Thanks & Cheers.
There is a solution to this that is pretty straightforward and although it's not perfect as it doesn't work dynamically, I've used it very successfully in this kind of situation where you are talking about selecting between a well defined set of metrics.
The technique makes use of a disconnected table to drive the slicer with the final formula using the selected value to decide which measure to use.
Lets say you have 2 measures [Sales] and [Profit] you want to choose between. You create a table in your PowerPivot model called, say, 'SlicerTbl' with a single column called Measure that has 2 rows 'Sales' and 'Profit'. No relationship is required. (the table can be called whatever you like btw).
You can then write a 3rd measure that enables you to choose which measure to use:
=
IF (
HASONEVALUE ( SlicerTbl[Measure] ),
SWITCH (
VALUES ( SlicerTbl[Measure] ),
"Measure 1", [Measure 1],
"Measure 2", [Measure 2]
),
BLANK ()
)
This basically checks to see if the slicer has a single value and if so uses VALUES() to return the selected value - because of the initial clause this can only ever be a single row. This means it returns blank in the case of multiple selections.
The SWITCH() is basically an elegant IF() that is easy to scale so I don't see why you couldn't do this with 20+ measures very quickly.
Hope this helps, I created a stupidly simple example here: Example Model
Related
I have two tables that use a unique concatenated column for their relationship. I simply want to make a measure that uses the values from C4 of Table1. I thought I could use a simple formula like =values(Table1[C4]) but I get an error of "A table of multiple values was supplied where a single value was expected."
Side note: I realize the concatenation is unnecessary here in this simple example, but it is necessary in the full data I am working with which is why I added it into this example.
Here's a simplified set of tables for what I am trying to do:
Table1
Table2
Relationships
First you should think. Do I really need a Calculated column? Can't this be calculated at runtime?
But if you still want to do it, you can use RELATED or RELATEDTABLE.
Keep in mind if you are pulling from RELATEDTABLE, returns many values. So you should apply some type of aggregation like SUMX or MAXX.
You can use context transition to retrieve the value.
= CALCULATE(MAX(Table1[C4])
I'm quite new to using pivot tables and data models, so I don't even know if what I want to do is possible. I have a pivot table (PivotTable1) and its source (Table 25) and I would like to add a hundred or so measures which are listed in the TableCombinations.
For example, I entered the two first measure in orange, but they are not linked to TableCombination and entering them all one by one would be quite long. Each measure is for a distinct Sum wfn column that sums all other rows multiplied by a coefficient. The TableCombinations table simply states the coefficient to be used for each column. For the first three rows, these are my measure formulas :
sum wf1=1.4*Table25[Sum of wD]+0*Table25[Sum of wL]+0*Table25[Sum of wS]+0*Table25[Sum of wW]+0*Table25[Sum of wWSOUL]
sum wf2=1.25*Table25[Sum of wD]+1.5*Table25[Sum of wL]+1*Table25[Sum of wS]+0*Table25[Sum of wW]+0*Table25[Sum of wWSOUL]
sum wf3=1.25*Table25[Sum of wD]+1.5*Table25[Sum of wL]+0*Table25[Sum of wS]+0.4*Table25[Sum of wW]+0*Table25[Sum of wWSOUL]
...
Two questions :
Is there a way to link the tables so that any change made to TableCombination would then be updated in the pivot table measures?
Is there a way to generate all the of the measures without typing them in one by one.
You should be able to use just one DAX measure to do this, using the CROSSJOIN function.
Don't set up a relationship between the Tables, and drag # to the Columns area of the PivotTable. Then create this Measure:
=SUMx(CROSSJOIN(Table1,Table2),Table1[wD]*Table2[wD]+Table1[wL]*Table2[wL]+Table1[wS]*Table2[wS]+Table1[wW]*Table2[wW]+Table1[wWSOUL]*Table2[wWSOUL])
That should give you the exact answer you need.
Here's how it looks using some sample data:
...and here's the sample data I'm using:
You could certainly use VBA to add measures, and to update them when the Table changes. I might have a crack at writing up an answer along that approach shortly. But here's another way to achieve what you want.
I've previously written some code to slave a Table to a PivotTable, so that any change in the PivotTable's dimensions or placement will be reflected in the shadowing Table's dimensions and placement. This effectively gives us a way to add a calculated field to a PivotTable that can refer to something outside of that PivotTable. If the PivotTable grows, the Calculated Table will grow. If the PivotTable shrinks, the Calculated Table will shrink, and any redundant formulas in it will be deleted.
You can easily use this approach to perform your calculations in a 2nd table alongside your PivotTable, and each column x in that 2nd table could easily reference row x in your 'parameters' table.
See Select Newest Record and Create New Table of Unique Values in Excel
Due to performance issues I need to remove a few distinct counts on my DAX. However, I have a particular scenario and I can't figure out how to do it.
As example, let's say one or more restaurants can be hired at one or more feasts and prepare one or more menus (see data below).
I want a PowerPivot table that shows in how many feasts each restaurant was present (see table below). I achieved this by using distinctcount.
Why not precalculating this on Power Query? The real data I have is a bit more complex (more ID columns) and in order to be able to pivot the data I would have to calculate thousands of possible combinations.
I tried adding to my model a Feast dimensional table (on the example this would only be 1 column of 2 rows). I was hoping to use that relationship to be able to make a straight count, but I haven't been able to come up with the right DAX to do so.
You could use COUNTROWS() combined with VALUES().
Specifically, COUNTROWS() will give you the count of rows in a table. That means COUNTROWS is expecting a table is input. Here's the magic part: VALUES() will return a table as results, and the table it returns are the distinct values in the table/column that you provide as the argument for VALUES().
I'm not sure if I'm explaining it well, so for the sample data you provided, the measure would look like this (assuming the table is named Table1):
Unique Feasts:=COUNTROWS(VALUES('Table1'[Feast Id]))
You can then create a pivot table from Powerpivot, and drag Restaurant Id into Rows, and drag the measure above into Values. Same result as DISTINCTCOUNT, but with less performance overhead (I think).
I have 2 tables.
First table: dimensional table to show available units of cars at start of selling cycle and for how long these units will be available.
Second table: to show how many cars were sold on a given month within their "available cycle".
I'd like to compare the "selling behaviour" within each cycle. Thus, I want to display the total initial units available next to the units sold at each stage within the cycle. The second dimension works fine, but not the first one.
This is what I get:
And this the desired output (note rows 4 and 5 for available_units)
I tried the below DAX code without success:
SumAvailableUnits:=CALCULATE(SUM([available_units]),FILTER(ALL(Table1[month_within_cycle]),[month_within_cycle]>=MAX([months_available])))
First, DAX Formatter is your friend. You may like writing unreadable single line measures, but no one else likes reading them.
I've also taken the liberty of cleaning up your table names and adding fully qualified column references. (Ignoring that your dimension isn't a pure dimension, as it holds numeric values that you aggregate in a measure)
SumAvailableUnits :=
CALCULATE (
SUM ( DimCar[available_units] ),
FILTER (
ALL ( FactSale[month_within_cycle] ),
FactSale[month_within_cycle] >= MAX ( DimCar[months_available] )
)
)
And immediately we see a problem. With the fully qualified column references, it is clear that you're trying to filter the lookup table (the one side) by the base table (the many side). In Power Pivot for Excel, we do not have bi-directional relationships (though they're available in Power BI and coming for Excel 2016). Our relationships' filter context only flows from the lookup table to the base table, typically from the dimension to the fact.
Additionally, your DimCar, by holding [available_units] and [months_available] encodes an implicit assumption that a specific [car_id] can only ever refer to a single, unchanging lot. You will never see another row with [car_id] = 1. This strikes me as highly unlikely. Even if it is the case the better solution is a model change.
In general, anything that goes onto a row or column label should come from a dimension, not a fact. Similarly, anything you're aggregating in a measure should live in a fact table. The usual exception is dimension counts - either bare, or as a denominator in a measure. Following these will get you 80% of the way in terms of dimensional modeling. You can see the tables and model diagram I've ended up with in the image below.
Here are the measure definitions
SumAvailableUnits:=SUM( FactAvailability[available_units] )
SumSold:=SUM( FactSale[cars_sold] )
Here are my source tables, my model diagram with relationships, and a pivot table built from these pieces and the measures above. Note the source of [month_within_cycle] in the pivot.
Finally, you might notice that my grand total behaves in a different way than in your original. Since the values are repeated monthly, we get a much larger grand total. If you need to instead end with the sum from the latest month (which it looks like you have in your sample), you can use an alternate measure, provided below. I don't understand why this would be your desired grand total, but you can achieve it fairly easily. Personally, I'd probably blank the measure at the grand total level.
SumAvailableUnits - GrandTotal:=
SUMX(
TOPN(
1
,FactAvailability
,FactAvailability[month_within_cycle]
,0
)
,FactAvailability[available_units]
)
This uses SUMX() to step through the table provided, defined by TOPN(). TOPN() returns the first row (in this case) in FactAvailability, including ties, after sorting by [month_within_cycle], out of all rows available in the filter context. In the context of a specific month, you get all the rows associated with that month - identical to the simple sum. In the grand total context, you get the rows associated with the last month.
SUMX() iterates over that table and accumulates the values of [available_units] in a sum.
I have a spreadsheet corresponding to entries of a user, their estimation, and the actual value (for example: hours for a particular project - again, this is only an example), which we can represent in CSV like:
User,Estimate,Actual
"User 1",5,5
"User 1",7,7
"User 2",3,3
"User 2",9,8
"User 3",6,7
"User 3",8,7
I'm trying to build a report on these users, to quickly see which users underestimate or overestimate, and so I created a pivot table. But, I can't figure out how to simply show if a user has underestimated at some point. I tried to create a calculated field like =IF(Estimate > Actual, 1, 0), but this sums, then compares the Estimate and Actual columns and tells me that "User 3" doesn't over/underestimate.
Without adding an additional field to my data, how can I accomplish this?
A similar SQL pseudo-query would be:
SELECT DISTINCT al.User,
(SELECT COUNT(*) FROM ActivityLog AS l2 WHERE l2.User = al.User AND l2.Estimate > l2.Actual) AS Overestimates
FROM ActivityLog AS al
Edit:
I'm still working on this, and currently have created a static list of users in some cells on the side, and have given them the Array Formulas: {=SUM(IF((A$2:A20 = F6)*(B$2:B20 > C$2:C20), 1, 0))} and {=SUM(IF((A$2:A20 = F6)*(B$2:B20 < C$2:C20), 1, 0))} (if I have the user's name in F6).
Mainly, I want to do this where the list of users can populate dynamically from the main data.
Calculated fields in pivot tables stink. I would get rid of the pivot table and do it with formulas. Start a unique list of users in H15 and enter this in I15
{=MAX(($A$2:$A$7=H16)*($B$2:$B$7-$C$2:$C$7<>0))}
array entered. This will return 1 if they ever over or under estimated and zero if they never did. The downside is that you can't "refresh" it like a pivot table so you have to make sure your unique user list is accurate all the time.
If that's too big of a downside, I think you'll need to add a column to your source data. Specifically
=ABS(B2-C2)
And add that to your pivot table. It will show zero for never over/under and non-zero otherwise.
You are aware that you should make sure the estimates are all in the same range? Smaller numbers can be estimated better (when talking about hours).
Add a column for actual-estimate
then summarize those values for min max and average. (or stddev)