How to add an if statement in a DAX formula measure? - excel

I am new to DAX and have created two measures to get the total pay per employee then lookup that total pay into a table and return a value in my Power Pivot.
Total Pay Measure:
NMRPaySum:=SUMX(Pay,[Regular Pay]+[Overtime Pay]+[Other Pay])
Range Lookup Measure:
SSSContributionEE :=
CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
)
)
However, I need the range lookup to only calculate if the employee type is satisfied.
The logic for it is below:
If Employee[Type]="Regular" Then
Calculate SSSConbtributionEE
Else
0
End If
I have tried this DAX formula, but doesn't seem to be working:
=
IF (
OR ( Salary[Type] = "Regular", Salary[Type] = "Agency" ),
CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
)
),
0
)
NMRPay Table:
SSS Contribution Table:
Employee Information Table:

Use your measure as is, for all the data. You then build a Pivot table, where you can use a filter or slicers on Employee Type to exclude unwanted values. Add the measure to the Values area and it will only calculate for data that is in the rows and columns of the pivot table.

For the OR condition, you should be able to add that as another filter:
= CALCULATE (
VALUES ( SSSContribution[EE] ),
FILTER (
SSSContribution,
[NMRPaySum] >= SSSContribution[Lower Bound] &&
[NMRPaySum] <= SSSContribution[Upper Bound]
),
FILTER (Salary, Salary[Type] = "Regular" || SalaryType = "Agency")
)
This may or may not work depending on your exact data model / relationship structure, but it might point you in the right direction. It's possible you need to use RELATED / RELATEDTABLE, but I'm not sure without being able to play with it myself.

Related

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

DAX formula working in Power BI but not on Power Pivot

