Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.

Reply
harshad_barge
Helper I
Helper I

Help with DAX code

Hi,

I have an excel output of a calculated DAX measure. The Calculated Pay (N) column is a sum of AUD Total Daily Earnings column, grouped by the Applicable Payroll Date. I want the Calculated Pay (Expected column to show the value only when the Applicable Payroll Date changes.
Many Thanks.

AUD Total Daily EarningsCalculatedPayCalculation DateApplicable Payroll DateCalculated Pay (N)Calculated Pay (Expected)
$327.81$2,031.341/09/2013 0:001/09/2013 0:002031.342031.34
$178.60$0.004/09/2013 0:0015/09/2013 0:001959.180
$185.73$0.005/09/2013 0:0015/09/2013 0:001959.180
$162.02$0.006/09/2013 0:0015/09/2013 0:001959.180
$228.94$0.007/09/2013 0:0015/09/2013 0:001959.180
$292.16$0.008/09/2013 0:0015/09/2013 0:001959.180
$151.95$0.0011/09/2013 0:0015/09/2013 0:001959.180
$151.96$0.0012/09/2013 0:0015/09/2013 0:001959.180
$151.96$0.0013/09/2013 0:0015/09/2013 0:001959.180
$189.94$0.0014/09/2013 0:0015/09/2013 0:001959.180
$265.92$1,959.1815/09/2013 0:0015/09/2013 0:001959.181959.18
$141.82$0.0018/09/2013 0:0029/09/2013 0:002063.780
$166.15$0.0019/09/2013 0:0029/09/2013 0:002063.780
$271.50$0.0020/09/2013 0:0029/09/2013 0:002063.780
$192.47$0.0021/09/2013 0:0029/09/2013 0:002063.780
$269.46$0.0022/09/2013 0:0029/09/2013 0:002063.780
$151.95$0.0025/09/2013 0:0029/09/2013 0:002063.780
$151.96$0.0026/09/2013 0:0029/09/2013 0:002063.780
$187.24$0.0027/09/2013 0:0029/09/2013 0:002063.780
$221.65$0.0028/09/2013 0:0029/09/2013 0:002063.780
$309.58$2,063.7829/09/2013 0:0029/09/2013 0:002063.782063.78
$151.96$0.0030/09/2013 0:0013/10/2013 0:002167.230
$171.93$0.001/10/2013 0:0013/10/2013 0:002167.230
$151.95$0.002/10/2013 0:0013/10/2013 0:002167.230
$289.32$0.005/10/2013 0:0013/10/2013 0:002167.230
$333.89$0.006/10/2013 0:0013/10/2013 0:002167.230
$405.20$0.007/10/2013 0:0013/10/2013 0:002167.230
$151.96$0.008/10/2013 0:0013/10/2013 0:002167.230
$141.82$0.009/10/2013 0:0013/10/2013 0:002167.230
$187.85$0.0010/10/2013 0:0013/10/2013 0:002167.230
$181.35$0.0011/10/2013 0:0013/10/2013 0:002167.232167.23
$169.19$0.0014/10/2013 0:0027/10/2013 0:002036.550
$184.08$0.0015/10/2013 0:0027/10/2013 0:002036.550
$173.75$0.0018/10/2013 0:0027/10/2013 0:002036.550
$247.18$0.0019/10/2013 0:0027/10/2013 0:002036.550
$285.67$0.0020/10/2013 0:0027/10/2013 0:002036.550
$151.96$0.0021/10/2013 0:0027/10/2013 0:002036.550
$151.96$0.0022/10/2013 0:0027/10/2013 0:002036.550
$151.96$0.0023/10/2013 0:0027/10/2013 0:002036.550
$254.88$0.0026/10/2013 0:0027/10/2013 0:002036.550
$265.92$2,036.5527/10/2013 0:0027/10/2013 0:002036.552036.55
$202.35$0.0030/10/2013 0:0010/11/2013 0:001928.30
$190.45$0.0031/10/2013 0:0010/11/2013 0:001928.30
1 ACCEPTED SOLUTION

OK, the failure here was that your sample data was not representative of your actual data. In your actual data, we have to account for Employee_ID. So, that can be done like this:

 

Result = 
    VAR __CalculatedPay = 'Sheet1'[Calculated Pay (N)]
    VAR __Next = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] > EARLIER('Sheet1'[Calculation Date]) &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculation Date]
        )
    VAR __NextPay = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] = __Next &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculated Pay (N)]
        )
