Week number to Month number - excel

I have a date with this format : 14w01 (year : 2014 week number : 1)
I want to convert this date in month like this : 14m01
Is there a function which converts a week number in a month number ?
Maybe something like this (in vba, not in formula) :
Format(weekNumber, "mm")
Thank you

It depends on how the weeks are defined. One way is to say that the first day of week#1 of a year is 1 January of that year. For this definition, a typical UDF is:
Public Function MonthFromDt(s As String) As Integer
Dim yr As Integer, wk As Integer, d As Date
ary = Split(s, "w")
yr = CInt(ary(0)) + 2000
wk = ary(1)
MonthFromDt = Month(DateSerial(yr, 1, 1) + 7 * (wk - 1))
End Function
There are other definitions of week number.

The DateFormat function is quiet comfortable, however the DateValue function, which parses a date, won't probably support your week format.
I suggest a trick with DateAdd, as DateAdd can handle weeks.
First split your date in year and week number:
Dim parts
parts = Split("2014w33", "w")
Dim year
Dim week
year = CInt(parts(0))
week = CInt(parts(1))
Then, add both to a "zero-date" to add up to the final date. Note that if you give "0" as year for DateAdd, VBA compiler interprets 2000.
dim DateResult
DateResult = dateAdd("yyyy", (year - 2000), DateValue("Jan 1, 0"))
Debug.Print dateResult
DateResult = dateAdd("ww", week, dateResult)
Debug.Print dateResult
Then show the result reformatted:
Debug.Print Format(DateResult, "yyyy\mm")
This prints on my side:
01.01.2014
20.08.2014
2014m08
August 2014, there is week 33 if I look up in the calendar. Seems correct.

I found a way to do it without VBA (and only using Formulas). This assumes A1 contains the "14w01" format
=LEFT(A1,2)&"m"&TEXT(MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)),"00")
Heres a breakdown of what the code does..
LEFT(A1,2) returns "14" (year)
MONTH(DATE(20&LEFT(A1,2),1,1)+(RIGHT(A1,2)*7)) converts the week # to the month # and it takes in the year 20&LEFT(A1,2) as well as week # RIGHT(A1,2)
TEXT(...,"00") pads the month # with a 0 if necessary (i.e. 3 becomes 03)
Then we just combine everything together to get "14m01"

Related

vba - get weeknumber