The following DAX formula works on Power BI but not on Power Pivot (don't show error but blank cells) using the same exact data model (checked this many times).
It's used in a calculated column.
Actual Units SO =
CALCULATE (
SUM ( COM_SellOut[QuantitySold] ),
FILTER ( COM_SellOut, COM_SellOut[Date] >= TMK_Promotion[FromDate] ),
FILTER ( COM_SellOut, COM_SellOut[Date] <= TMK_Promotion[ToDate] ),
FILTER ( COM_SellOut, COM_SellOut[ProductCode] = TMK_Promotion[ProductCode] ),
FILTER ( COM_Customers, COM_Customers[id] = TMK_Promotion[Customer] )
)
A little context: this formula iterates a promotion table and calculates the units sold of a given product, in a given customer between a given period. Works flawlessly in PowerBI but not on PowerPivot.
Any ideas of what could be causing the problem?
Thanks in advance!
Power Pivot and Power BI use the same engine, so the same version DAX works in both applications. Are you using a colon (Actual Units SO :=) in front of your equal sign (no space). In Power Pivot it's a must whereas in Power BI it's optional. I see in your example there is no colon, so your DAX measure won't work in Power Pivot. It's a syntax issue not a model or DAX issue.
Actual Units SO :=
CALCULATE (
SUM ( COM_SellOut[QuantitySold] ),
FILTER ( COM_SellOut, COM_SellOut[Date] >= TMK_Promotion[FromDate] ),
FILTER ( COM_SellOut, COM_SellOut[Date] <= TMK_Promotion[ToDate] ),
FILTER ( COM_SellOut, COM_SellOut[ProductCode] = TMK_Promotion[ProductCode] ),
FILTER ( COM_Customers, COM_Customers[id] = TMK_Promotion[Customer] )
)
I think you can get a better performance by using logical and in one filter rather than nesting your filters :
Actual Units SO =
CALCULATE (
SUM ( COM_SellOut[QuantitySold] ),
FILTER ( COM_SellOut, COM_SellOut[Date] >= TMK_Promotion[FromDate]
&& COM_SellOut, COM_SellOut[Date] <= TMK_Promotion[ToDate]
&& COM_SellOut, COM_SellOut[ProductCode] = TMK_Promotion[ProductCode]
&& COM_Customers, COM_Customers[id] = TMK_Promotion[Customer]
)
)

DAX sum of multiplication (sumproduct) across multiple tables

I am struggling with what I think is a really silly problem.
I am trying to get "MTD target" values from an arbitrary date selection. I have a table 'out' which has many dimensions +date, as well as a target table which gives me a constant target value per day, for each month. My goal is to get the number of days selected per EACH month and multiply it by the corresponding daily target for the relevant month.
For example, month 1 daily target is 2, month 2 daily target is 4. I have 4 days in month 1, and 3 days in month 2. My cumulative target should be 2*4+3*2 = 14.
I can do this for a single month no problem. But as soon as I have a date range selected that crosses 2 or more months it all goes to hell.
Table 'out' has date, country, and other dimensions.
Table 'targets' has a year, month, and country dimensions.
I am trying to get some join and multiplication that is something like SUM(month_country * selected_days)
Here are the DAX measures I've tried:
mtd_inv_tgt :=
CALCULATE (
SUM ( targets[daily_spend] ),
FILTER (
targets,
targets[market] = FIRSTNONBLANK ( out[co_market], "" )
&& targets[yyyymm] >= MIN ( out[yyyymm] )
&& targets[yyyymm] <= MAX ( out[yyyymm] )
)
)
* DISTINCTCOUNT ( out[date] )
mtd_inv_tgt :=
SUMX (
FILTER (
targets,
targets[market] = FIRSTNONBLANK ( out[co_market], "" )
&& targets[yyyymm] >= MIN ( out[yyyymm] )
&& targets[yyyymm] <= MAX ( out[yyyymm] )
),
targets[daily_spend] * DISTINCTCOUNT ( out[date] )
)
This works fine if the dates selected belong to one month. If I select 2 months it will add the daily spend across 2 months and then multiply it by the number of dates covering the 2 months. Like from the above example it would be (2+3)*(4+2) = 30, which is obviously wrong.
The caveat is I can't use SUMX on the 'out' table because there are many records per date+country, whilst the targets are a single entry per month+country.
I think something similar to this should work:
mtd_inv_tgt :=
SUMX (
VALUES ( out[date] ),
LOOKUPVALUE (
targets[daily_spend],
targets[yyyymm], SELECTEDVALUE ( out[yyymm] )
)
)
This iterates over each distinct out[date] value in the current filter context and adds up the daily_spend for each of those dates that it looks up by matching on yyymm.
Iterating over only the yyymm might be more efficient:
mtd_inv_tgt :=
SUMX (
VALUES ( out[yyymm] ),
DISTINCTCOUNT ( out[date] )
* LOOKUPVALUE (
targets[daily_spend],
targets[yyyymm], EARLIER ( out[yyymm] )
)
)
Note: If these don't work as expected, please provide sample data to check against as I haven't actually tested these.

How I can find percentage out of subtotals with multiple columns in Pivot table

How I can find percentage out of subtotals with multiple columns in Pivot table.
PercentYes :=
CALCULATE ( SUM ( MyTable[value] ), MyTable[answers] = "yes" ) /
CALCULATE (
SUM ( MyTable[value] ),
ALL ( MyTable[subcategory], MyTable[answers] )
)
I created a sample of values
I would first create a sum measure:
Sum of Values:=SUM(MyTable[Value])
Then, I would create the percentage measure:
Percent of Values :=
DIVIDE (
[Sum of Values],
CALCULATE (
[Sum of Values],
ALL ( MyTable[Subcategory],MyTable[Answers] )
)
)
Using DIVIDE will help with error trapping zeroes in the denominator. The result looks like this:

how to apply Calculate function with two filters in DAX to get the Running Sum

I would like to get the running sum of [Days Past Due] Column grouped by project number and for each project number, get the value for each phase/end date.
IN SQL I would do:
SELECT Project_number
,phase
,Sum(Days Past Due) RunningTotal
FROM Table
GROUP BY Project_number
,phase
ORDER BY Project_number
,phase
I would do something similar in DAX please.
I try that:
CALCULATE (
SUM ( DataSource[Days Past Due] ),
ALLEXCEPT ( DataSource, DataSource[Project Number] )
)
It gives me the total for each project number repeated in the 4 rows. That's not what I want exactly. I need to apply a second filter on that.
Please look at the attachment, it has the last column with the desired output.
Thank you in advance for your suggestions.
You can adjust your attempt like this:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
)
)
Note that you can include more filtering conditions in the FILTER function by joining more conditions with &&. You can add more filter conditions inside CALCULATE as well. Here's an example:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= MAX( DataSource[End Date] )
&& DataSource[Start Date] > DATE( 2018, 12, 31 )
),
DataSource[Phase] = "Scope"
)
The documentation for CALCULATE and FILTER might be useful for further clarification:
https://dax.guide/calculate/
https://learn.microsoft.com/en-us/dax/calculate-function-dax
https://dax.guide/filter/
https://learn.microsoft.com/en-us/dax/filter-function-dax
If you are trying to write this formula in a calculated column, it will not work as expected and you will need to use EARLIER instead of MAX:
Cumulative Days Past Due =
CALCULATE(
SUM( DataSource[Days Past Due] ),
FILTER(
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= EARLIER( DataSource[End Date] )
)
)
The reason for this is that in a measure MAX is calculated within its local filter context but in a calculated column the context is different and you use EARLIER to refer to the earlier row context, that is, the End Date in the current row of the larger table (rather than the smaller FILTER table).
If you want something that works either as a measure or a calculated column, then #RADO's solution is pretty close and you can write this:
Cumulative Days Past Due =
VAR CurrDate =
CALCULATE( MAX( DataSource[Start Date] ) )
RETURN
CALCULATE(
SUM( DataSource[Days Past Due] ),
ALLEXCEPT( DataSource, DataSource[Project Number] ),
DataSource[End Date] <= CurrDate
)
In this version, the MAX works just as it did before in the first version above and it should also work in a calculated measure because wrapping the MAX in a CALCULATE performs a context transition that transforms the row context into a filter context corresponding to that single row.
You can drop the CALCULATE wrapper for just a measure and drop both the CALCULATE and MAX functions for a simpler calculated column. In either of these cases, this variable version is likely the more performant one since the ALLEXCEPT function is optimized to work efficiently within CALCULATE rather than having to instantiate a new table when using FILTER.
For further details on cumulative totals, I recommend DAX Patterns as a resource:
https://www.daxpatterns.com/cumulative-total/

Resources