RETURN
    IF(__CalculatedPay <> __NextPay,__CalculatedPay,0)

 

Updated PBIX is attached.

 


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

View solution in original post

17 REPLIES 17
Anonymous
Not applicable

I think your table is a table in the model, not a visual. So please use Power Query to do what you want. It's not only much much simpler but it IS THE WAY to do it.

Best
D
Greg_Deckler
Super User
Super User

OK, I may be mistaken but I believe you will need to add an Index column to your data table. Then you should be able to use a technique similar to MTBF as desribed here: See my article on Mean Time Between Failure (MTBF) which uses EARLIER: http://community.powerbi.com/t5/Community-Blog/Mean-Time-Between-Failure-MTBF-and-Power-BI/ba-p/3395...


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

So the excel formula works but in excel. How do I translate this logic to DAX?

 

=IF(AND(D2>=C2,E2<>E3),E2,0)

AUD Total Daily EarningsCalculatedPayCalculation DateApplicable Payroll DateCalculated Pay (N)Calculated Pay (Expected)Expected (Excel Formula)
$327.81$2,031.341/09/2013 0:001/09/2013 0:002031.342031.342031.34
$178.60$0.004/09/2013 0:0015/09/2013 0:001959.1800
$185.73$0.005/09/2013 0:0015/09/2013 0:001959.1800
$162.02$0.006/09/2013 0:0015/09/2013 0:001959.1800
$228.94$0.007/09/2013 0:0015/09/2013 0:001959.1800
$292.16$0.008/09/2013 0:0015/09/2013 0:001959.1800
$151.95$0.0011/09/2013 0:0015/09/2013 0:001959.1800
$151.96$0.0012/09/2013 0:0015/09/2013 0:001959.1800
$151.96$0.0013/09/2013 0:0015/09/2013 0:001959.1800
$189.94$0.0014/09/2013 0:0015/09/2013 0:001959.1800
$265.92$1,959.1815/09/2013 0:0015/09/2013 0:001959.181959.181959.18
$141.82$0.0018/09/2013 0:0029/09/2013 0:002063.7800
$166.15$0.0019/09/2013 0:0029/09/2013 0:002063.7800
$271.50$0.0020/09/2013 0:0029/09/2013 0:002063.7800
$192.47$0.0021/09/2013 0:0029/09/2013 0:002063.7800
$269.46$0.0022/09/2013 0:0029/09/2013 0:002063.7800
$151.95$0.0025/09/2013 0:0029/09/2013 0:002063.7800
$151.96$0.0026/09/2013 0:0029/09/2013 0:002063.7800
$187.24$0.0027/09/2013 0:0029/09/2013 0:002063.7800
$221.65$0.0028/09/2013 0:0029/09/2013 0:002063.7800
$309.58$2,063.7829/09/2013 0:0029/09/2013 0:002063.782063.782063.78
$151.96$0.0030/09/2013 0:0013/10/2013 0:002167.2300
$171.93$0.001/10/2013 0:0013/10/2013 0:002167.2300
$151.95$0.002/10/2013 0:0013/10/2013 0:002167.2300
$289.32$0.005/10/2013 0:0013/10/2013 0:002167.2300
$333.89$0.006/10/2013 0:0013/10/2013 0:002167.2300
$405.20$0.007/10/2013 0:0013/10/2013 0:002167.2300
$151.96$0.008/10/2013 0:0013/10/2013 0:002167.2300
$141.82$0.009/10/2013 0:0013/10/2013 0:002167.2300
$187.85$0.0010/10/2013 0:0013/10/2013 0:002167.2300
$181.35$0.0011/10/2013 0:0013/10/2013 0:002167.232167.232167.23
$169.19$0.0014/10/2013 0:0027/10/2013 0:002036.5500
$184.08$0.0015/10/2013 0:0027/10/2013 0:002036.5500
$173.75$0.0018/10/2013 0:0027/10/2013 0:002036.5500
$247.18$0.0019/10/2013 0:0027/10/2013 0:002036.5500
$285.67$0.0020/10/2013 0:0027/10/2013 0:002036.5500
$151.96$0.0021/10/2013 0:0027/10/2013 0:002036.5500
$151.96$0.0022/10/2013 0:0027/10/2013 0:002036.5500
$151.96$0.0023/10/2013 0:0027/10/2013 0:002036.5500
$254.88$0.0026/10/2013 0:0027/10/2013 0:002036.5500
$265.92$2,036.5527/10/2013 0:0027/10/2013 0:002036.552036.552036.55
$202.35$0.0030/10/2013 0:0010/11/2013 0:001928.300
$190.45$0.0031/10/2013 0:0010/11/2013 0:001928.31928.31928.3

 

