I have a sales data set and want to create a calculated column to be used as legend on graphs and also use as filter of dates but I'm struggling on with the part that identificate the previous 3 months before the last month.
My formula looks like this:
Period identification =
IF('Base'[Date]=CALCULATE(MAX('Base'[Date]);FILTER('Base';'Base'[FYTD]="FY1920"));"LM";
IF(
AND('Base'[Date]>=
DATEADD(CALCULATE(MAX('Base'[Date]);FILTER('Base';'Base'[FYTD]="FY1920"));-3;MONTH);
'Base'[Date]<CALCULATE(MAX('Base'[Date]);FILTER('Base';'Base'[FYTD]="FY1920")));"P3M";
IF('Base'[Date]=CALCULATE(MAX('Base'[Date]);FILTER('Base';'Base'[FYTD]="FY1819"));"LM YA";"OTHERS")))
The first IF() (Last Month - LM) and the last (Last Month Year Ago - LM YA) are working fine. I just can't find a way of PBI accept the kind of calculus I'm trying to do in the middle to identificate the previous 3 months before the last month.
*The [FYTD] is another calculated column that identificate the corresponding fiscal year of the [Date].[Month]
Thanks in advance
I think you can make this much easier using the handy EOMONTH function to move through time.
Try something like this where RefDate is the date that you want to use to calculate dates relative to. I'm using the end last month.
Period =
VAR RefDate = EOMONTH ( TODAY (), -1 )
RETURN
SWITCH (
TRUE (),
EOMONTH ( Base[Date], 0 ) = EOMONTH ( RefDate, 0 ), "LM",
Base[Date] > EOMONTH ( RefDate, -4 ), "P3M",
EOMONTH ( Base[Date], 0 ) = EOMONTH ( RefDate, -12 ), "LM YA",
"OTHERS"
)
Note:SWITCH(TRUE(),...) returns the result for the first condition that evaluates to TRUE().
Related
DateTable=CALENDARAUTO()
Calculated columns:
NextYearDate = DATEADD(DateTable[Date],1,YEAR)
The above calculated column shows blanks instead of the next years date. Why is that and how to fix it?
DATEADD is a Time Intelligence function, which returns dates from your date column shifted by the specified interval. This means that for the latest year in your date table, there are no "next year" values to return.
An alternative would be:
NextYearDate =
DATE (
YEAR ( DateTable[Date] ) + 1,
MONTH ( DateTable[Date] ),
DAY ( DateTable[Date] )
)
I have a quick question, is there a way to filter data from set days between 2 months?
E.g filter from 16-15 of Jan-Feb.
Is this possible?
For example i have used a measure to calculate days between dates
Last Assessment 16-15
= CALCULATE(SUM('Table1'[Duration1]),'Table1'[Start],
DATESBETWEEN('Calendar'[Date], [Assessment Date], [Assessment one month]))
Assessment Date = if(DAY(TODAY())<16,DATE(YEAR(TODAY()),MONTH(TODAY())-1,15),
DATE(YEAR(TODAY()),MONTH(TODAY()),15))
Assessment one month = EDATE([Assessment Date],-1)+1
Assessment 6 = EDATE([Assessment Date],-6)+1
Assessment 12 = EDATE([Assessment Date],-12)+1
The last assessment does show from the 16th of 2 months ago to last months 15th e.g Dec 16th - Jan 15th.
But i need to show from last 6 months and the last 1 year.
How can i work this out so i can show the Last 6 months and 1 year.
So far i have had to use a date filter to manually select the dates which i want to stop and have it be automatic.
If it is just the last 6 months or the last year you could make a custom column in the query editor (this would be the easiest way then). Like a filter flag:
'Includes the current month
Last 6 Months Flag = Date.IsInPreviousNMonths([YourDate], 6) or Date.IsInCurrentMonth([YourDate])
'Without the current month
Last 6 Months Flag = Date.IsInPreviousNMonths([YourDate], 6)
The same for last year:
Last Year Flag = Date.IsInPreviousYear([YourDate])
Drag and drop these custom columns as filter on your report and you are done.
consider following measure for Latest assessment (basically what you had before with EDATE for safe Dec/Jan handling and with variables for better performance)
Latest Assessment Date =
VAR __today = TODAY()
RETURN
IF (
DAY ( __today ) < 16,
DATE ( YEAR ( __today ), MONTH(EDATE(__today, - 1)), 15 ),
DATE ( YEAR ( __today ), MONTH ( __today ), 15 )
)
then you have this measure for handling 1/6/12 scenarios, you just replace 12 with whatever number of months you need
Measure 12 =
VAR __nrOfMonthsBack = 12
VAR __lastAssesment = [Latest Assessment Date]
RETURN
CALCULATE (
SUM ( Table1[Duration] ),
ALL('Calendar'), --this will reset any date filters coming from slicers
DATESBETWEEN (
'Calendar'[Date],
EDATE ( __lastAssesment, - __nrOfMonthsBack ) + 1,
__lastAssesment
)
)
EDIT: added ALL('Calendar') to disable filters coming from slicers
I need to show how many active contracts we have open for each month in the last 6 months. I am trying to figure out a way to display this. Here is my table
Machine Enrollment# StartDate EndDate
A 1 1/2/2016 6/18/2019
B 2 12/15/2012 5/12/2034
C 3 3/25/2019 4/25/2021
D 4 1/7/2000 7/15/2019
A 5 10/1/2019 10/1/2025
I have thousands of rows. I want to be able to show a rolling 6 month visual for how many machines are under contract. So in this small example it would look like this
Apr-19 June-19 Jul-19 Aug-19 Sep-19 Oct-19
4 4 3 2 2 3
Where do I even begin in creating this? In the past, we have just looked at the numbers for the current month and tacked those results onto the end of a static table and deleted the column from over 6 months ago. I have been assigned to automate this report in Power BI. I am guessing I need to create a column/measure that looks at the EndDate and compares it to the filtered Date in the visual (ie: Aug-19) and determines if the contract was open at that time. But I do not know. Any help is much appreciated. Thanks in advance!
I think I found a solution for what you are looking for. You may find a sample pbix file here.
1. Create a calendar table
A calendar table is required to filter/slice the time periods. The calendar table needs to have a unique Date column, and optional columns such as Year, Quarter, and Month, depending on what units of period you need in the analysis.
A calendar table can be most easily created as a DAX calculated table. Here is an example of a minimal calendar table required in this use case.
Calendar =
ADDCOLUMNS(
CALENDAR( MIN( Contracts[StartDate] ), MAX( Contracts[EndDate] ) ),
"Year Month", FORMAT( [Date], "mmm-yy" ),
"Year Month Number", YEAR( [Date] ) * 100 + MONTH( [Date] )
)
2. Create a measure to calculate number of open contracts
Every numbers calculated and shown in reports need to be defined as measures.
Let's think about the number of May-19. The current filter context includes all 31 dates in the Calendar table between 2019-05-01 and 2019-05-31. In this case, how can we think of an open contract? If the contract starts after 2019-05-31, it is not open. If the contract ends before 2019-05-01, it is not open as well. Therefore the open contract meets this condition.
Starts on or before 2019-05-31 and
Ends on or after 2019-05-01
Below is the measure definition to count the number of contracts based on this condition.
# Open Contracts =
VAR MinDate = MIN( 'Calendar'[Date] )
VAR MaxDate = MAX( 'Calendar'[Date] )
RETURN COUNTROWS(
FILTER(
Contracts,
Contracts[StartDate] <= MaxDate
&& Contracts[EndDate] >= MinDate
)
)
3. Add dynamic filter for last 6 months
If I was understanding correctly, the requirement is to show monthly number of last 6 calendar months, excluding this month. I could not find a straightforward way for this. My solution may contain a bit of hacky scent.
Power BI does not have built-in filter support based on calendar months relative to now. We need to build a custom logic to achieve this. I did it by creating a measure that indicates whether current filter context is within the desired period. This measure is a flag that returns 1 if the filter context is a single calendar month which is included in the last 6 calendar months, or returns BLANK otherwise.
__Last6MonthFlag =
VAR YearMonths = CALCULATETABLE(
VALUES( 'Calendar'[Year Month] ),
REMOVEFILTERS( 'Calendar'[Year Month] ),
'Calendar'[Date] > EOMONTH( TODAY(), -7 )
&& 'Calendar'[Date] <= EOMONTH( TODAY(), -1 )
)
RETURN IF(
HASONEVALUE( 'Calendar'[Year Month] )
&& SELECTEDVALUE( 'Calendar'[Year Month] ) IN YearMonths,
1
)
Then I used this measure in the visual filter like this.
You need to do below activities to achieve your requirement.
Define a calendar table holding all the dates for your report. Define a calculated column for Month-Year. Month-Year = FORMAT('CalendarTable'[Date], "MM-YYYY")
You can define a calculated measure, which will return 1 if the end date of the contract is < 6 months from current date (you can use TODAY() function). This function will help in rolling calculation based on current date. Otherwise, this calculated measure will return NULL and SUM them.
You can drag the month-Year calculated column, defined in step no. 1, to the column axis. You can drag the calculated measure, defined in step no.2, to the values section. PowerBI control by default filters out the NULL values. So, when you use the calculated measure defined in step no. 2, you will get values only for the last 6 months. As the calculation is defined based on TODAY(), it will be a running calculation.
So I know this question has been asked a few times, and I've religiously looked over different approaches, however I still don't quite understand why I'm getting an incorrect result.
Case: I have Sales Data from ~2016 -> 2019 (up until the 2/18/2019) I'm have a Measure to show me the YTD, however I'm looking for a measure for Last Years to date(the 18th in this particular circumstance).
Right now, I have this:
Total Sales LYTD =
CALCULATE (
[Total Sales],
SAMEPERIODLASTYEAR (
FILTER (
VALUES ( Sales[Completed Date] ),
Sales[Completed Date] <= MAX ( Sales[Completed Date] )
)
)
)
The logic to me makes sense, but I'm sure I'm missing something, has it appears it's grabbing the ENTIRE total of 2018 when in reality i'm looking for 01/01/2018 -> 2/18/2018
This is going to be dynamically uploaded with new sales data
What am I missing? Thank you so much!
Not sure I understand your table setup so lets look at this scenario and hopefully it helps.
Suppose you have the data in two tables, Sales and Calendar, and there's a 1:* relationship between the calendar and the sales tables. Then I would write the measures like this:
SalesToDateThisYear =
calculate(
Sum(Sales[Sales]);
Calendar[Year] = Year(Today())
)
and
SalesToDateLastYear =
var dateLastYear = Today() - 365
return
calculate(
Sum(Sales[Sales]);
Calendar[Year] = Year(dateLatsYear);
Calendar[Date] < dateLastYear
)
The two filter arguments are combined with a logic AND. So only dates from the first of last year to today's date last year will be included.
If you want to use the SamePeriod-function you can probably write something like this
SPLY =
calculate =
Sum(Sales[Sales]);
SamePeriodLastYear(
Filter(
Values(Calendar[Date]);
Calendar[Date] >= Date(year(today()); 1; 1) && Calendar[Date] < Today()
)
)
)
The SamePeriod-function takes a set of dates (this year) and converts them to dates last year.
Cheers
Currently, I have calculated the working days between two date by using the following formula.
TAT = CALCULATE(SUM('Days Table'[Is Work Day]),
DATESBETWEEN('Days Table'[Date],'Re-run Data'[DATE_ORDERED],'Re-run
Data'[DATE_COMPLETED]))
The problem is that if a client level has multiple orders that span all the working days in the Days Table, their sum includes all of the days instead of the sum of days between orders. This also skews the averages.
Does anyone have simpler solution to get number of working days between two dates?
Your current solution relies on having the [Is Work Day] column in your calendar table.
This measure returns the number of working days between the Date Ordered and Date Completed - based on working days being Monday - Friday, and excluding dates listed in a 'Holidays' table, without needing any calculated columns:
TAT =
COUNTROWS (
FILTER (
ADDCOLUMNS(
DATESBETWEEN (
'Calendar'[Date],
MIN ( 'Re-run Data'[DATE_ORDERED] ),
MAX ( 'Re-run Data'[DATE_COMPLETED] )
),
"Is Weekday", WEEKDAY ( 'Calendar'[Date], 2) < 6,
"Is Holiday", CONTAINS ( Holidays, Holidays[Holiday Dates], 'Calendar'[Date] )
),
[Is Weekday] = TRUE() && [Is Holiday] = FALSE()
)
)
See https://pwrbi.com/so_54718437/ for worked example (PBIX)
Upon further analysis, the formula I included in my question does exactly what I need it to do.