Sum row with next row value and grab next value in other column for the date selected - row

Let's say I have this data:
Earn Earn Cum.
13-Apr - -
14-Apr 48 48
15-Apr 257 305
16-Apr 518 823
17-Apr 489 1,312
18-Apr 837 2,149
19-Apr 1,005 3,154
20-Apr 1,021 4,175
21-Apr 1,463 5,638
22-Apr 2,630 8,268
23-Apr 2,993 11,261
24-Apr 3,354 14,615
25-Apr 4,332 18,947
26-Apr 4,885 23,832
27-Apr 4,514 28,346
28-Apr 4,356 32,702
29-Apr 4,824 37,526
30-Apr 7,082 44,608
1-May 6,091 50,699
2-May 1,407 52,106
When a date is selected in a dropdown slicer for example: 1-May I'd like to sum the rows 1-May with the next row 2-May for the column Earn and grab the next value 52,106 for the column Earn Cum.. The result should be:
1-May 7,498 52,106
Another example: if the date selected was 30-Apr the result must be:
30-Apr 13,173 50,699
I'm scratching my head trying to do this using a measure in Power BI.

I'll call your table "Data".
Create a measure:
Next Earn =
VAR Current_Date = MAX ( Data[Date] )
VAR Next_Date = Current_Date + 1
RETURN
CALCULATE (
SUM ( Data[Earn] ),
Data[Date] = Current_Date || Data[Date] = Next_Date
)
Create another measure:
Next Cum Earn =
VAR Current_Date = MAX ( Data[Date] )
VAR Next_Date = Current_Date + 1
RETURN
CALCULATE ( SUM ( Data[Earn Cum] ), Data[Date] = Next_Date )
Result:
Note: the code assumes that your dates are sequential (no gaps). If they have gaps, things are a bit more complex.

