How to show previous month's growth rate, that also takes care of year change and Jan-Dec in Power BI using DAX? - powerbi

I want to calculate and show month on month growth rate in power bi, in both visual - Table and scorecard. In Table all the month should have their respective growth rate, except for current month (in some cases, otherwise can consider current month as well). And in scorecard if no month is selected from the slicer, current/previous month's growth rate should be visible. I had no issue before the year change.
Previously I used the following DAX to get the output:
MoM = VAR CurrentMonth = MONTH(TODAY())
VAR CurrentYear = YEAR(TODAY())
VAR LastYear = CurrentYear-1
VAR CurrentMonthPrice = CALCULATE([TotalPrice], FILTER(AllCommodities, AllCommodities[Year]=CurrentYear && MONTH(AllCommodities[Date])= CurrentMonth))
VAR LastYearMonthPrice = CALCULATE([TotalPrice], FILTER(AllCommodities, AllCommodities[Year]=LastYear && MONTH(AllCommodities[Date])= CurrentMonth))
VAR growth = DIVIDE(CurrentMonthPrice,LastYearMonthPrice)-enter image description here1
RETURN
IF(SELECTEDVALUE(AllCommodities[Commodities])="NA", "-", growth)
But due to year change, I'm unable to calculate the M-o-M rate. I tried using the following formula:
New MoM =
DIVIDE(
SUMX(FILTER(ALLSELECTED(trail), MONTH(trail[Date]) = MONTH(SELECTEDVALUE(trail[Date],NOW())) && YEAR(trail[Date]) = YEAR(SELECTEDVALUE(trail[Date],NOW()))), trail[Revenue]),
SUMX(FILTER(ALLSELECTED(trail), MONTH(trail[Date]) = IF(MONTH(SELECTEDVALUE(trail[Date],NOW()))=1,12,MONTH(SELECTEDVALUE(trail[Date],NOW()))-1) && YEAR(trail[Date]) = IF(MONTH(SELECTEDVALUE(trail[Date],NOW()))=1,YEAR(SELECTEDVALUE(trail[Date],NOW()))-1,YEAR(SELECTEDVALUE(trail[Date],NOW())))), trail[Revenue])) - 1
But it is only good for table visual and if a particular month is selected, it gives -100% error. which should not happen and give that particular month's growth rate.
How do I modify my DAX ?
Old DAX :
MoM = VAR CurrentMonth = MONTH(TODAY())
VAR CurrentYear = YEAR(TODAY())
VAR LastYear = CurrentYear-1
VAR CurrentMonthPrice = CALCULATE([TotalPrice], FILTER(AllCommodities, AllCommodities[Year]=CurrentYear && MONTH(AllCommodities[Date])= CurrentMonth))
VAR LastYearMonthPrice = CALCULATE([TotalPrice], FILTER(AllCommodities, AllCommodities[Year]=LastYear && MONTH(AllCommodities[Date])= CurrentMonth))
VAR growth = DIVIDE(CurrentMonthPrice,LastYearMonthPrice)-1
RETURN
IF(SELECTEDVALUE(AllCommodities[Commodities])="NA", "-", growth)
But it doesn't works for year change.
New DAX:
New MoM =
DIVIDE(
SUMX(FILTER(ALLSELECTED(trail), MONTH(trail[Date]) = MONTH(SELECTEDVALUE(trail[Date],NOW())) && YEAR(trail[Date]) = YEAR(SELECTEDVALUE(trail[Date],NOW()))), trail[Revenue]),
SUMX(FILTER(ALLSELECTED(trail), MONTH(trail[Date]) = IF(MONTH(SELECTEDVALUE(trail[Date],NOW()))=1,12,MONTH(SELECTEDVALUE(trail[Date],NOW()))-1) && YEAR(trail[Date]) = IF(MONTH(SELECTEDVALUE(trail[Date],NOW()))=1,YEAR(SELECTEDVALUE(trail[Date],NOW()))-1,YEAR(SELECTEDVALUE(trail[Date],NOW())))), trail[Revenue])) - 1
But it doesn't work with scorecard or if a month is selected from the slicer , it gives -100% error.
[![Output required][1]][1]
[1]: https://i.stack.imgur.com/7FIV3.png