I would like to get the current week number.
I tried this:
MsgBox (Format(Now, "ww", vbMonday))
The result:
3
But it has to be 2
Where is my mistake?
msgbox format(now(),"ww",vbMonday,vbFirstFourDays)
provides the ISO weeknumber, which is what it seems you want.
or:
msgbox worksheetfunction.IsoWeekNum(date)
Note that there is a bug in the VBA Format (and DatePart) functions in that they can return the wrong weeknumber for the last Monday of some years when determining the ISO WeekNumber
So if you are going to use the Format function, you need to check for that bug.
Worksheetfunction.IsoWeekNum does not have that bug.
To workaround the bug, Microsoft suggests checking the weeknumber of the week after any date where the weeknumber calculates to 53.
Function WOY (MyDate As Date) As Integer ' Week Of Year
WOY = Format(MyDate, "ww", vbMonday, vbFirstFourDays)
If WOY > 52 Then
If Format(MyDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then WOY = 1
End If
End Function

How to define a variable in between 2 date periods and time periods?

So I'm trying to define a variable or multiple variable so I can easily filter in my data set. Essentially I need to filter by date/time in my data set. The format of the date and time in the data set is as such: 2019-01-03 8:45:30 PM
What I want to do is to define a variable in order to always filter the data based on the current date. My data always changes every day, therefore my point of reference is today's date. Essentially I need to filter data starting from 2 days ago at 11am all the way to yesterdays date ending at 10am. How would i go about defining my variable? I tried doing the following:
Dim StandardH As Date
StandardH = Date - 1 + (1 / 24)
And do the same thing all the way to 10 am and do - (1/24) all the way till 11am but that doesn't seem to work.
I realize that there's probably a simpler way of doing this. Any ideas?
Thanks,
In VBA:
"2 days ago at 11 AM" translates to Date - 2 + TimeSerial(11, 0, 0)
"Yesterday at 10 AM" translates Date - 1 + TimeSerial(10, 0, 0)
That's in relation to the date and time the code is being run, and assumes by "2 days ago" you mean "the day prior to yesterday".
If I had some dates on "Sheet4" in the range "B7:B17" (assume there is a header in cell B6), then I think I could use the code below to filter from (and including) 2 days ago at 11 AM, up to (and including) yesterday at 10 AM:
Option Explicit
Sub FilterDatesInclusively()
With ThisWorkbook.Worksheets("Sheet4")
.AutoFilterMode = False
Dim fromDate As Date
fromDate = Date - 2 + TimeSerial(11, 0, 0)
Dim toDate As Date
toDate = Date - 1 + TimeSerial(10, 0, 0)
.Range("B6:B17").AutoFilter Field:=1, Criteria1:=">=" & CDbl(fromDate), Operator:=xlAnd, Criteria2:="<=" & CDbl(toDate)
End With
End Sub
Maybe there is some way of filtering without converting to double, but I couldn't work it out.

Get day number within calendar week for a specific date

I have a data set which includes dates.
I need to split this out by week number for reporting purposes.
What I have so far is:
startDate variable containing 03/01/2015 (populated from data in spreadsheet)
startDay = Day(startDate)
startMonth = Month(startDate)
startYear = Year(startDate)
startWeek = Application.WorksheetFunction.WeekNum(DateSerial(startYear, startMonth, startDay))
which gives me week 1 in startWeek
However I know need to know how far into week 1 the date is.
So for this example, as the date is the 3rd of January, it includes 3 days of week 1
Meaning the reporting I'm putting together will only report on 3 days (as opposed to the full week)
The only way I've figured to do this so far is to calculate which day of the year the date is and the use a MOD calculation (basically divide by 7 and the remainder is how far into the week it is)
dayNumber = DateDiff("d", DateSerial(startYear, 1, 1), DateSerial(startYear, startMonth, startDay)) + 1
dayOfWeek = dayNumber Mod 7
This does work, but I was wondering if there was a nicer solution than this.
You could use a loop to determine how many days before startDate the week number changed:
Public Sub FindDaysInWeekNo()
Dim startDate As Date
startDate = DateSerial(2015, 1, 3)
Dim startWeek As Integer
startWeek = Application.WorksheetFunction.WeekNum(startDate)
Dim i As Integer
Do While startWeek = Application.WorksheetFunction.WeekNum(DateAdd("d", -i, startDate))
i = i + 1
Loop
Debug.Print i '= 3rd day in this week number
End Sub
The following table shows my comparison to the other suggested formulas and why I think that (refered to =WEEKNUM) my calculation is correct.
Note that if you assume 1st to 7th January will be week 1 (days 1 to 7) you cannot use the WeekNum function because this will give you a different result (see table above and note that the first week has only 6 days according to the WeekNum function). Also you cannot name this week number (as what everybody calls week number is defined as https://en.wikipedia.org/wiki/Week#Week_numbering).
Instead you will need to use …
Public Function AlternativeWeekNum(startDate As Date) As Integer
AlternativeWeekNum = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) \ 7 + 1 'note that this no normal division but a integer division and uses a backslash instead
End Function
to calculate the week number your alternative way, and …
Public Function AlternativeWeekNumDay(startDate As Date) As Integer
AlternativeWeekNumDay = WorksheetFunction.Days(startDate, DateSerial(Year(startDate), 1, 1)) Mod 7 + 1
End Function
to calculate the day in the alternative week.
You can use the Weekday() function for this:
=WEEKDAY(B4;2)
The second parameter mentions how you want your days to be counted (starting from Sunday or Monday, counting starting from 0 or from 1, ...).
dayOfWeek = (8 + Weekday(startDate) - Weekday(DateSerial(startYear, 1, 1))) mod 7
Just take the positive mod 7 of the difference between the current Day-Of-Week and the Day-Of-Week for the 1st January of whatever the year is

Creating flags for calculating rolling averages in excel

I have a data sheet which looks like:
year month
2017 2017-01
2017 2017-02
2017 2017-03
......
2018 2018-04
2018 2018-05
Note the column month contains text string. I need to create a new column flag in excel which filters which months are to be used in calculating rolling 12M averages for current month and which months are to be used for calculating rolling 12M averages for previous year.
For example today's date is 5/24/2018, so month 2018-05 will be marked as "current". months between 2018-04 to 2017-05 will be marked as "both". month 2017-04 will be marked as "previous". Rest all months will be marked as NA. My final data should look like this:
year month flag
2017 2017-01 NA
2017 2017-02 NA
2017 2017-03 NA
2017 2017-04 Previous
......
2018 2018-04 Both
2018 2018-05 Current
I am having trouble implementing this logic in excel as the column month is a text string and simply using IF condition doesn't works for me. Any leads on this is appreciated.
Edit:
I tried converting the months to a number by using =DATEVALUE(B2 & "-01").
I stored the number for current month in a variable curr.
Now I am using the following formula =IF(B22=curr,"Current", IF(B2=curr-395,"Previous","Both")).
This creates the flag column which I require although there's still an issue based on whether the month has 30 or 31 days. Any solutions for this please?
One way to do it is to use DATDIF.
=DATEVALUE(B2 & "-01") will give you the first of each month in column B.
To return the month number use =DATEDIF(C2,TODAY(),"m") where column C holds the DATEVALUE formula. This will return 0 for this month, 1 for last month... 13 for April 2017.
Now check to see if the count of months = 0 then it's current, if it's greater than 11 it's NA, otherwise it's both. =IF(D2=0,"Current",IF(D2>11,"NA","Both"))
... Edit ....
That's wrong - forgot the "Previous" and "Both" isn't 12 months ....
=IF(D2=0,"Current",IF(D2>13,"NA",IF(D2=13,"Previous","Both")))
As considering your column month format = "YYYY-MM" this code may be helpful
this is Excel function, to use it you need to save this function in the module and use it. `
Function MyDateCal(cell As Range) As String
Dim YearCurrent, YearCell, monthCurrent, MonthCell As Integer
Dim cellVal As String, DiffMonth As Integer[![enter image description here][1]][1]
cellVal = cell.Value
MyDateCal = "NA"
'cellVal = Cells(1, 1).Value
YearCurrent = Year(Now())
monthCurrent = Month(Now())
YearCell = CInt(Left(cellVal, 4))
MonthCell = CInt(Right(cellVal, 2))
DiffMonth = 12 * (YearCurrent - YearCell) + (monthCurrent - MonthCell)
If DiffMonth = 0 Then
MyDateCal = "Current"
ElseIf DiffMonth > 0 And DiffMonth <= 12 Then
MyDateCal = "Both"
ElseIf DiffMonth = 13 Then
MyDateCal = "Previous"
End If
End Function
`

Start the Week Number from the first sunday of every fiscal year in Excel

I am trying to find the week number for a fiscal year which is starts on first sunday of February. I have got it to a point where I can get the week number which starts on first of every year (in my case feb).
Not able to start it from First Sunday. Below is what I've come up with.
=IF(AND(MONTH($E2)=2,DAY($E2)=1),1,ROUNDUP(($E2-DATE(YEAR($E2)-IF(MONTH($E2)<2,1,0),2,0)+WEEKDAY(DATE(YEAR($E2)-IF(MONTH($E2)<2,1,0),2,0)))/7,0))
I would also like it to end on Saturday of last week of the year.
For example: in Feb 2016, the week count should start from 7thFeb2016 and the count should end on 4thFeb2017.
Use this formula to find week number of given date:
=IF(A1>=IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2)),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2))+1)/7,0),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1)-1,2,1),DATE(YEAR(A1)-1,2,7-WEEKDAY(DATE(YEAR(A1)-1,2,1),1)+2))+1)/7,0))
I hope you want this.
UPDATED
If you want week number of fiscal quarter, use this:
=ROUNDUP(MOD(=IF(A1>=IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2)),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1),2,1),DATE(YEAR(A1),2,7-WEEKDAY(DATE(YEAR(A1),2,1),1)+2))+1)/7,0),ROUNDUP((A1-IF(WEEKDAY(DATE(YEAR(A1),2,1),1)=1,DATE(YEAR(A1)-1,2,1),DATE(YEAR(A1)-1,2,7-WEEKDAY(DATE(YEAR(A1)-1,2,1),1)+2))+1)/7,0)),13.01),0)
I just chucked this together (no doubt there is a more elegant way to do this). You can use it by putting it into a Module in your VBA editor and then on the worksheet use the function =AltWeekNumber(E2)
Function AltWeekNumber(endDate As Range) As Date
Dim startDate As Date
startDate = FirstFebruarySunday(year(endDate.Value))
If startDate > endDate Then
startDate = FirstFebruarySunday(year(endDate.Value) - 1)
End If
AltWeekNumber = DateDiff("w", startDate, endDate.Value, vbSunday)
End Function
Private Function FirstFebruarySunday(year As Integer) As Date
For i = 1 To 7
If Weekday(DateSerial(year, 2, i)) = 1 Then
FirstFebruarySunday = DateSerial(year, 2, i)
Exit Function
End If
Next i
End Function

Resources