It will help to have access to date intelligence, so create a date table if you don't have one already. The following dax sets up a small table that just barely covers the sample data in your example.
Date = CALENDAR(Date(2019,4,10),Date(2019,5,5))
Create a relationship between the Dates in your table and the new Date dimension. Add a slicer to your visuals using the Date dimension.
We can use IF and ISFILTERED to check if filtering is being done. If we aren't filtering on Date then we get the normal table behavior. If we are, we'll see our modified result.
Earn _ Alt =
var tomorrow = CALCULATE (
SUM(Table1[Earn]),
dateadd('Table1'[Date], 1, DAY)
)
return Sum(Table1[Earn]) + IF(ISFILTERED`('Date'[Date]),tomorrow,0)`
and
Earn Cum. _ Alt = IF(ISFILTERED('Date'[Date]),
CALCULATE (
SUM(Table1[Earn Cum.]),
dateadd('Table1'[Date], 1, DAY)
),
SUM(Table1[Earn Cum.]))
Results:
-Unfiltered-
-Filtered-

Related

Power BI DAX - Dynamically Calculate Distinct Count of Patients with Most Recent Value Less Than 9

I have a table of a1C values structured in this way:
patientID Result_Date Value
A 1/1/2021 5
B 3/3/2021 9
C 5/5/2021 4
A 3/1/2021 9
B 6/1/2021 13
A 7/1/2021 4
C 4/8/2022 12
etc...
I need to create a DAX measure that will dynamically calculate the distinct count of patients who have a value less than 9 as their last value as well as the distinct count of all patients in the population from the past 12 months of whatever date range is filtered. This is so I can calculate % a1c < 9. I have a calendar table in this data model so the idea is that as a user selects a fiscal month, the measure would dynamically calculate the % of distinct patients with an a1C less than 9 as their latest value over the past 12 months. I cannot share the actual dataset per HIPAA
Here are a few examples of the work I tried to do just to get a table of patients with their most recent date and most recent value as I figure that is the first step. I have been unsuccessful. Thank you for any help you can provide!
VAR summaryTable =
VAR patientID = VALUES(A1c[patientID])
VAR results = FILTER(A1c, A1c[patientID] = patientID)
VAR MaxDate = CALCULATE( MAX(A1c[Result_Date]), results)
RETURN
CALCULATETABLE(A1c, FILTER(results, A1c[Result_Date] = MaxDate)
/*ADDCOLUMNS(SUMMARIZE(A1c, A1c[patientID], "ValueDate", MAX(A1c[Result_Date]))
// , "LastValue", LOOKUPVALUE(A1c[Value_Formatted], A1c[Result_Date], FORMAT("ValueDate", "MM/DD/YYYY"), A1c[patientID], "patientID"))
// does not run due to formatting of columns; attempted to format but still doesn't work
//ADDCOLUMNS(VALUES(A1c[patientID]), "ValueDate", MAX(A1c[Result_Date]))
/* ADDCOLUMNS (
VALUES ( A1c[patientID] ),
"#outer val",
SELECTCOLUMNS (
TOPN ( 1, 'A1c', MAX(A1c[Result_Date]) ),
"#val", 'A1c'[Value_Formatted]
)) */)
lessThanNine =
VAR patientlastDates=
ADDCOLUMNS(
VALUES(tbl[patientID])
,"lastdate",LASTDATE(tbl[Result_Date])
)
VAR patientLastValue =
ADDCOLUMNS(
patientlastDates
,"lastValue", VAR currentP=[patientID]
VAR currentD=[lastdate]
RETURN
CALCULATE(
MAX(tbl[Value])
,tbl[patientID]=currentP
,tbl[Result_Date]=currentD
)
)
VAR filtered=
FILTER(
patientLastValue
,[lastValue]<9
)
RETURN
COUNTROWS(filtered)
Distinct count as below:
patientsWithinTimeFrame=
IF(
ISFILTERED('tbl'[Result_Date])
,COUNTROWS(VALUES('tbl'[patientID]))
,COUNTROWS(
CALCULATETABLE(
VALUES('tbl'[patientID])
,DATESINPERIOD(
'tbl'[Result_Date]
,MAX('tbl'[Result_Date])
,-1
,year
)
)
)
)

Rank and Rank Increment/Decrement from selected week vs previous week

I have a table visual with branch, client and revenue information. The revenue is coming from a measure which is affected by the week selector slicer.
I need to show Rank for selected week and rank increment/decrement from selected week's rank vs previous week from selected week. In snapshot, Rank # and Rank are the requirements.
I tried to create rank with AllSelected function but it is always affected by week slicer and I cannot get previous week rank to compare and put Rank increment/decrement.
DAX I tried for Rank
This Week GP =
var _Total =
CALCULATE(
SUM(V_TopClients[revenue]),
DATESBETWEEN('Date'[date],[current_week_start_date], [current_week_end_date])
)
return _Total
Previous Week GP =
var _Total =
CALCULATE(
SUM(V_TopClients[revenue]),
DATESBETWEEN('Date'[date],[previous_week_start_date], [previous_week_end_date])
)
return _Total
Rank This Week =
RANKX(
ALLSELECTED(V_TopClients),
CALCULATE(SUM(V_TopClients[Revenue])
)
)
--Update: added dax for measures
Here I am able to get the rank for this week i.e. the week selected on slicer.
But unable to get rank for previous week.
I have v_TopClients that has weekly revenue information linking to dimCalendar, Date tables.
Here is another and probably the best option for you-
Step-1:
Create a new custom table based on your table "TopClient". The code is as below-
group_by_result_new =
VAR group_wise_revenue =
GROUPBY (
TopClients,
TopClients[CalendarWeekKey],
TopClients[clientID],
"gp_this_week", SUMX(CURRENTGROUP(), TopClients[GrossProfit])
)
RETURN
SELECTCOLUMNS (
group_wise_revenue,
"CalendarWeekKey", TopClients[CalendarWeekKey],
"clientID", TopClients[clientID],
"gp_this_week", [gp_this_week]
)
Step-2:
Create relation between table "DimCalendar" and "group_by_result_new" using the column "CalendarWeekKey"
Step-3:
Create a new column (remember it a column) as below-
gp_prev_week =
VAR client_id = group_by_result_new[clientID]
VAR calendar_key_this_week = group_by_result_new[CalendarWeekKey]
VAR end_date_this_week =
LOOKUPVALUE(
DimCalendar[WeekEndingDate],
DimCalendar[CalendarWeekKey], CONVERT(calendar_key_this_week,INTEGER)
)
VAR end_date_prev_week = CONVERT(end_date_this_week,DATETIME) - 7
VAR calendar_key_prev_week =
LOOKUPVALUE(
DimCalendar[CalendarWeekKey],
DimCalendar[WeekEndingDate] , end_date_prev_week
)
VAR gp_prev_week =
LOOKUPVALUE(
group_by_result_new[gp_this_week],
group_by_result_new[CalendarWeekKey],calendar_key_prev_week,
group_by_result_new[clientID], CONVERT(client_id,INTEGER)
)
RETURN gp_prev_week
Step-4:
Create a new column (remember it a column) for RANK this week as below-
rank_this_week =
RANKX (
FILTER (
group_by_result_new,
group_by_result_new[CalendarWeekKey] = EARLIER (group_by_result_new[CalendarWeekKey])
),
group_by_result_new[gp_this_week],
,
DESC
// ,
// DENSE
)
Step-5:
Create a new column (remember it a column) for RANK prev week as below-
rank_prev_week =
RANKX (
FILTER (
group_by_result_new,
group_by_result_new[CalendarWeekKey] = EARLIER (group_by_result_new[CalendarWeekKey])
),
group_by_result_new[gp_prev_week],
,
DESC
// ,
// DENSE
)
And that's all! This should also work same as my previous solution.
Cheers!!
In DAX, there are builtin function PREVIOUSMONTH, PREVIOUSQUARTER and PREVIOUSYEAR available. But as you are searching for weekly data comparison, you required your own date periods to calculate. I just can give you some idea as below-
First, crate 4 measure based on your slicer week/date selection.
Example:
current_week_end_date = SELECTEDVALUE(Dates[Date])
current_week_start_date = SELECTEDVALUE(Dates[Date]) - 7
previous_week_end_date = SELECTEDVALUE(Dates[Date]) - 8
previous_week_start_date = SELECTEDVALUE(Dates[Date]) - 15
Now, you need 2 separate measure to calculate this week and previous week total revenue. Example Measures are given below-
1.
this_week_revenue =
CALCULATE(
SUM(table[revenue]),
DATESBETWEEN(
'Dates'[Date],
[current_week_start_date],
[current_week_end_date]
)
)
2.
previous_week_revenue =
CALCULATE(
SUM(table[revenue]),
DATESBETWEEN(
'Dates'[Date],
[previous_week_start_date],
[previous_week_end_date]
)
)
Now you have both weekly value in your hand and you can compare measure "this_week_revenue " with measure "previous_week_revenue" to generate the directions indicators.
Hope this will help!
Below image is just for reference:

Opening closing out of ledger data

I have ledger data in which I have three columns
Item, Posting date, Qty
How can I return Opening, In, Out, Closing using dax of each item for 30 days?
SQL code in which I am doing as on date
case
when Sum(ILE.Quantity) over (order by ILE.[Item No_]) < 0
and ILE.[Posting Date] = #DateTo
then -Sum(ILE.Quantity) over (order by ILE.[Item No_])
else 0
end AS [Out Quantity],
case
when ILE.[Posting Date] < #DateTo
then Sum(ILE.Quantity) over (order by ILE.[Item No_])
else 0
end AS [Opening]
Sample Data https://docs.google.com/spreadsheets/d/1N3qg3F7fW1NB6Z3-ZIg-RAidGBlIwzma8DZbeMjLF20/edit?usp=sharing
Import your Rawdata in Power BI
Create a Calendar table
Linked them
Create 5 measures :
Qty = Sum(Rawadata[Quantity])
Qty In = CALCULATE([Qty]; Rawadata[Quantity]>0)
Qty Out = CALCULATE([Qty]; Rawadata[Quantity]<0)
Final Sold =
Var DateInContext = MAX('Calendar'[Date])
RETURN
CALCULATE(
[Qty];
All('Calendar');
'Calendar'[Date]<= DateInContext
)
Initial Sold = CALCULATE([Final Sold],DATEADD('Calendar'[Date];-1;DAY)
)
Then you can build a table with these measures.
Here is the final result :
FYI, the same approach also works in Excel's Power Pivot.

How to find DateDiff from same column with condition in Power BI

I am having one table in PowerBI which is having 3 columns: 1.EnrollId 2.Status 3.StatusChangeDate. One EnrollId is having 4 statuses and their particular statusChangeDates. I want to find no. of days between two dates with status condition.
EnrollId Status StatusChangeDate
101 AppStart 15/02/2019
101 Application 27/03/2019
101 Enrollment 03/04/2019
101 Complete 28/04/2019
I want to create formula in DAX like
[StatusChangeDate (where Status="Enrollment") - StatusChangeDate(where status="AppStart)]
or
[StatusChangeDate (where Status="Complete")- StatusChangeDate(where status="Enrollment)]
i.e. 03/04/2019 - 15/02/2019 = 44 Days
28/04/2019 - 03/04/2019 = 25 Days
My advice is go for a Calculated Column, you can try and adjust this to a measure but there is more factors to consider regarding the filter context.
For a calculated column:
DaysLastChange =
VAR _currentStatusChangeDate = [StatusChangeDate]
VAR _currentEnrollId = [EnrollId]
RETURN
DATEDIFF(
CALCULATE(MAX('Table1'[StatusChangeDate]);FILTER('Table1';_currentEnrollId = [EnrollId] && _currentStatusChangeDate > [StatusChangeDate] ));
_currentStatusChangeDate;
DAY
)
If you want measures, try something like this. For each period between two Statuses, you need to create another measure. When more than one [EnrollId] is selected, the measure returns a blank.
Days Enrollment - Complete =
VAR scDateEnrollment =
CALCULATE ( MAX ( 'Table'[StatusChangeDate] ), 'Table'[Status] = "Enrollment" )
VAR scDateComplete =
CALCULATE ( MAX ( 'Table'[StatusChangeDate] ), 'Table'[Status] = "Complete" )
RETURN
IF (
HASONEVALUE ( 'Table'[EnrollId] ),
DATEDIFF ( scDateEnrollment, scDateComplete, DAY )
)
Cardvisuals or a table-visual would look like this. As you can see the table-visual is not affected by the slicer.
EDIT
This is the table i used:

DAX to calculate cumulative sum column (year to date) for all individual products

I have 3 columns in a table: Date, Product, and Volume. Based on this is I want to calculate the cumulative sum (or YTD) column for each of the products.
I know that to calculate cumulative total we use:
YTD_Actual = CALCULATE(Sum(Combined[Actual Volume]),FILTER(Combined,Combined[Date] <= EARLIER(Combined[Date])))
But I want this to additionally filter individual products and do this calculation for that product.
The expected column is shown in the picture below:
As far as you manage to get the Month column in date format, the following works:
YTD =
VAR currProduct = Table1[Product]
VAR currMonth = Table1[Month]
VAR ytdTotal =
CALCULATE(
SUM(Table1[Volume]),
FILTER(
ALL(Table1),
Table1[Month] <= currMonth &&
Table1[Product] = currProduct
)
)
RETURN IF(NOT(ISBLANK(ytdTotal)), ytdTotal,0)
Result: