How to loop through the weeks in a date range with vba - vb.net

I have seen how to loop through weeks of a year, w1301,w1302,w1303, I can get the week number if i loop through + on week number but I believe there is a way to directly loop weekly with vba, i hope at least.
DateSerial(Year(Now), Month(Now), Day(Now)) To DateSerial(2013, 3, 1)
StartDate = #1/1/2013#
EndDate = #12/31/2013#
For DateLooper = StartDate To EndDate
I got the function for a week number from date
Public Function IsoWeekNumber(d1 As Date) As Integer
Attributed to Daniel Maher
Dim d2 As Long
d2 = DateSerial(Year(d1 - WeekDay(d1 - 1) + 4), 1, 3)
IsoWeekNumber = Int((d1 - d2 + WeekDay(d2) + 5) / 7)
End Function

You could just use the DateAdd function
For i = 1 To 52
Debug.Print DateAdd("ww", i, Now())
Next i

A day has an integer value of 1, so you could iterate by week like this:
startDate = #1/1/2013#
endDate = #12/31/2013#
For d = startDate To endDate Step 7
'do stuff
Next
The week number can be determined with the DatePart function, e.g.:
WScript.Echo DatePart("ww", Now)
This will work in both vbscript and vba.

I tried this solution and it seems to work, am not 100% sure of how it handles the 28,30,31 days of different months but i trust vba. i know am making a mistake probably :))
currentDate = "2013-01-02" ' coz i wanted to start on a wednesday
for week = 1 to 52
debug.print currentDate
currentDate = DateAdd("ww",1,currentDate)
next week

Related

VBA get the last day of the month

I am pretty new to VBA. I have a range of dates and I need to write a code that will change the date in the cell to the last day of the month, used in a cell.
For example, if the date in the cell is 28/03/2018 I want it to be replaced by 31/03/2018. Any idea how I can do that?
You can also get the result you need with one line of code thanks to the Eomonth formula:
Range("A1") = Excel.Application.WorksheetFunction.EoMonth(Range("A1").Value2, 0)
You can use a user-defined function GetLastDayOfMonth() and pass the range you are interested in:
Option Explicit
Public Function GetLastDayOfMonth(ByVal myDate As Date) As Date
GetLastDayOfMonth = DateSerial(Year(myDate), Month(myDate) + 1, 0)
End Function
Public Sub TestMe()
Range("A1") = DateSerial(2000, 11, 11)
If Range("A1") = GetLastDayOfMonth(Range("A1")) Then
Debug.Print "LAST DAY!"
End If
Range("A1") = DateSerial(2000, 12, 31)
If Range("A1") = GetLastDayOfMonth(Range("A1")) Then
Debug.Print "LAST DAY! " & Range("A1")
Range("A1") = DateAdd("d", 1, Range("A1"))
End If
End Sub
The function checks the month and the year of the date, which is passed and it returns a new date, which is the last day of the month for this specific month and year.
Then in the TestMe version, you can compare a given date with the last day of the month, generated by the function. If the dates are the same, then this date is the last day of the corresponding month. Using DateAdd() it is possible to get the next day of the lastDay.
In the example above, I have explicitly written Range("A1") 9 times, thus it is probably easier to follow.
To get it really short you can use:
Sub test()
Dim myDate As Date
myDate = #3/28/2018#
Debug.Print DateSerial(Year(myDate), Month(myDate) + 1, 0)
End Sub
First, if you just want the last day of the month in Excel, use the =EOMONTH function, or see this SO post for the vba code:
VBA Run Macro Last Day of the Month
Rolling your own date time code is a bad idea. Don't do it.
This VBA function will calculate the last day of the month:
Public Function LastDay(ByVal d As Date)
Dim returnDate As Date
'First day of current month
returnDate = DateSerial(Year(d), Month(d), 1)
'Forward a month
returnDate = DateAdd("m", 1, returnDate)
'back one day
returnDate = DateAdd("d", -1, returnDate)
LastDay = returnDate
End Function
Works by jumping to the beginning of the month, adding a month then subtracting a day (so 1st Feb->1st Mar->28 Feb)
Like this in VBA:
Sub LastDayOfMonth()
Dim dates As Range, dt As Range
Set dates = Range("A1") //Update as required
For Each dt In dates
dt = Application.WorksheetFunction.EoMonth(dt, 0) //e.g. 01/06/2018 ~~~> 30/06/2018
Next
End Sub
VBA way:
Function LastDayOfMonth(ByVal d As Date)
LastDayOfMonth = DateSerial(Year(d), Month(d), 1)
LastDayOfMonth = DateAdd("m", 1, LastDayOfMonth)
LastDayOfMonth = DateAdd("d", -1, LastDayOfMonth)
End Function
Construct new date:
year: from old date
month: from old date
day: 1
Add 1 month to new date.
Subtract 1 day from new date.
Steps 2 and 3 save you from all complexities of date calculations.
For Excel way, please refer to the other answer.

Vba days in week in another week

Currently I have this:
Now() - Weekday(Now(), vbMonday) + 1
The problem is, if I use a different week, the same date still shows.
I have a dropdownlist that shows me the days from the week I select. Now it selects it from this week, so also in week 1 the date of monday is already the 9th.
How it should be:
I select a weeknumber and the dates that correspondent with that weeknumber need to be shown in the dropdownlist.
Can somebody please help me? I really don't know what to do..
You could use something like this, if I've got you.
Function FirstMondayInWeek(intWeekNum As Integer) As Date
Dim d As Date
d = DateSerial(Year(Now) - 1, 12, 31)
Do Until Weekday(d, vbMonday) = 1
d = d + 1
Loop
FirstMondayInWeek = DateAdd("WW", intWeekNum - 1, d)
End Function

VBA to find Second sunday for March every year

I have an if condition in my VBA code to check if it is spring Day light savings day, which is the second Sunday of March. The below code works for all except when 3/1/2015 (for example) is Sunday, then this shows 3rd Sunday. I can add another condition to check if it is Sunday then don't add 7 to the formula, but is there a better way of doing this?
If my_date = (DATEVALUE("3/1/" & this_year) + 7+ CHOOSE(WEEKDAY(DATEVALUE("3/1/" & this_year), 1),7,6,5,4,3,2,1))
This works:
For VBA :
DateSerial(this_year, 3, 1) + 6 - WorksheetFunction.Weekday(DateSerial(this_year, 3, 1), 3) + 7
For Excel:
DateSerial(this_year, 3, 1) + 6 - Weekday(DateSerial(this_year, 3, 1), 3) + 7
Enter the year you want to look at in Cell A1, then select a cell where you want to see the date of the 2nd Sunday in March for the given year and run this code:
Sub test()
Dim i As Integer
Dim dt As Date
Dim y As Integer
i = 0
y = Range("A1").Value
dt = "3/1/" & y
While i < 2
If WeekdayName(Weekday(dt), False, vbUseSystemDayOfWeek) = "Sunday" Then
i = i + 1
If i <> 2 Then
dt = DateAdd("d", 1, dt)
End If
Else
If i <> 2 Then
dt = DateAdd("d", 1, dt)
End If
End If
Wend
ActiveCell.Value = dt
End Sub
I thought I would just add this below code for anyone else who comes across this. I wanted to create a GENERAL purpose block of code that gets any day of week of any month. Ie. if I want the second Sunday or the last Sunday I could retrieve this from one function. Thus I have written the below. You can alter it to how you need it. Ie. Sunday/ Monday or first, second or third etc. This is done by cycling through the days of the month and if the day return which ever day of week you are looking for you save the day in a collection. Once your have cycled through the month you then cycle through the collection to retrieve the necessary date you need!
Function DayOfMonth(theDate As String) As String
'cycle through the given month
'check each day of month and if sunday add day of month to collection
'then cycle through collection for required sunday of month
'daylight savings only happens in march and november
On Error Resume Next
Dim i As Long
Dim testDate As String 'this get passed through function
Dim theYear As Long, theMonth As Long
Dim dayCollection As New Collection
theYear = Year(theDate)
theMonth = Month(theDate)
'build collection of sunday's day of month
For i = 1 To 31
testDate = i & "/" & theMonth & "/" & theYear
If Weekday(testDate, vbSunday) = 1 Then
dayCollection.Add i
End If
Next i
For i = 1 To dayCollection.Count
'2nd sunday
If i = 2 Then
DayOfMonth = dayCollection(i) & "/" & theMonth & "/" & theYear
End If
'last sunday of month
If i = dayCollection.Count Then
DayOfMonth = dayCollection(i) & "/" & theMonth & "/" & theYear
End If
Next i
'clear collection
Set dayCollection = New Collection
End Function
Cheers!
Here's a slight modification to Slubee's answer which I find a little more elegant and easier to follow:
DateSerial(Year, 3, 1) - WorksheetFunction.Weekday(DateSerial(Year, 3, 1), 2) + 14
The 1st term = the date value of March 1st
The 2nd term = a number between 1(Monday) and 7 Sunday)
So (1st term minus 2nd term) gives you the last Sunday in February... and clearly adding 14 will get you the second Sunday of March.
With this structure, the formula can more easily be adapted to similar use cases such as the start/end of daylight saving time in Europe (last Sunday of March/October) or the end of USA DST (first Sunday of November).
If you start from the last day of the previous month, you can correctly calculate the second Sunday of the target month, even if it begins on a Sunday.
The following code sample calculates the start and end date/time of Daylight Saving Time for US areas that observe DST.
If you are developing a function to do this, be sure to test years like 2020 where March begins on a Sunday.
Dim dteLast As Date
Dim dteStart As Date
Dim dteEnd As Date
' DST starts on the second Sunday in March at 2 AM
dteLast = DateSerial(Year(dteDate), 3, 1) - 1
dteStart = dteLast - Weekday(dteLast) + 15 + TimeSerial(2, 0, 0)
' DST ends on the first Sunday in November at 2 AM
dteLast = DateSerial(Year(dteDate), 11, 1) - 1
dteEnd = dteLast - Weekday(dteLast) + 8 + TimeSerial(2, 0, 0)
If my_date = (DateSerial(this_year, 3, 1) + (8 - Weekday(DateSerial(this_year, 3, 1)) Mod 7) + 7) Then

Excel VBA Comparing between a given date and (given date - 2 months)

I am writing a code to ensure that the data date of a system is not later than 2 business month-end date. For instance, if the job run date for the system is 23/12/2015, the valid data date is 30/10/2015 and 30/11/2015. The dates involved are only business days.
I have this code below:
If DateDiff("m", dataDate, jobRunDate) > 2 Then
MsgBox "Error in dataDate"
End If
However, I do not know how to find:
The last day of the month
Compute 2 business month back
Any help will be greatly appreciated. Thanks!
To find the last day of the month, you can find the first day of the next month and subtract a day:
Dim last As Date
Dim current As Date
current = Now
last = DateSerial(Year(current), Month(current), 1) - 1
Debug.Print last
To get the last business day of a month, just subtract days until it falls on a weekday:
Do While Weekday(last, vbMonday) > 5
last = last - 1
Loop
Debug.Print last
Combining the 2 ideas and extracting it as a function gets you this:
Private Sub Example()
Debug.Print LastBizDayOfMonth(Year(Now), Month(Now) - 1)
Debug.Print LastBizDayOfMonth(Year(Now), Month(Now) - 2)
End Sub
Private Function LastBizDayOfMonth(inYear As Integer, inMonth As Integer) As Date
LastBizDayOfMonth = DateSerial(inYear, inMonth + 1, 1) - 1
Do While Weekday(LastBizDayOfMonth, vbMonday) > 5
LastBizDayOfMonth = LastBizDayOfMonth - 1
Loop
End Function
Here is how to get the last day of a month:
Sub LastDayOfMonth()
Dim d As Date
mnth = 12
yr = 2015
d = DateSerial(yr, mnth + 1, 0)
MsgBox d
End Sub
You must then subtract two months from that date. If the result falls on a Saturday or Sunday, you must decide if you want to go forward to the next Monday or backward to the previous Friday.

Determine how many days into the year a certain date is when the date is determined by a variable

What I am trying to do is check column AJ for each date that occurs during a year determined by variable "Año". For the dates that are I would like to see how far into the year they are (that is how many days after the first January each date occurs); this is the part that is giving me the error (indicated in my code). What I need is a function to give how many days into the year a date occurs or a better way of writing that line of code.
For Each cl In Workbooks(WbkA).Worksheets("Sheet1").Range("AJ2:AJ1000")
If (cl.Value - ("01/01/" & Año)) > 0 And (cl.Value - ("01/01/" & Año)) < 366 Then 'if it´s in this year
ValueA = ValueA + (cl.Value * ((cl.Offset(0, -13).Value - ("01/01/" & Año)) / 365)) ' this part is giving me the error
End If
End If
Next cl
You are complicating things too much. DateDiff can perform the calculations you want:
Dim iniDate As Date, curDate As Date
Dim ValueA As Integer, Año As Integer
Año = 2010
iniDate = Format(CDate("01/01/" & Año), "MM/dd/yyyy") 'You can change the Format
curDate = Format(CDate("01/05/" & Año), "MM/dd/yyyy")
ValueA = DateDiff("d", iniDate, curDate) 'RESULT -> 4
Dates are stored as the number of days since 1/1/1900, so you can just subtract two dates to get the number of days.
Dim lAno As Long
Dim rCell As Range
Dim dValueA As Double
lAno = 2010
For Each rCell In Sheet1.Range("AJ2:AJ100").Cells
If Year(rCell.Value) = lAno Then 'if it's in the year
'+= some value * the number of days
dValueA = dValueA + (rCell.Offset(0, -13).Value * (rCell.Value - DateSerial(lAno, 1, 1)))
End If
Next rCell