I want to have a date table created with DAX for a power BI report where it will have week index numbers 0,-1,-2,etc to go back in time and make comparisons of weeks. I found the below out on the web (I dont remember where)
DATE =
GENERATE (
CALENDAR( DATE( YEAR( TODAY() ) - 2, MONTH( TODAY() ), DAY( TODAY()) ), TODAY()),
VAR startOfWeek = 1 // Where 1 is Sunday and 7 is Saturday, thus a 3 would be Tuesday
VAR currentDay = [Date]
VAR days = DAY( currentDay )
VAR months = MONTH ( currentDay )
VAR years = YEAR ( currentDay )
VAR nowYear = YEAR( TODAY() )
VAR nowMonth = MONTH( TODAY() )
VAR dayIndex = DATEDIFF( currentDay, TODAY(), DAY) * -1
VAR todayNum = WEEKDAY( TODAY() )
VAR weekIndex = INT( ROUNDDOWN( ( dayIndex + -1 * IF( todayNum + startOfWeek <= 6, todayNum + startOfWeek, todayNum + startOfWeek - 7 )) / 7, 0 ) )
RETURN ROW (
"day", days,
"month", months,
"year", years,
"day index", dayIndex,
"week index", weekIndex,
"month index", INT( (years - nowYear ) * 12 + months - nowMonth ),
"year index", INT( years - nowYear )
)
)
This report should be updated daily but I noticed that today VAR Week index is not calculating correctly. Today is 4/1/2020 so I would expect 3/29/2020 - 4/1/2020 to have a week index of 0 however only 4/1/2020 and 3/31/2020 have week index 0.
I have played around with this formula a bit and cannot seem to get something that would consistently work for a report that is updated daily. I am probably going to just begin using the ISO week and ISO year values to get at my comparisons but I will lose some functionality that the week index number gives me. Can anyone please help with the a working formula?
Thank you!
The weekIndex can be simpler calculated, you can change it to:
VAR weekIndex = ROUNDDOWN((dayIndex + todayNum - startOfWeek - 6)/7;0)
Related
I have a table in Power BI which shows Date In and Date Out of work completed, it's connected to a Calendar table with dates. I have 3 formula's to get actual working days after weekends and bank holidays etc. The trouble is however, it used to work and now yields the below error.
"The start date or end date in Calendar function can not be Blank
value."
Below are my formulas
Workdays (After Excluding Weekends Only) =
COUNTROWS (
FILTER (
ADDCOLUMNS (
CALENDAR ( 'Pro'[Date In], 'Pro'[Date Out] ),
"Day of Week", WEEKDAY ( [Date], 2 )
),
[Day of Week] <> 5
&& [Day of Week] <> 6
)
) - 1
Workdays (After excluding Holidays only) =
COUNTROWS (
FILTER (
ADDCOLUMNS(
CALENDAR ('Pro'[Date In], 'Pro'[Date Out]),
"Is Holiday", CONTAINS ('Holidays', 'Holidays'[Dates], [Date])
),
[Is Holiday] = FALSE()
)
)
Workdays (After excluding Weekends & Holidays) =
COUNTROWS (
FILTER (
ADDCOLUMNS(
CALENDAR ('Pro'[Date In], 'Pro'[Date Out]),
"Is Weekday", WEEKDAY ([Date], 2) < 6,
"Is Holiday", CONTAINS ('Holidays', 'Holidays'[Dates], [Date])
),
[Is Weekday] = TRUE() &&
[Is Holiday] = FALSE()
)
) - 1
im working on a calculated column in a SSAS model.
My Idea is to generate every month as date ( f.e 2021-01-01) based on a start and end date, who are also columns of that entry. Basically i wanna duplicate every entries with the month column for further calculations
when i have startdate 2021-04-28 and enddate 2022-02-28
i want to have 2021-04-01 , 2021-05-01 etc... till 2022-02-01
how do i write this in DAX?
Try this way:
Calendar =
VAR start_date = DATE( 2021, 4, 28 )
VAR end_date = DATE( 2022, 2, 28 )
VAR start_date_first = DATE( YEAR( start_date ), MONTH( start_date ), 1 )
VAR end_date_eom = EOMONTH( end_date, 0 )
VAR result =
FILTER(
CALENDAR( start_date_first, end_date_eom ),
DAY( [Date] ) = 1
)
RETURN
result
I have the below query which gives me the headcount per month when I select a month from the date table which is fine and works correctly.
I would like the average headcount for the past 12 months from the selected date e.g if i select Aug 2020, the average should be a sum of headcount from July 2019 - Aug 2020
Active Employees =
var currentdate = 'Date'[Max Date]
RETURN
CALCULATE(
DISTINCTCOUNT('Joined Query'[EMP_NO]),
'Joined Query'[DATE_OF_EMPLOYMENT] <= currentdate,
or(
ISBLANK('Joined Query'[DATE_OF_LEAVING]),
'Joined Query'[DATE_OF_LEAVING] > currentdate
)
)
You can reuse your headcount measure per month like this:
average 12 months =
VAR currentdate = SELECTEDVALUE('Date'[Max Date])
RETURN AVERAGEX(
SUMMARIZE(
FILTER(ALL('Date'),
'Date'[Max Date] <= currentdate && 'Date'[Max Date] >= EDATE(currentDate,-11)),
'Date'[Max Date],
"headcount", [Active Employees]
), [headcount])
Please note, -11 gives you the date 12 months ago in regards to the current selected date. In your question you say if you select August you want to see from July last year, and that would actualy be 14 months, not 12. If that's your use case you need to change it to -13.
Create 2 following measures for 12 month start and end date-
12 Month End Date =
VAR D1 =
DATEVALUE(
SELECTEDVALUE('Date'[Max Date].[MonthNo])
& "/1/"
& SELECTEDVALUE('Date'[Max Date].[Year])
)
RETURN D1-1
12 Month Start Date =
VAR D1 =
DATEVALUE(
SELECTEDVALUE('Date'[Max Date].[MonthNo])
& "/1/"
& SELECTEDVALUE('Date'[Max Date].[Year])
)
RETURN EDATE(D1,-12)
Now create this following measure for average calculation-
12_month_average =
(
CALCULATE(
DISTINCTCOUNT('Joined Query'[EMP_NO]),
DATESBETWEEN(
'Date'[Max Date],
[12 Month Start Date],
[12 Month End Date]
)
) + 0
) / 12
I have a problem on this calendar, the weeks calculations per year are working correctly based on our needs, but now I need to add a iteration variable (#runningWeekSeed) that increments in 1 when the week changes (#WorkWeekSeed).
I'm not sure If i explained correctly.
/*
This Query is built for a 4-4-5 calendar, Mon - Sun week.
Each Fiscal year start on 01/01/YYYY ends on 12/31/YYYY.
*/
DECLARE
#FiscalCalendarStart DATETIME, -- Calendar starts
#EndOfCalendar DATETIME, -- Calendar ends
#CurrentDate DATETIME, -- Calendar date being calculated against
#RunningDaySeed INT, -- Days calculations
#RunningWeekSeed INT, -- Weeks calculations
#FiscalYearSeed INT, -- Years calculations
#RunningPeriodSeed INT, -- Fiscal Month
#WorkWeekSeed INT, -- Fiscal Week
#WorkQuarterSeed INT, -- Fiscal Quarter
#WorkPeriod INT, -- Used to assign where the extra "leap week" goes. Based on the 4-4-5 calendar.
#WeekEnding DATETIME
DECLARE #FiscalTimePeriods AS TABLE (
Sysdate VARCHAR (10), -- Date with format MMDDYYYY
Date_Time_Target DATETIME, -- The date, but with Time duh
MSC_Week INT, -- Running week according MSC Calendar
MSC_Year INT, -- Calendar with corresponding days into the Fiscal year
weekEnding DATETIME,
runningWeekSeed INT
)--Of Table
/* These are user variables, and should be set according every need */
SELECT
#FiscalCalendarStart = '20150101', -- The date of year start. Used as the base date for calculations (This case will be on 12/29/2015 to match 7 days week for week 1 of 2015)
#EndOfCalendar = '20901231' , -- The date on which the calendar query will end. Can be adjusted for each need
#RunningDaySeed = 1, -- This is used to measure the number of days since the calendar began, often used for depreciation (usually 1)
#RunningPeriodSeed = 1, -- The number of fiscal months since the original calendar began (usually 1)
#RunningWeekSeed = 1, -- The number of fiscal weeks since the original calendar began (usually 1)
#FiscalYearSeed = 2015 -- The starting fiscal year (first 3 days of week 1 belongs to 2014 but it's on 2015 fiscal calendar)
/* These are iteration variables, do not mess with these */
SELECT
#WorkPeriod = 1 ,
#WorkWeekSeed = 1 ,
#WorkQuarterSeed = 1
/* The loop is iterated once for each day */
SET #CurrentDate = #FiscalCalendarStart
SELECT #WeekEnding = dateadd ( D , 8 - DATEPART ( DW , #CurrentDate ), #CurrentDate )
WHILE #CurrentDate <= #EndOfCalendar
BEGIN --MAIN BEGIN
INSERT INTO #FiscalTimePeriods
SELECT
CONVERT ( VARCHAR (10), #CurrentDate , 101 ) AS SysDate,
#CurrentDate AS Date_Time_Target,
#WorkWeekSeed AS MSC_Week,
YEAR (#CurrentDate) AS MSC_Year,
#WeekEnding,
#RunningWeekSeed
/* Iterate the date and increment the RunningDay */
SET #CurrentDate = DATEADD ( D , 1 , #CurrentDate )
SELECT #RunningDaySeed = #RunningDaySeed + 1,
#WeekEnding = dateadd ( D , 8 - DATEPART ( DW , #CurrentDate ), #CurrentDate )
/* If #CurrentDate is 01/01/YYYY, reset fiscal counters */
IF (DATEPART (MONTH, #CurrentDate) = 1 AND DATEPART(DAY, #CurrentDate) = 1)
BEGIN
SELECT
#WorkPeriod = 1 ,
#WorkWeekSeed = 1 ,
#WorkQuarterSeed = 1,
#FiscalYearSeed = #FiscalYearSeed + 1
END
ELSE
/*************Check if Monday is between 12/23 to 12/31 *****************/
IF DATEPART ( DW , #CurrentDate ) = 2 -- Check if #CurrentDate is monday
IF DATEPART (MONTH, #CurrentDate) = 12 AND (DATEPART(DAY, #CurrentDate) in (23, 24, 25, 26, 27, 28, 29, 30, 31)) -- If #CurrentDate is Dec 23 to 31
BEGIN
SELECT
#WeekEnding = dateadd ( D , 8 - DATEPART ( DW , #CurrentDate ), #CurrentDate ),
#WorkWeekSeed = 52,
#WorkQuarterSeed = 4,
#WorkPeriod = 12
END
ELSE
IF DATEPART ( DW , #CurrentDate ) = 2
BEGIN
SELECT
#WeekEnding = dateadd ( D , 8 - DATEPART ( DW , #CurrentDate ), #CurrentDate ),
#WorkWeekSeed = CASE
WHEN #WorkWeekSeed = 53 THEN 52
ELSE #WorkWeekSeed + 1
END
END
/* Compare if current date acomplish ISO_WEEK standard ISO 8601*/
IF DATEPART ( ISO_WEEK , #CurrentDate ) = 1
SELECT
#WorkPeriod = 1,
#WorkWeekSeed = 1,
#WorkQuarterSeed = 1
------------------------HERE IS WHERE START TO DO THE CALCULATION OF THE runningWeekSeed-------------------------
IF #WorkWeekSeed = 52
SELECT #WeekEnding = dateadd ( D , 8 - DATEPART ( DW , #CurrentDate ), #CurrentDate ),
#RunningWeekSeed = #RunningWeekSeed
ELSE
IF DATEPART(DW, #CurrentDate) = 2
SELECT #RunningWeekSeed = #RunningWeekSeed + 1
ELSE
IF (DATEPART (MONTH, #CurrentDate) = 1 AND DATEPART(DAY, #CurrentDate) = 1)
SELECT #RunningWeekSeed = #RunningWeekSeed + 1
END -- MAIN BEGIN
SELECT
*
FROM #FiscalTimePeriods
ORDER BY Date_Time_Target ASC
The needed results need to be like this
I'm trying to write an expression in SSRS:
If today's DAY is <= 15th day, return pay period previous month 16th to last day of month
If today's DAY is >= 16th day, return current month day 1st to 15th
This is the expression I have now but its not working:
Start Date:
=IIF(DAY(TODAY) <= 15, DateAdd(DateInterval.Day, 1-Day(Today), Today), DateAdd(DateInterval.Month, -1, (DateAdd(DateInterval.Day, 16-Day(Today), Today)))),
IIF(DAY(TODAY) >= 16, dateadd("m",0,dateserial(YEAR(Today),MONTH(Today),1)
End Date:
=IIF(DAY(TODAY) <= 15, DateAdd(DateInterval.Day, -1, DateSerial(Year(Date.Now), Month(Date.Now), 1)),
IIF(DAY(TODAY) >= 16, dateadd(dd,datediff(dd,datepart(dd,getdate()),15),getdate())
I just had to do something similar in the past week...
--StartDate, if current day is more than 16, set to 1, else 16
=iif(DatePart("d",Today) >= 16, DateSerial(Year(Today), Month(Today), "1").AddMonths(-1), DateSerial(Year(Today), Month(Today),"16").AddMonths(-1))
--EndDate, if current day is more than 16 set to 15, else month end
=iif(DatePart("d",Today) >= 16, DateSerial(Year(Today), Month(Today), "15").AddMonths(-1), DateSerial(Year(Today), Month(Today),"1").AddDays(-1))
Use the following expressions
StartDate:
=
Iif ( Day(Today())>15
, DateAdd( "d", -Day(Today())+1, Today())
, DateAdd("d", -Day(Today())+16, DATEADD("m", -1,Today()))
)
EndDate:
=
Iif ( Day(Parameters!DateParam.Value)>15
, DateAdd("d", -Day(Today())+15 , Today())
, DateAdd("d", -Day( Today()) , Today())
)