Creating flags for calculating rolling averages in excel - 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
`

Related

Generate "duplicate" row if between a date there is more than one month involved

I'm asked to "automatize" some Excel tasks regarding medical licenses, what I mainly need right now is to identify if a license is longer than a month period, if so, duplicate the entire row data besides the date which needs to be adapted on the "next month" and also generate a period id that includes the year + month (e.g. 201801 for a license started in Jan/2018).
What I did first was checking and displaying if a license is longer than x period (did a loop that counts days and identify if it matches with the month above the cell), so if one started on Jan and ended in Feb it would show like this:
period id member start date end date jan feb
201801 john doe 09/01/2018 07/02/2018 23 7
=SUMAPRODUCTO(--(TEXTO(FILA(INDIRECTO($J9 & ":" & SI($K9="";HOY();$K9)));"MMM")=N$8))
The problem with the table above is that the file becomes humongous with the formula, so instead I'm thinking, for now, just the row duplication:
period id member start date end date
201801 john doe 09/01/2018 31/01/2018
201802 john doe 01/02/2018 07/02/2018
The thing is I can't figure how to compare months and print them the way I have to.
Sub CopyData()
Set hojatst = Sheets(Hoja5)
Dim d
Dim j
d = 1
j = 8
Do Until IsEmpty(hojatst.Range("D" & j))
If hojatst.Range("D" & j) < hojatst.Range("E" & j) Then
d = d + 1
End If
j = j + 1
End Sub
This is a 'sketch' of the code you will need to write. Stackoverflow is not a code request service and so you need to do your best to write it yourself. The community is happy to help you troubleshoot while you learn, but you should be using Google a lot. I wrote out the sketch to get you started because I remember how hard it was to learn the basics of coding. Feel free to ask clarifying questions.
First of all I cannot get Excel to recognize the DD/MM/YYYY format. It might be because mine is a US copy and that is not a standard time format here. You seem to be using a different version of Excel due to the formulas you listed. However be sure to double check that your code is correctly reading the DD/MM/YYYY format as you proceed.
Create a variable cl that is your current line. Create md which is the month difference.
If Month (Start Date) is less than Month(End Date) Then md = Difference of Months, insert that many lines below the current line. Range("E" & cl+md).Value = Range("E" & cl)which pastes your end date to the last slot.
Then for cl < cl+md fill in the periods by add +1 to the value if the last number is not 4 and +97 if it is.
Then fill in the blank cells for the dates with the Start of Month and End of Month dates.
Finally set cl = cl + md + 1 and loop to move on to the next 'original' line.

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

Retutn only Buisness days in custom date function in excel

I have a date which I will need to increment the date by a day, month or year from the actual date. This is based of a list of fields below and is different per the input. Also each resultant date has to be a business day i.e not a weekend day or a bank holiday. Also if the resultant date is either Dec 25 or Jan 1st the day needs to move forward to the next business day (not a weekend day).
I have created this in Excel using a couple of formulas though it is a bit clunky.
Below is my data set
Business Date 15/05/2018
Tenor Settlement Value Settlement Period
ON 1 Day
TN 2 Day
SP 2 Day
SN 3 Day
1W 7 Day
2W 14 Day
3W 21 Day
1M 1 Month
2M 2 Month
3M 3 Month
In column E - I am using formula
=IF(D4="Day",$B$1+C4,IF(D4="Month",EDATE($B$1,C4),(TEXT($B$1,"dd/mm/")&(YEAR($B$1)+C4))+0))
In column F - I am using formula
=E4+LOOKUP(WEEKDAY(E4),{1,2,3,4,5,6,7},{1,0,0,0,0,0,2})
In column G - I am using formula
=F4+IF(AND(OR(TEXT(F4,"ddmm")="2512",TEXT(F4,"ddmm")="0101"),WEEKDAY(F4)>=2,WEEKDAY(F4)<=6),LOOKUP(WEEKDAY(F4),{1,2,3,4,5,6,7},{0,1,1,1,1,3,0}),LOOKUP(WEEKDAY(F4),{1,2,3,4,5,6,7},{1,0,0,0,0,0,2}))
In H I format the date in mm/dd/yyyy and I have my desired result.
storax has kindly created a function for me which replicates my excel formula in column E - on this thread Increment a date by a number of days, months or years
Function IncDate(ByVal dt As Date, ByVal add As Long, ByVal dmy As String) As Date
Select Case UCase(dmy)
Case "DAY"
IncDate = DateAdd("d", add, dt)
Case "MONTH"
IncDate = DateAdd("m", add, dt)
Case "YEAR"
IncDate = DateAdd("yyyy", add, dt)
Case Else
IncDate = dt
End Select
Could use some advise on how I could incorporate my formulas in columns F & G to make the process less clunky.
Manipulating the DATE function (DateSerial in vba) with the WORKDAY.INTL function seems to produce the correct business dates.
Put this in E4 and fill down.
=WORKDAY.INTL(DATE(YEAR(B$1)+(D4="year")*C4, MONTH(B$1)+(D4="month")*C4, DAY(B$1)+(D4="day")*C4)-1, 1, 1, holidays)
[holidays] is a named range (Formulas, Defined Names, Defined Name) with a Refers To: of,
=Sheet10!$Z$2:INDEX(Sheet10!$Z:$Z, MATCH(1E+99, Sheet10!$Z:$Z))

SLA COUNT IN EXCEL FORMULA

I'm looking for an excel (Office 2016 packet) formula that count SLA for ticket resolution.
the SLA counter must consider :
1) Monday To Saturday as work day ;
2) Holiday as no working days (must be skipeed as work day);
3) SLA start for ticket generate in workdays during range-time "08:00-20:00" out of this time-range SLA count is "0" ;
4) Output should result as R1= first 24Hours ; R2= from 25 to 48 hours ; R3= from 49 to 72 hours; "Out of Sla" = since 72 hours
Data to count SLA is formatted as below for either for ticket open and closure:
Column N Column O Column P Column Q
"TICKET START DATE" "TICKET STOP DATE" "SLA" "HOLIDAY"
28/4/18 13:30 30/4/18 19:20 2 25/04/2018
28/4/18 13:11 29/4/18 13:11 1 01/05/2018
28/4/18 12:57 28/4/18 12:57 1
I solved point 1) & 2) with NETWORKDAYS.INTL formula using the first column as start_date ; the second column as end_date; 11 as third formula's field to exclude Sunday as workdays; fourth formula's value pointing a column where are listed the "holidays" date .
I could not find a solution for point 3).
It will also appreciate a possible solution for point 4) .
Thank you in advance.
Formula example of above fields :
=NETWORKDAYS.INTL(N15;O15;11;Q16:Q17)
Alessandro.
I've needed to do something similar in the past. Please see the formula below. It will give you the amount of time between working days (Monday-Friday), only taking into account times 8:30am to 5:30pm. Try inserting your specific parameters.
=IFERROR((NETWORKDAYS.INTL(H8,I8,,)-1)*("17:30"-"8:30")
+IF(NETWORKDAYS.INTL(I8,I8,,),MEDIAN(MOD(I8,1),"8:30","17:30")
,"17:30")-MEDIAN(NETWORKDAYS.INTL(H8,H8,,)*MOD(H8,1),"8:30","17:30"),"")
H8 = Start Date
I8 = End Date
8:30 = Start Time
17:30 = End Time

Week number to Month number

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"

Resources