Excel <> Power BI. Power BI cannot reference cells. But, pasting your Excel formula here might help. Power BI does not deal with cells, you have to filter your way to victory.


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

🙂

Here is the formula:

 

=IF(AND(D2>=C2,E2<>E3),E2,0)

 

Checks if the column is greater than other however, it also checks if previous row is equal to the next row (in the same column) So that is the catch that I would use help figuring out in DAX.

Right, you will definitely want an index column. Otherwise, Power BI is going to have no idea if one row comes before another. If you have an index column, you can do something like this for a calculated column in a table:

 

Column =
  VAR __NextID = [Index] + 1
  VAR __NextDate = MAXX(FILTER('Table',[Index] = __NextID),[Applicable Payroll Date])
RETURN
  IF([Applicable Payroll Date] <> __NextDate,<<some calculation goes here>>,BLANK())

@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Awesome! 
Firstly, how do I go about building that Index column. Note, this is a calculated measure hence I cannot go back to edit queries and add index there.

Thanks,

Harshad

Wait, why can't you add an Index column in your query? This is a calculated table?


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

@harshad_barge - You have essentially posted the same question to multiple threads. That is not good. It confuses things as you have different information in different threads. Makes it very difficult to help you. It is specifically called out as improper etiquette here How to Get Your Question Answered Quickly: https://community.powerbi.com/t5/Community-Blog/How-to-Get-Your-Question-Answered-Quickly/ba-p/38490. If you need to give a thread a visibility "bump", please post a new forum message with a link back to the original thread.

 

So, with all that said, I took a closer look at this, and this took a little bit of time because I had to convert your dates, but it seems that we can use your Calculation Date as a substitute for an Index. So I ended up with the below code. PBIX is attached.

 

Result = 
    VAR __CalculatedPay = 'Table'[Calculated Pay (N)]
    VAR __Next = 
        MINX(
            FILTER(
                'Table',
                'Table'[Calculation Date] > EARLIER('Table'[Calculation Date])
            ),
            'Table'[Calculation Date]
        )
    VAR __NextPay = 
        MINX(
            FILTER(
                'Table',
                'Table'[Calculation Date] = __Next
            ),
            'Table'[Calculated Pay (N)]
        )
RETURN
    IF(__CalculatedPay <> __NextPay,__CalculatedPay,0)

@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Hi Greg,

Sorry for the delayed response.

However, your DAX does not seem to work. It is still repeating values. 

That being said, i am intrigued how does the

EARLIER 

function work? Looks like we can use it to substitute the "row +1 " as excel does but, it seems to be not an efficient one for big datasets. (I will keep that in mind)
I am sorry for replicating the question. Really sorry.
However, I noted, i did not really frame my querstion and the example dataset completely. Hence, i saw the need to post fresh. Point taken to avoid doing that!.

Let me clarify further; the dataset i posted is a sample dataset of employees being paid. essentially, many employees get paid on any given day (Applicable Payroll Date and Calculation Date columns) hence, I am a bit unsure how would that work (treating that column as index)
Its a really tricky one right?
I love these challenges.
Thanks so much Greg! We will get to the solution. I can smell it!

@harshad_barge in the example PBIX file attached to my previous message, my column did not repeat values. Can you explain that in more detail? It seems to return exactly what you want in the column.

 

With regards to EARLIER, easily the worst named DAX function in existence. You should think of it is "current row". The reason it is called earlier is that it is referring to an "earlier" context than the one that you are creating. So, when you say something like:

 

FILTER(ALL('Table'),[Column] = EARLIER([Column]))

 

The way to read this is "create a new filter context using all of the rows in the table and then within this new context check each row to see if the [Column] in this new context matches the [Column] from the EARLIER context (which would be row context if this is a column).

 


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Hi Greg,

Please find the screenshot of the column I replicated.

The Result column is still repeating.

 

Capture.PNG

 

 

I don't see your column Calculation Date, where is that column? This is a screen shot from the PBIX I sent and am again attaching here that takes your sample data and replicates exactly the column you requested. The Result column is exactly the same as the Expected (Excel Formula). If however your Calculation Dates are descending instead of ascending like in your example data that could likely be the cause of the issue.

 

image.png

 

 


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Hi Greg,

Please find the dataset with anonymised names. 
The logic is essentially checking when the sum of "CalculatedPay" should be paid which is on/closest (before) to "Applicable Payroll Date".
The "Calculated Pay" column is missing that sum when the employee did not work on the applicable payroll date. and the Calculated Pay (N) column is doing the job but repeating values.
Please find the dataset here

Thanks !

OK, the failure here was that your sample data was not representative of your actual data. In your actual data, we have to account for Employee_ID. So, that can be done like this:

 

Result = 
    VAR __CalculatedPay = 'Sheet1'[Calculated Pay (N)]
    VAR __Next = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] > EARLIER('Sheet1'[Calculation Date]) &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculation Date]
        )
    VAR __NextPay = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] = __Next &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculated Pay (N)]
        )
RETURN
    IF(__CalculatedPay <> __NextPay,__CalculatedPay,0)

 

Updated PBIX is attached.

 


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Thanks a ton Greg!

This works.
If you can please explain the code, i would understand it much better.

 

Harshad

Sure, @harshad_barge glad we got there. I've probably spent a good 3 or 4 hours on this over the last couple days so an extra 15 minutes isn't going to break the bank. 🙂

 

Here is the code again for reference:

Result = 
    VAR __CalculatedPay = 'Sheet1'[Calculated Pay (N)]
    VAR __Next = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] > EARLIER('Sheet1'[Calculation Date]) &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculation Date]
        )
    VAR __NextPay = 
        MINX(
            FILTER(
                'Sheet1',
                'Sheet1'[Calculation Date] = __Next &&
                    'Sheet1'[Employee_ID] = EARLIER('Sheet1'[Employee_ID])
            ),
            'Sheet1'[Calculated Pay (N)]
        )
RETURN
    IF(__CalculatedPay <> __NextPay,__CalculatedPay,0)

 

So, this is a column thus we are in row context. The first line just grabs the value for the Calculated Pay (N) column in the current row and stores this in the variable __CalculatedPay.

 

Next we create the variable __Next. The purpose of this variable is to find the minimum next Calculation Date in the table that is greater than the current row's value for Calculation Date for the same employee that is in our current row. So, we FILTER our table using EARLIER. I described how EARLIER works earlier in the thread so I won't belabour how this works. We use MINX to grab the lowest (earliest - don't get confused) date from that filtered set. The filtered set includes all rows in the table for the current employee that have a Calculation Date that is greater than the current row's value for Calculation Date. 

 

Next, we use the same basic technique to find the value for the Calculated Pay (N) column that corresponds with the employee from our current row and the __Next date we just calculated. We store this value in the variable __NextPay.

 

In our RETURN statement, we now compare the value of our current row __CalculatedPay with the value of __NextPay. If the value is different, we return __CalculatedPay. If the value is the same, we return 0. The overall effect is that if we are at the maximum Calculated Date for a consistent Calculated Pay (N), then we return the value in our Calculated Pay (N) column for the current row because the very next Calculated Date in our table for the current employee the value for Calculated Pay (N) has changed. If we are in a row that is not the maximum Calculated Date for a consistent Calculated Pay (N) then we return 0 because the next Calculated Pay (N) is the same as our current row's value for Calculated Pay (N).

 

Hopefully that is clear. The logic is perhaps a bit tough to wrap your head around which is why this problem was very challenging.

 

 

 

 


@ me in replies or I'll lose your thread!!!
Instead of a Kudo, please vote for this idea
Become an expert!: Enterprise DNA
External Tools: MSHGQM
YouTube Channel!: Microsoft Hates Greg
Latest book!:
The Definitive Guide to Power Query (M)

DAX is easy, CALCULATE makes DAX hard...

Helpful resources

Announcements
Microsoft Fabric Learn Together

Microsoft Fabric Learn Together

Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.

Top Solution Authors