Related

Power BI is there an equivalent of SUMX Filter to do a DISTINCTCOUNT

I have created the following code in Power BI to give me LY sales figures for any selected range.
Total Net Sales LY =
VAR MINSequentialDayNumber = MIN('Dim_Date'[SequentialDayNumber-LY])
VAR MAXSequentialDayNumber = MAX('Dim_Date'[SequentialDayNumber-LY])
RETURN
SUMX(
FILTER(
ALL(Dim_Date),
'Dim_Date'[SequentialDayNumber]>=MINSequentialDayNumber && 'Dim_Date'[SequentialDayNumber]<=MAXSequentialDayNumber),[Total Net Sales])
I am trying to do the same for a Count of Distinct Location IDs but DISTINCTCOUNTX is not usable.
Is there a way to do this with DAX, otherwise I will have to create a separate table of distinct counts and feed in which is getting messy.
Location Count LY =
VAR MINSequentialDayNumber = MIN('Dim_Date'[SequentialDayNumber-LY])
VAR MAXSequentialDayNumber = MAX('Dim_Date'[SequentialDayNumber-LY])
RETURN
DISTINCTCOUNTX(
FILTER(
ALL(Dim_Date),
'Dim_Date'[SequentialDayNumber]>=MINSequentialDayNumber && 'Dim_Date'[SequentialDayNumber]<=MAXSequentialDayNumber),[DistinctTransaction_ID])
OK I think I have worked it out...
Location Count LY =
VAR MINSequentialDayNumber = MIN('Dim_Date'[SequentialDayNumber-LY])
VAR MAXSequentialDayNumber = MAX('Dim_Date'[SequentialDayNumber-LY])
RETURN
CALCULATE
(DISTINCTCOUNT('Fact_Sales'[DistinctTransaction_ID]),
FILTER(ALL(Dim_Date),
'Dim_Date'[SequentialDayNumber]>=MINSequentialDayNumber && 'Dim_Date'[SequentialDayNumber]<=MAXSequentialDayNumber)
)

Calculating single values from cumulative data in Power BI

In my sales table I would like to change cumulative values into single values. Here is sample data from my table.
I created a measure that as far as I know should works for this.
sales_single_values = VAR current_sales = SUM('sales'[sales cumulative]) VAR prev_sales SUM('sales'[sales cumulative]) - CALCULATE( current_sales, 'sales'[period] = 'sales'[period] - 1) Return IF(ISBLANK(prev_sales), BLANK(), current_sales - prev_sales)
But unfortunately the final result on the chart is still the same as I used cumulative values, not single ones. Any ideas what should I change in my measure?
Expected values would be:
Period 1: 4
Period 2: 2
Period 3: 7
As a measure, something like:
sales_single_values =
var prev = max('sales'[period]) - 1
var prev_sales = CALCULATE( SUM('sales'[sales cumulative]), 'sales'[period] = prev)
Return
sum(sales[sales cumulative]) - prev_sales
But this seems like more of a modeling transformation, so do it in PQ, or with a calculated column, like
current sales =
var prev = calculate( max('sales'[period]) ) - 1
var prevSales = calculate( sum(sales[sales cumulative]), all(sales), sales[period] = prev)
return
sales[sales cumulative]-prevSales

PowerBI: Total Count Distinct

