Calculating Variance and Variance% in Dax - excel

In my PBIX File, I have measures that calculate Revenue, COGS, Gross Margin etc.
Revenue = Sum(Amt)
More measures that calculate value for Last year Revenue_LY, COGS_LY and GM_LY.
Revenue_LY = CALCULATE (
[Revenue],
FILTER (
ALL ( 'Date' ),
'Date'[FinYear]= MAX ( 'Date'[FinYear] ) - 1 && 'Date'[FinPeriod] = max('Date'[FinPeriod])
)
)
Now I need variance and variance% measures for each which compare data against last year and budget. The amount of measures is just getting too many.
Revenue_CY-LY = CALCULATE([Revenue],KEEPFILTERS(Versions[VersionCode] = "Act")) - CALCULATE([Revenue_LY],KEEPFILTERS(Versions[VersionCode] = "Act"))
Revenue_CY-LY% = IF([Revenue_CY-LY] < 0, -1, 1) *
IF(
ABS(DIVIDE([Revenue_CY-LY],[Revenue])) > 99.9,
"n/a",
ABS(DIVIDE([Revenue_CY-LY],[Revenue])*100)
)
Is there a way to summarize the measures used. I don't want to create individual measures of each variance.

Yes. You can create a dynamic measure.
First create Revenue, COGS, Gross Margin, etc. measures.
Revenue = SUM([Amt])
COGS = SUM([Cost])
Gross Margin = [Revenue] - [COGS]
...
Then you create a table with one row for each of your measures:
My Measures = DATATABLE("My Measure", STRING, {{"Revenue"}, {"COGS"}, {"Gross Margin"}})
The names don't need to align with your actual measures, but they will be displayed so make them presentable.
Then you create a measure on that table which will dynamically be the same as the selected row in the table:
Selected Measure = SWITCH(SELECTEDVALUE('My Measures'[My Measure], BLANK()), "Revenue", [Revenue], "COGS", [COGS], "Gross Margin", [Gross Margin], BLANK())
Next you go and create all the complicated time-intelligence measures using the [Selected Measure] as the base:
Dynamic_LY = CALCULATE (
[Selected Measure],
FILTER (
ALL ( 'Date' ),
'Date'[FinYear]= MAX ( 'Date'[FinYear] ) - 1 && 'Date'[FinPeriod] = max('Date'[FinPeriod])
)
)
And then you can do [Dynamic_CY-LY] and [Dynamic_CY-LY %] in a similar manner to the ones in your question, replacing references to the [Revenue] measure with references to the dynamic measures.
Now you can either use a slicer on the 'My Measures'[My Measure] column to dynamically change every instance of [Dynamic_CY-LY] and the other dynamic measures, or you can add a filter on each visualisation to filter 'My Measures'[My Measure].
It might be that you'd also like to have a default value for [Selected Measure] instead of defaulting to BLANK(); just put that in last position in the SWITCH() function.

Related

Power Pivot: Average by group using many-to-many table relationship

I have three tables in Power Pivot. Pupils, Baselines and Reports. The Pupils table connects to the Reports and Baselines tables via a One to Many relationship as shown below.
The Reports table has each pupil listed multiple times for each subject they have a report in. They are also listed multiple times in the Baselines table for each baseline score they have. What I want to accomplish is to create a measure that calculates the average baseline score in each subject. So take all pupils who have a maths report, I want to know the average baseline score in maths.
I tried the following measure:
Av Baseline:=AVERAGEX( CALCULATETABLE( Baselines, Baselines[Type] = "Overall" ), Baselines[Average] )
However the above when used in a pivot table produces the same result for all subjects, so the filter context is not being applied. I keep hearing people using bridge tables, which does add a ton of data and are not very efficient so I hope to avoid those if at all possible.
I have provided some example data with the desired output table, hope that helps?
Could you please test this:
Note: I hope Your Pupils table has a column called [Subject Code] It is not clear from your shared data.
Version - 1
Av Baseline :=
AVERAGEX (
VALUES ( Pupils[Subject Code] ),
CALCULATE (
SUM ( Baselines[Average] ),
CALCULATETABLE ( Baselines, Baselines[Type] = "Overall" )
)
)
Version - 2
Av Baseline =
VAR Combin =
SUMMARIZE (
Baselines,
Baselines[Type],
Pupils[Subject Code],
Baselines[Result]
)
VAR Combinfiltered =
FILTER ( Combin, Baselines[Type] = "Overall" )
VAR Result =
CALCULATE ( AVERAGE ( Baselines[Result] ), Combinfiltered )
RETURN
Result

