I have implemented a fiscal calendar into my Power BI Data Model for some time intelligence magic.
This fiscal calendar has a specific start and end date for each month and is mainly based on ISO 8601 Calendar (Gregorian).
However, my current approach is not working anymore for this year, since the filter "Current Fiscal Week" is not working. If I filter on Current Fiscal Week, then I get the second week of January instead of the first week.
But why?
My code has the following structure:
Calendar =
VAR BaseCalendar =
CALENDAR (
DATE ( 2020, 1, 1 ),
DATE ( 2022, 01, 03 )
)
RETURN
GENERATE (
BaseCalendar,
VAR BaseDate = [Date]
VAR WeekNumber =
WEEKNUM ( BaseDate )
VAR Year =
YEAR ( BaseDate )
VAR FiscalWeek =
WEEKNUM (
BaseDate,
21
)
VAR FiscalYear =
IF (
FiscalWeek < 5
&& WeekNumber > 50,
Year + 1,
IF (
FiscalWeek > 50
&& WeekNumber < 5,
Year - 1,
Year
)
)
RETURN
ROW (
"Fiscal Week", FiscalWeek,
"Current Fiscal Week",
IF (
AND (
FiscalWeek
= WEEKNUM (
TODAY (),
2
),
FiscalYear
= YEAR (
TODAY ()
)
),
TRUE (),
FALSE ()
)
)
)
I think that the Current Fiscal week should be found with the same formulas used to compute the FiscalWeek and FiscalYear. I put the variable definitions for the new variables outside of the GENERATE, since they just depend on TODAY()
VAR TodayBaseDate =
TODAY()
VAR TodayWeekNumber =
WEEKNUM( TodayBaseDate )
VAR TodayYear =
YEAR( TodayBaseDate )
VAR TodayFiscalWeek =
WEEKNUM( TodayBaseDate, 21 )
VAR TodayFiscalYear =
IF(
TodayFiscalWeek < 5
&& TodayWeekNumber > 50,
TodayYear + 1,
IF( TodayFiscalWeek > 50 && TodayWeekNumber < 5, TodayYear - 1, TodayYear )
)
VAR BaseCalendar =
CALENDAR( DATE( 2020, 1, 1 ), DATE( 2022, 01, 03 ) )
RETURN
GENERATE(
BaseCalendar,
VAR BaseDate = [Date]
VAR WeekNumber =
WEEKNUM( BaseDate )
VAR Year =
YEAR( BaseDate )
VAR FiscalWeek =
WEEKNUM( BaseDate, 21 )
VAR FiscalYear =
IF(
FiscalWeek < 5
&& WeekNumber > 50,
Year + 1,
IF( FiscalWeek > 50 && WeekNumber < 5, Year - 1, Year )
)
RETURN
ROW(
"Week day", FORMAT( [Date], "ddd" ),
"Today", TODAY(),
"Fiscal Week", FiscalWeek,
"Current Fiscal Week",
AND( FiscalWeek = TodayFiscalWeek, FiscalYear = TodayFiscalYear )
)
)
Related
Trying to create a slicer that when clicked only the months YTD, specifically up the the last month of current.
Such as slicer box clicked: (Say current month is August) then Months "Jan","Feb",..."July" would only display to click.
I've tried several things, my last attempt was to create a Dax table with dates and try to do a switch:
Dates =
var CurrentMonthInt = month(TODAY())
var monthis8 = "Jan" + "Feb" + "March" + "April" + "May" + "June" + "July"
VAR BaseTable =
CALENDAR(
DATE( YEAR ( MIN(Reporting[InvoiceDate])),01,01),
DATE( YEAR ( MAX(Reporting[InvoiceDate])),12,31)
)
RETURN
ADDCOLUMNS(
BaseTable,
"Year", YEAR([Date]),
"Month", FORMAT([Date],"mm"),
"Year Month", FORMAT([Date],"YYYY MM"),
"Month YTD", SWITCH(TRUE(),
CurrentMonthInt = 1, "Jan",
CurrentMonthInt = 8, monthis8,
"testing"
)
)
this returns a variant data type and will not work. I am thinking this is trying to add them all up on the same row.
Hello Please test this and let me know if It solves your problem.
Dates =
VAR CurrentMonthInt =
MONTH ( TODAY () )
VAR BaseTable =
CALENDAR (
DATE ( YEAR ( MIN ( Reporting[InvoiceDate] ) ), 01, 01 ),
DATE ( YEAR ( MAX ( Reporting[InvoiceDate] ) ), 12, 31 )
)
RETURN
FILTER (
ADDCOLUMNS (
BaseTable,
"Year", YEAR ( [Date] ),
"Month", MONTH ( [Date] ),
"Year Month", FORMAT ( [Date], "YYYY MM" )
),
[Month] <= CurrentMonthInt - 1
)
Note: I haven't tested it.
I have two tables like this
Table: creation date
ID user create date
1 ABC Jan 1, 2021
2 EFC Feb 1, 2021
3 HIJ Feb 1, 2021
1 ABC Feb 1, 2021
1 ABC Feb 20, 2021
And a log of blocking
ID user blocked from blocked till
1 ABC Jan 20, 2021 Feb 10, 2021
3 HIJ Jan 5, 2021 Jan 10, 2021
1 ABC Feb 25, 2021 Mar 10, 2021
As you can see the relationship between the tables are Many to Many. What I wanted to check is if the create date is during the blocked date in the log.
If it was ONE to MANY relationship, I could have used
Yes or No = IF(AND(creation date < RELATED(log[blocked from]), creation date > RELATED(log[blocked till])), "Yes", "No")
But now as there are multiple rows for the same ID how can I just check if the creation date is between any of the blocked from and Blocked till date?
You can use a measure like this
Measure2 =
VAR _maxID =
MAX ( creationDate[ID] )
VAR _minBlockedFrom =
CALCULATE (
MIN ( blockLog[blocked from] ),
FILTER ( VALUES ( blockLog[ID] ), blockLog[ID] = _maxID )
)
VAR _maxBlockedTill =
CALCULATE (
MAX ( blockLog[blocked till] ),
FILTER ( VALUES ( blockLog[ID] ), blockLog[ID] = _maxID )
)
VAR _maxDate =
MAX ( creationDate[create date] )
RETURN
IF ( _maxDate >= _minBlockedFrom && _maxDate <= _maxBlockedTill, "Yes", "No" )
Edit
please use a measure like this
Measure3 =
MAXX (
ADDCOLUMNS (
FILTER (
CROSSJOIN (
SELECTCOLUMNS (
creationDate,
"_id", creationDate[ID],
"_user", creationDate[user],
"_date", creationDate[create date]
),
blockLog
),
[_user] = [user]
),
"condition",
IF ( [_date] >= [blocked from] && [_date] <= [blocked till], "Yes", "No" )
),
[condition]
)
You can create a Measure as below-
is_from_block_range =
var current_row_id = min('CreationDate'[ID])
var current_row_user = min('CreationDate'[user])
var creation_date = min('CreationDate'[create date])
var chk_macth =
COUNTROWS(
FILTER(
all('BlockLog'),
'BlockLog'[ID] = current_row_id
&& 'BlockLog'[user] = current_row_user
&& 'BlockLog'[blocked from] <= creation_date
&& 'BlockLog'[blocked till] >= creation_date
)
)
return if(chk_macth >=1, "Yes", "No")
Output will be as below-
I'm creating a calendar table in DAX:
Dates =
CALENDAR (
MIN ( 'Work Weeks'[Start Date].[Date] ),
MAX ( 'Work Weeks'[Start Date].[Date] )
)
The work weeks table contains a week number and a start date for each week.
For each date in my new Dates table, I want to assign a work week number using the start date of the work week. Note that work weeks start on different days of the week (they're assigned properly in my work weeks table though).
So what I'm trying is:
Dates =
ADDCOLUMNS (
CALENDAR (
MIN ( 'Work Weeks'[Start Date].[Date] ),
MAX ( 'Work Weeks'[Start Date].[Date] )
),
"Work Week",
CALCULATE (
MAX ( 'Work Weeks'[Start Date].[Date] ),
'Work Weeks'[Start Date] <= Date
)
)
I'm not sure how to reference the current row/date in the condition at the end. And then I also need to return the work week number, rather than just the start date.
Assuming your work week table looks something like this:
You can use this date table code to add the week number:
Date Table =
VAR ListOfDate =
VAR MinDate = MIN ( Sales[Order Date] ) -- Replace the reference with the column of your model
VAR MaxDate = MAX ( Sales[Order Date] ) -- Replace the reference with the column of your model
VAR StartDate = DATE ( 2021, 1, 1 ) -- DATE ( YEAR ( MinDate ), 1, 1 )
VAR EndDate = DATE ( 2021, 12, 31 ) -- DATE ( YEAR ( MaxDate ), 12, 31 )
VAR Result = CALENDAR ( StartDate, EndDate )
RETURN
Result
VAR WorkWeekTable = ALL ( WorkWeek )
VAR CalendarTable =
GENERATE (
ListOfDate,
VAR CurrentDate = [Date]
RETURN
ROW (
"Calendar Year Number", YEAR ( CurrentDate ),
"Calendar Month Number", MONTH ( CurrentDate ),
"Work week",
CALCULATE (
MIN ( WorkWeek[Work Week Number] ),
CurrentDate >= WorkWeek[Work Week Start Date],
CurrentDate <= WorkWeek[Work Week End Date],
REMOVEFILTERS ( )
)
)
)
RETURN
CalendarTable
The result will look like this:
I am using a matrix table in powerbi to show previous week totals for different areas (categories). I have the majority of it working but I am not able to correctly get the subtotals on the table working.
I believe it has to do with the filtering that I am using - i have been unable to correct it.
screen capture
As you can see my Total for week 24 previous is missing
Dax code is:
VAR Area =
MAX ( 'SumTable'[Area Name] )
VAR CurrentWeek =
SELECTEDVALUE ( SumTable[WeekofYear] )
VAR CurrentYear =
SELECTEDVALUE ( SumTable[Year] )
VAR MaxWeekNumber =
CALCULATE ( MAX ( SumTable[WeekofYear] ), ALL ( SumTable ) )
RETURN
IF (
HASONEVALUE ( SumTable[Area Name] ),
SUMX (
FILTER (
ALL ( SumTable ),
IF (
CurrentWeek = 1,
SumTable[WeekofYear] = MaxWeekNumber
&& SumTable[Year] = CurrentYear - 1
&& SumTable[Area Name] = Area,
SumTable[WeekofYear] = CurrentWeek - 1
&& SumTable[Year] = CurrentYear
&& SumTable[Area Name] = Area
)
),
SumTable[BOE]
),
SUMX (
FILTER (
ALLSELECTED ( SumTable ),
IF (
CurrentWeek = 1,
SumTable[WeekofYear] = MaxWeekNumber
&& SumTable[Year] = CurrentYear - 1,
SumTable[WeekofYear] = CurrentWeek - 1
&& SumTable[Year] = CurrentYear
)
),
SumTable[BOE]
)
)
Data Table:
Example Table Format
Thank you, first time poster!
B
I would start by spliting my data table from my date table.
And I guess you don't need to ALL the whole table, just the columns for year and weeknumber and keep the Area in context, that way you don't have to bother if HASONEVALUE it will just work.
SELECTEDVALUE only returns if only a single value for that column is in context, not the case for totals and subtotals.
MyMeasure =
VAR CurrentWeek =
MAX( SumTable[WeekofYear] )
VAR CurrentYear =
MAX( SumTable[Year] )
VAR MaxWeekNumber =
CALCULATE ( MAX ( SumTable[WeekofYear] ), SumTable[Year] = CurrentYear-1 )
RETURN
IF(
CurrentWeek = 1,
CALCULATE(
SUM(SumTable[BOE]),
FILTER (
ALL ( SumTable[Year],SumTable[WeekofYear]),
SumTable[WeekofYear] = MaxWeekNumber
&& SumTable[Year] = CurrentYear - 1
)
),
CALCULATE (
SUM ( SumTable[BOE] ),
FILTER (
ALL ( SumTable[WeekofYear] ),
SumTable[WeekofYear] = CurrentWeek-1
)
)
)
I did not have a chance to confirm this code.
Currently visualizing sales for the past 30days, but looking to switch it in to the past 20 workdays instead, I've got workday column up and running in datetable, so ideally id want to use a filter of workday=1 and grab the 20 newest rows?
Sales 30d =
CALCULATE([Sales],
FILTER(
ALL(d_dates[date]),
d_dates[date]
>TODAY()-30))
This is what im using to show revenue for past 30 days, what'll i need to change?
You can try with this below measure-
slaes_last_20_days =
VAR today = TODAY()
VAR selected_date_min =
MINX(
TOPN(
20,
FILTER(
ALL(d_dates),
d_dates[date].[Date] <= today
&& workday = 1
),
d_dates[date].[Date],
DESC
),
d_dates[date].[Date]
)
RETURN
CALCULATE(
[Sales],
FILTER(
ALL(d_dates),
d_dates[date].[Date] >= selected_date_min
&& workday = 1
)
)
VAR Last20Workdays =
selectcolumns(
TOPN(
20,
FILTER(
d_dates,
d_dates[date] < TODAY()
&& d_dates[workday] = 1
),
d_dates[date],
DESC
),
"WorkDay",
d_dates[date]
)
This worked.