I need some help with my measure counting correct in total.
This is the MainTable:
With my Measure "CountPass" I count every ID distinct with the action "pass":
CountPass = CALCULATE(DISTINCTCOUNT(Workflow[ID]),Workflow[action]="pass")
Furthermore with my Measure CountPassPreweek I do same with reference on previous Week by using the a date table:
CountPassPreweek =
var currentweek = SELECTEDVALUE(DateTable[WeekNum])
var currentweekday = SELECTEDVALUE(DateTable[WeekNo])
var currentyear = SELECTEDVALUE(DateTable[Year])
var maxweeknum = CALCULATE(MAX(DateTable[WeekNum]),all(DateTable))
Return
SUMX(
if(currentweek = 1,
DateTable[WeekNo] = currentweekday && DateTable[WeekNum] = maxweeknum && DateTable[Year] = currentyear - 1,
DateTable[WeekNo] = currentweekday && DateTable[WeekNum] = currentweek -1 && DateTable[Year] = currentyear)),
[CountPass]
)
This is working so far but not showing the totals, so I have a second measure for doing that:
CountPreweekTotal =
var _table = SUMMARIZE(DateTable,DateTable[Date],"_value",[CountPassPreweek])
return
SUMX(_table,[_value])
And here you see my problem: The measure doesn't count distinct like the "original" counting Measure as you see here
Hope somebody can help me with that.
Thanks a lot!
It's counting 3 since abc is getting counted twice the way your measure is written (since dates are separated in your SUMMARIZE).
Since you appear to have a proper date table, you should be able to use time intelligence functions to write this much more simply as
CountPassPreviousWeek =
CALCULATE ( [CountPass], DATEADD ( DateTable[Date], -7, DAY ) )
This should work for the total too.

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:

Calculate sales of products that sold this year but not the year before

I want to calculate the sum of NetSales for the products that had sales this year (2019) but NOT sales last year (2018).
This is what I'm trying (and a million variations more similar to this):
NetSales CY Not LY =
VAR ThisYear= 2019
VAR YearBefore= 2018
VAR TabelaThisYear = SUMMARIZE(FILTER(SUMMARIZE('Facts';Facts[ArticleNo];Facts[InvoiceDate];Facts[NetSalesCurr]);YEAR('Facts'[InvoiceDate])=ThisYear && Facts[NetSalesCurr]>0);Facts[ArticleNo])
VAR TabelaYearBefore = SUMMARIZE(FILTER(SUMMARIZE('Facts';Facts[ArticleNo];Facts[InvoiceDate];Facts[NetSalesCurr]);YEAR('Facts'[InvoiceDate])=YearBefore && Facts[NetSalesCurr]>0);Facts[ArticleNo])
VAR ProdutosOnlyThisYear = EXCEPT(TabelaThisYear;TabelaYearBefore)
RETURN
CALCULATE(SUM(Facts[NetSalesCurr]);ProdutosOnlyThisYear)
I would use the following approach, where we don't hardcode the years:
NetSales CY Not LY=
CALCULATE(
SUM(Facts[NetSalesCurr]),
FILTER(
VALUES(Facts[ArticleNo]),
CALCULATE(
COUNTROWS(Facts),
PREVIOUSYEAR(Calendar[Date])
) = 0
)
)
Let's break it down:
The inner FILTER function iterates through VALUES(Facts[ArticleNo]) - that is all ArticleNo's that have sales in the currently selected period.
For every one of those ArticleNo's, we calculate the number of rows on the fact table for the previous year. CALCULATE(COUNTROWS(Facts), PREVIOUSYEAR(Facts[InvoiceDate]))
We keep only those ArticleNo's where this number is = 0.
The list of ArticleNo's returned from FILTER is then used in the outer CALCULATE statement, so that we only get the sum of NetSales for articles that did not have any sales in the previous year.
For more information, please see the New and returning customers-pattern.
you can use the dax formula like at the below , if you have a calendar table ;
this year = CALCULATE ( SUM[measure];DATEADD(CALENDAR[DATE]),0,YEAR)
last year = CALCULATE ( SUM[measure];DATEADD(CALENDAR[DATE]),-1,YEAR)