VBA change specific bit of date - vba

I currently have a spreadsheet with pre written dates in order in a dd/mm/yyyy format, but i want to be able to change the entire sheet so that when i select a month from a drop down list it changes all the dates so they stay starting at the 1st through to the 31st, but only the month changes, using visual basic. I can use this to set specific dates,
Range("C3") = Format(DateSerial(Year:=2005, Month:=2, Day:=3), "mm-dd-yyyy")
But can i change just the month using something like this for example
Range("C3") = Format(DateSerial(Month:=5), "mm-dd-yyyy")

You could do something like this:
Function MakeDates(startDate As Date) As Date()
Dim myDates() As Date, myYear As Integer, myMonth As Integer, daysInMonth As Integer
Dim firstOfMonth As Date, firstOfNextMonth As Date, d As Integer
myYear = Year(startDate)
myMonth = Month(startDate)
firstOfMonth = DateSerial(myYear, myMonth, 1)
firstOfNextMonth = DateSerial(myYear, myMonth + 1, 1)
daysInMonth = DateDiff("d", firstOfMonth, firstOfNextMonth)
ReDim myDates(daysInMonth - 1)
For d = 1 To daysInMonth
myDates(d - 1) = DateSerial(myYear, myMonth, d)
Next d
MakeDates = myDates
End Function
Then you can call it like this
Dim d
d = MakeDates(#2/1/2014#)
Range("A1").Resize(rowsize:=31).Value = ""
Range("A1").Resize(rowsize:=UBound(d) + 1) = WorksheetFunction.Transpose(d)
That second to last line will remove the excess dates for you.
You should have your range formatted as a date. You can do that in code or just do it once in Excel. The latter is probably easier.

Related

Add month to previous cells date For each loop

All,
I have written a little procedure which I would like a for each loop to insert the current month into the first cell "01"/MM/YY and then add one month to the date as it goes through the loop. Using the example below;
K1 = 01/06/2018
L1 = 01/07/2018
M1 = 01/08/2018 etc
The code I am using is below - The error is on the DateAdd line.
Sub test()
Dim dt As date
dt = "01/" & Application.Text(Now(), "MM/YY")
Dim i As Double
i = 1
For Each c In Range("K1:XFD1")
If c.Value = "" Then Exit For
c.Value = dt
'change date to one months time
dt = DateAdd(m, i, dt)
i = i + 1
Next c
End Sub
Any help regarding this would be much appreciated.
Put "m" not m. m would be a variable. "m" is a literal string representing the argument being "month".
dt = DateAdd("m", i, dt)

Find monday of after a certain date

I have 2 tables, Table 1 and Table 2. Both the tables have one date column each. I am inserting the first Monday of the month on top of the table 1 and Table 2, both. I will fetch date value from each row of the table 2, and if it is more than the value on top of the table, I will insert 0. If the date value in the table 2 is "16/02/2018", and it is not a Monday, I will insert the Monday after it, and the value 1 for that record.How can I proceed with it? Please help.
Dim col_tab2_dat as Date
first_day = DateSerial(Year(Date), Month(Date), 1)
last_day = DateSerial(Year(Date), Month(Date) + 1, 1)
curr_month= Format(first_day, "mmm")
w = Weekday(first_day , vbMonday)
FirstMonday = first_day + IIf(w <> 1, 8 - w, 0)
tab1_last_lin = ws.Columns(2).Find("Total(T1)").Row
tab2_last_lin = ws.Columns(2).Find("Total(T2)").Row
find_tab2 = ws.Columns(1).Find("Table 2").Row
last_lin = Range("B" & Rows.Count).End(xlUp).Row
last_col_tab1 = ws.Cells(tab1_last_lin, ws.Columns.Count).End(xlToLeft).Column
last_col_tab2 = ws.Cells(tab2_last_lin, ws.Columns.Count).End(xlToLeft).Column
last_dat = ws.Cells(2, last_col_tab1 - 1).Value
new_date = last_dat + 7
For i = find_tab2 + 3 to tab2_last_lin
ws.Cells(find_tab2 + 3, 1).Value = col_tab2_dat
If col_tab2_dat > last_dat Then
I am stuck here. What to do next?
End If
Next i
Here is a function that will return the next Monday:
Public Function GetNextMonday(dt As Date) As Date
Do Until Weekday(dt, vbSunday) = 2
dt = DateAdd("d", 1, dt)
Loop
GetNextMonday = dt
End Function
Here's a function that will work for any day of the week.
NextWeekday Function:
Function NextWeekday(FromDate As Date, vbWeekday As VbDayOfWeek) As Date
If Weekday(FromDate) < vbWeekday Then
NextWeekday = FromDate + vbWeekday - Weekday(FromDate)
Else
NextWeekday = FromDate + 7 + vbWeekday - Weekday(FromDate)
End If
End Function
It takes two arguments:
FromDate: The Date of which you are wanting to find the next weekday of. You can simply use "Date" as the argument for today's Date.
vbWeekday: The upcoming day of the week you are wanting the date for.
VBA Example:
Once you've added the above function to your code module, it's easy to get its value:
Sub Main()
Dim NextThursday As Date
NextThursday = NextWeekday(Date, vbThursday)
End Sub
Worksheet Formula Example:
Or you can use it as a worksheet function:
=NextWeekday(Today(), 5)
Worksheet Formula Considerations:
Notice in the worksheet formula we had to remove the vbThursday constant as worksheet functions doesn't have this functionality built-in. However, if you want to still use these constant values in your worksheet, you can create them yourself by using the Name Manager.
Click on the Formulas Tab, then on Define Name
Start creating your constants starting at vbSunday = 1 through vbSaturday = 7 by placing the Constant Name in the Name: field, and the value in the Refers to: field:
And there you have it! You can now refer to them using your named values:
Additional Example Usage:
Comments:
The benefit of using the VbDayOfWeek Type is that you will now gain IntelliSense when using the function:

Get First And Last Day Of Year

In VBA I know you can use this syntax to subtract a year from a date
Dim testdate As String, DateTest As String
testdate= "03/21/2017"
DateTest = Month(testdate) & "/" & Day(testdate) & "/" & Year(testdate) - 1
But how could you find the first and last date of a given year? For example, let's use the same date
testdate = "03/21/2017"
and get the following values
firstdate = "01/01/2017"
lastdate = "12/31/2017"
You can use DateSerial:
Sub Test()
Dim dt As Date, firstDay As Date, lastDay As Date
dt = Date
firstDay = DateSerial(Year(dt), 1, 1)
lastDay = DateSerial(Year(dt), 12, 31)
Debug.Print firstDay
Debug.Print lastDay
End Sub
If it is always the beginning and the end of the year that interest you, you can just use the 1st of January and the 31st of december. To mimic your syntax :
Dim testdate As String, DateTest As String
testdate= "03/21/2017"
FirstDayOfYear = "1/1/" & Year(testdate)
LastDayOfYear = "12/31/" & Year(testdate)

Special date formatted string to Date (VB.net)

If i have a string containing a date formatted like this:
1402-3
which means Year: 2014, Week: 02 and Day number 3 (monday is 1), how can i convert this to a normal date? (in this case the date above is today; 2014-01-08 - wednesday 8 jan 2014)
Edit: I came up with a function like this, can anyone tell if this is gonna fail or maybe have a better and better coded function/solution?
Private Function StrangeFormattedDateToRegularDate(ByVal StrangeDate As String) As Date
Dim Y As String = "20" & StrangeDate.Substring(0, 2) 'I'll be dead before this fails, haters gonna hate
Dim W As String = StrangeDate.Substring(2, 2)
Dim D As String = StrangeDate.Substring(5, 1)
'Get first day of this year
Dim RefDate As Date = New Date(CInt(Y), 1, 1)
'Get the first day of this week (can be the year before)
Dim daysOffSet As Integer = DayOfWeek.Monday - RefDate.DayOfWeek
RefDate = RefDate.AddDays(daysOffSet)
'Add as many days as the weeks is
RefDate = RefDate.AddDays(7 * CInt(W))
'now the date is the last day of this week (plus one day), remove the days that are ahead, and remove that extra day
Dim daysToRemove = ((7 - CInt(D)) * -1) - 1
RefDate = RefDate.AddDays(daysToRemove)
Return RefDate
End Function
This should be what you're looking for :) This looked challenging so I tried it. Tell me if it works for you or not :)
Function GetDate(InputDate As String) As DateTime
Dim FirstDayofYear As Date = CType("1/1/20" & Mid(InputDate, 1, 2), Date)
Dim LastDayofYear As Date = CType("12/31/20" & Mid(InputDate, 1, 2), Date)
Dim target As Date
For x = 0 To DateDiff(DateInterval.Day, FirstDayofYear, LastDayofYear)
Dim dfi = DateTimeFormatInfo.CurrentInfo
Dim calendar = dfi.Calendar
Dim weekOfyear = calendar.GetWeekOfYear(FirstDayofYear.AddDays(x), dfi.CalendarWeekRule, DayOfWeek.Sunday)
If CInt(Mid(InputDate, 3, 2)) = weekOfyear And CInt(Mid(InputDate, InStr(InputDate, "-") + 1)) = FirstDayofYear.AddDays(x).DayOfWeek Then
target = FirstDayofYear.AddDays(x)
GoTo skip
End If
Next x
skip:
Return target
End Function
This works up to Year 2099. We're probably all dead by then.

Getting Dates of Current week does not work as expected

iam trying to get the Dates (Monday - Sunday) for the current Week.
This is my current Code:
Dim kw As Integer = DatePart(DateInterval.WeekOfYear, Now, , FirstWeekOfYear.FirstFourDays)
If DatePart(DateInterval.Weekday, Now, Microsoft.VisualBasic.FirstDayOfWeek.Sunday) = 6 Then
kw = kw + 1
End If
Dim CurrDateFirstDay As Date = DateAdd(DateInterval.Day, 1, ReturnDateForWeekNumber(kw))
For i = 1 To 7
strCurrDay = FormatDateTime(CurrDateFirstDay, DateFormat.LongDate)
........
My Problem is that my code starts at 16.01.2013 and the last date is Thuesday 22.01.2013 next week. Why is that? Why does he start Wednesday 16.01.2013 and not Monday 14.01.2013? And why do i get returned dates of the next week? What iam doing wrong?
Edit:
ReturnDateForWeekNumber:
Public Shared Function ReturnDateForWeekNumber(ByVal iWeek As Integer) As DateTime
Return DateAdd(DateInterval.WeekOfYear, iWeek - 1, FirstDayOfYear)
End Function
What am I doing wrong?
You should step through your code in the debugger and observe the result, as I did:
Dim kw As Integer = DatePart(DateInterval.WeekOfYear, Now, , FirstWeekOfYear.FirstFourDays)
This returns the current week, which is week 3.
If DatePart(DateInterval.Weekday, Now, Microsoft.VisualBasic.FirstDayOfWeek.Sunday) = 6 Then
kw = kw + 1
End If
This checks if the weekday is the 6th day of the week (friday). We're not friday so If condition is not entered.
Dim CurrDateFirstDay As Date = DateAdd(DateInterval.Day, 1, ReturnDateForWeekNumber(kw))
This adds one day to the result of ReturnDateForWeekNumber, which returns:
Return DateAdd(DateInterval.WeekOfYear, iWeek - 1, FirstDayOfYear)
This adds 2 (week 3 minus 1) weeks to the first day of the year (Jan 1st), a tuesday. Jan 1st + 2 weeks = January 15th.
Now remember that you add one day to ReturnDateForWeekNumber, that's why CurrDateFirstDay has a value of January 16th.
Edit
I think your code is overly complicated and uses a lot of legacy VB6 functions. I would do it this way:
Dim myDate As Date = DateTime.Today
Dim dayDiff As Integer = myDate.DayOfWeek - DayOfWeek.Monday
Dim currentDay As Date = myDate.AddDays(-dayDiff) 'Monday
For i = 1 to 7
Console.WriteLine(currentDay)
'Do something with current day
currentDay = currentDay.AddDays(1)
Next
You might have to do some adjustments for your case but I believe this approach is simpler and less error prone.
Dim dateStartDateOfWeek As Date = GetWeekStartDate(52, 2014)
Dim dateEndDateOfWeek As Date = DateAdd(DateInterval.Day, 7, dateStartDateOfWeek)
Private Function GetWeekStartDate(ByVal weekNumber As Integer, ByVal year As Integer) As Date
Dim startDate As New DateTime(year, 1, 1)
Dim weekDate As DateTime = DateAdd(DateInterval.WeekOfYear, weekNumber - 1, startDate)
Return DateAdd(DateInterval.Day, (-weekDate.DayOfWeek) + 1, weekDate)
End Function