Return DAX Measure created from Table VAR that ignores filter context

I have a table that looks like this:
I've loaded this into Excel PowerPivot and am trying to create a normalized/indexed column that I can use in pivot table. For reasons I wont go into, I'm trying to do this via a Measure vs a Calculated Column.
Here is the code for my Measure:
Measure 1:=VAR Group1 = GROUPBY('Test','Test'[Country],'Test'[Date],"Visits1", SUMX(CURRENTGROUP(),'Test'[Visits])) VAR Group2 = GROUPBY(Group1,[Country],"Visits2", MAXX(CURRENTGROUP(),[Visits1])) RETURN CALCULATE(MAXX(Group2,[Visits2]),ALL('Test'[Date]))
I'm pretty novice with DAX, but this is what I assume is happening when I create my Table VARs:
Using this Measure, when I go and create a Pivot Table, I get this (I've manually added the yellow columns):
As you can see, 'Measure 1', does not equal my 'Expected' column. I've tried a whole bunch of ways to use ALL() in my RETURN statement, but I cannot get it to work. Can anyone help?
Oh, and once I achieve this my goal was to indexed value as seen in my final yellow column using the pseudo formula below.
Row value / Max column value (but filtered by country) * 100
[measure] :=
VAR MaxVisits =
CALCULATE (
MAXX ( VALUES ( Visits[Date] ), CALCULATE ( SUM ( Visits[Visits] ) ) ),
ALL ( Visits[Date] )
)
VAR CurrentVisit =
CALCULATE (
MAXX ( VALUES ( Visits[Date] ), CALCULATE ( SUM ( Visits[Visits] ) ) )
)
VAR Ratio =
DIVIDE ( CurrentVisit, MaxVisits ) * 100
RETURN
Ratio

Searching for DAX formula - equivalent to Excel SUMIF

I am searching for a DAX formula.
Specifically:
If SOLD (1st column) = count volume (second column), if not SOLD = 0
I need to reflect the volume of SOLD in a new column. UNSOLD Volumes should be 0.
I attach the reduced data set.
If I understand, you want to only perform aggregation when the SOLD_UNSOLD column is equal to "SOLD", otherwise return 0? If so, the following formula will do this, you'll just need to update the column names accordingly. The outer IF prevents problems resulting from further evaluation (i.e. grand totals) and it's necessary to wrap the column in the VALUES function as this will turn the column into a table of the unique values of it.
'YourTable'[CountOfSold] =
IF (
COUNTROWS ( VALUES ( YourTable[SOLD_UNSOLD] ) ) = 1,
IF (
VALUES ( YourTable[SOLD_UNSOLD] ) = "SOLD",
COUNT ( YourTable[ColumnToAggregate] ),
0
),
0
)
The Excel SUMIF is closest to the DAX SUMX.
I'm not positive I'm understanding what you are asking for, but I think you'd want something like this:
SOLD_VOLUME = SUMX(Table1,
IF(Table1[SOLD_UNSOLD] = "SOLD",
Table1[DAILY_VOLUME],
0
)
)
You could also do this with a filter:
SOLD_VOLUME = SUMX(
FILTER(
Table1,
Table1[SOLD_UNSOLD] = "SOLD"
),
Table1[DAILY_VOLUME]
)

DAX: Calculate the ratio of Metric A to a sibling Metric B (when both reside in the same group)

I am a complete noob to DAX and OLAP, so please, forgive any errors.
Story
Basically, I have a Matrix component in PowerBI Desktop report.
Months are on the columns, Metrics - on the rows:
The problem arises when I try to calculate the ratio of (percents in red):
Metric B to Metric A (B/A)
Metric C to Metric B (C/B)
All metrics reside in the same group. I wish these ratios be put as a separate, but one column.
I have no problems to calculate Metric ratio to total; I just take SUM(#) and divide by measure Total:
Total = CALCULATE(SUM('Data'[#]); ALL('Data'[Metric]))
Question
But how do I get a SUM(#) aggregate for Metric X which I could later use to calculate the ratio of other metrics?
What I've done so far
As one of the steps I created this table to get the aggregated # for Metric A:
Table = ADDCOLUMNS(
SUMMARIZE('Data';
'Data'[GroupAndMetric];
'Data'[Year];
'Data'[MonthNo]);
"Count";
CALCULATE(SUM('Data'[#]); 'Data'[GroupAndMetric] = "Group A - Metric A")
)
Any help appreciated.
I think there is an easier way to get your expected result but I am assuming your data is exactly the same as the posted in the OP.
Create the following measures to calculate the previous and current values in the given context of each metric.
Sum of [#]:
CurrentValue = SUM(Data[#])
Current Group
CurrentGroup = FIRSTNONBLANK(Data[Group],0)
Current Metric
CurrentMetric = FIRSTNONBLANK(Data[Metric],0)
Current Month:
CurrentMonth = FIRSTNONBLANK(Data[Month],0)
This calculates the previous Metric
PrevMetric =
IF (
[CurrentMetric] = "Metric A",
BLANK (),
IF (
[CurrentMetric] = "Metric B",
"Metric A",
IF ( [CurrentMetric] = "Metric C", "Metric B", BLANK () )
)
)
Calculate the previous metric sum of # necessary for the ratio calculation:
Previous # Sum =
CALCULATE (
SUM ( Data[#] ),
FILTER (
ALL ( Data),
COUNTROWS (
FILTER (
Data,
EARLIER ( Data[Metric] ) = [PrevMetric]
&& EARLIER ( Data[Group] ) = [CurrentGroup]
&& EARLIER ( Data[Month] ) = [CurrentMonth]
)
)
)
)
Finally calculate the ratio:
% Ratio = DIVIDE([CurrentValue], [Previous # Sum])
You will get a bunch of measures but you just have to use the % Ratio in the matrix:
Let me know if this helps.
There are probably (much) better ways of doing this, but here's one way:
To do a metric B divided by metric A (for example):
Metric B to Metric A =
DIVIDE (
CALCULATE ( SUM ( Data[#] ), FILTER ( Data, Data[Metric] = "Metric B" ) ),
CALCULATE ( SUM ( Data[#] ), ALL ( Data[Metric] ), Data[Metric] = "Metric A" ),
BLANK ()
)
The first CALCULATE (the numerator) returns blank if the pivot table isn't filtered to metric B. The second CALCULATE (the divisor) returns the sum of Metric A (following any other filters that are applied, so it won't sum up metric B's that are in another group for example, as long as group is on your pivot table). If we're looking at any metric other than B, this whole division will be BLANK because the numerator will be blank. The final BLANK says that if there are no metric A's (i.e. divide by zero), then the result will also be BLANK.
Assuming 2 measures like this, you could then combine them into a single column:
Final Ratio =
IF (
NOT ( ISBLANK ( [Metric B to Metric A] ) )
&& NOT ( ISBLANK ( [Metric C to Metric B] ) ),
BLANK (),
IF (
NOT ( ISBLANK ( [Metric B to Metric A] ) ),
[Metric B to Metric A],
IF (
NOT ( ISBLANK ( [Metric C to Metric B] ) ),
[Metric C to Metric B],
BLANK ()
)
)
)
This first part says, if both measures are not blank, return a blank (i.e. I don't want a group total that doesn't make sense). Then it goes through each metric and says if it isn't blank, display it. Otherwise, display blank. Since each underlying measure only returns a value for a single given metric, this should work.

How to have a measure lookup a value based on the row and column context?

I need to Aggregate a number of multiplications which are based on the Row and Columns context. My best attempt at describing this is in pseudo-code.
For each cell in the Pivot table
SUM
Foreach ORU
Percent= Look up the multiplier for that ORU associated with the Column
SUMofValue = Add all of the Values associated with that Column/Row combination
Multiply Percent * SUMofValue
I tried a number of ways over the last few days and looked at loads of examples but am missing something.
Specifically, What won't work is:
CALCULATE(SUM(ORUBUMGR[Percent]), ORUMAP)*CALCULATE(SUM(Charges[Value]), ORUMAP)
because you're doing a sum of all the Percentages instead of the sum of the Percentages which are only associated with MGR (i.e., the column context)
Link to XLS
One way of doing that is by using nested SUMX. Add this measure to ORUBUMGR:
ValuexPercent :=
SUMX (
ORUBUMGR,
[PERCENT]
* (
SUMX (
FILTER ( CHARGES, CHARGES[ORU] = ORUBUMGR[ORU] ),
[Value]
)
)
)
For each row in ORUBUMGR you will multiply percent by ....
the sum of value for each row in Charges where ORUBUMGR ORU is the same as Charges ORU. Then you sum that product.

Resources