Looking to change this Microsoft Word VBA Code so that the expiration date is always every Monday of the week, not a specific date:
Sub MyMacro()
ExpirationDate = #6/1/2013#
If Now() < ExpirationDate Then
'Rest of macro goes here
End if
End Sub
Any thoughts on how to do this would be great :)
If Weekday(Date) = 2 Then ... 'Monday
Public Function FindMonday(dt As Date) As Date
Do Until WeekdayName(Weekday(dt)) = "Monday"
dt = DateAdd("d", 1, dt)
Loop
FindMonday = dt
End Function
ExpirationDate = (Date + 7) - (Weekday(Date) - Weekday(vbMonday))
This formula will always return the date of next Monday, as specified by "+7"
You don't need to declare the variable Expirationdate.
If Date < (Date + 7) - (Weekday(Date) - Weekday(vbMonday)) Then
will do the job.
Note that Now returns a date/time value whereas Date returns a date integer. If time is of the essence you would have to add it in. Add 0.5 to the above formula to fix the expiration time on next Monday, 12 noon.
I'd usually use this function:
Public Function PreviousMonday(CurrentDate As Date) As Date
PreviousMonday = CurrentDate - Weekday(CurrentDate - 2)
End Function
You can then call it as:
PreviousMonday(Date()) - would return 24/07/2017 if entered today (28th).
PreviousMonday(CDATE("1 July 2017")) - would return 26/06/2017
PreviousMonday(42430) would return 29/02/2016 (42430 = 1st March 2016).
Related
How can I get the ISO week number of some date in VBScript or VBA?
First, note that:
It is important to report the week year along with the week number, as the date's year could be different.
Several Windows components contain a bug for some years' last Monday.
In my experience the simplest, clearest and most robust way to compute this is:
Sub WeekNum(someDate, isoWeekYear, isoWeekNumber, isoWeekDay)
Dim nearestThursday
isoWeekDay = WeekDay(someDate, vbMonday)
nearestThursday = DateAdd("d", 4 - Int(isoWeekDay), someDate)
isoWeekYear = Year(nearestThursday)
isoWeekNumber = Int((nearestThursday - DateSerial(isoWeekYear, 1, 1)) / 7) + 1
End Sub
This also returns the ISO day of the week, counting from 1 for Mondays.
Enter any date into A1 cell, then run following code...
Range("A2").FormulaR1C1 = "=INT((R1C-DATE(YEAR(R1C-WEEKDAY(R1C-1)+4),1,3)+WEEKDAY(DATE(YEAR(R1C-WEEKDAY(R1C-1)+4),1,3))+5)/7)"
You can get it via DatePart() VBA function:
Sub IsoWeek()
Dim isoWeekNum As Byte
Dim myDate As Date
myDate = DateValue("01-01-2022")
isoWeekNum = DatePart("ww", myDate, vbMonday, vbFirstFourDays)
If isoWeekNum > 52 Then ' Bug check (to avoid the bug with Mondays)
If Format(myDate + 7, "ww", vbMonday, vbFirstFourDays) = 2 Then isoWeekNum = 1
End If
Debug.Print isoWeekNum
End Sub
So I need to know how I can grab every other Friday starting with the date of a Friday, have the program check if the date is one of those dates and if so do X function. So far I found how to find the Friday after one Friday, but I need it to gather up the dates and save them then check against them.
Dim payday as Date= GetNext(DayOfWeek.Friday)
Function GetNext(ByVal d As DayOfWeek, Optional ByVal StartDate As Date = Nothing) As Date
If StartDate = DateTime.MinValue Then StartDate = Now
For p As Integer = 1 To 7
If StartDate.AddDays(p).DayOfWeek = d Then Return StartDate.AddDays(p)
Next
End Function
Then Here is the If Statement I am thinking of
If Date.Today = payday Then
'do this
End If
Rough sketch of what I was thinking.
Dim startDate As Date 'fill with an initial Friday
Function IsPayday(Optional dte as Date? = Nothing) As Boolean
dte = If(dte, Today)
Return DateDiff(DateInterval.Day, startDate, dte) Mod 14 = 0
End Function
and use it:
Dim yesterday = Today.AddDays(-1)
If IsPayday(yesterday) Then
'yesterday was a pay day
End If
If IsPayday() Then
'today is a pay day
End If
I have a DateTimePicker named dtpDateSelection. When I select a date I need to break the date down into two variables. I need Quarter to equal the quarter that the date is in. And I need Year to equal the year that the date is in. I thought I knew how to do this but I'm having trouble. Here is the code I've tried:
Dim Year As String = DatePart("yyyy", dtpDateSelection)
Dim Quarter As String = DatePart("q", dtpDateSelection)
And this is the error I get:
Additional information: Argument 'DateValue' cannot be converted to type 'Date'.
A simple solution:
Dim year As Integer = DateTimePicker.Value.Year
Dim quarter As Integer = ((DateTimePicker.Value.Month - 1) \ 3) + 1
So you have the DateTime value from the DateTimePicker.Value property.
Using that you can retrieve the year of the date, like this:
Dim year As Integer = DateTimePicker.Value.Year
For determining the quarter the date is within, try this:
Public Shared Function DetermineQuarter(dateTime As DateTime) As Integer
If dateTime.Month <= 3 Then
Return 1
End If
If dateTime.Month <= 6 Then
Return 2
End If
If dateTime.Month <= 9 Then
Return 3
End If
Return 4
End Function
Now you can get the quarter value, like this:
Dim quarter As Integer = DetermineQuarter(DateTimePicker.Value)
As others pointed out, a DateTime value has a .Month member. For the quarter, I have always used a simple Choose function
Dim quarter As Integer = Choose(DateTimePicker1.Value.Month, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4)
Beyond that, your two lines of code work, but you need to add the .Value to the end of dtpDateSelection. The DatePart function 2nd parameter has an Object type, so it will allow you to pass in a control (which is what you are doing), but the end result will be an error. The .Value changes it to the date selected in the picker.
Dim Year As String = DatePart("yyyy", dtpDateSelection.Value)
Dim Quarter As String = DatePart("q", dtpDateSelection.Value)
I'm trying to find the number of weeks between two dates in Excel VBA (with some min/max functionality in between), was getting Type Mismatch error (Run-time error '13') for the following line:
WeeksWorked = Application.WorksheetFunction.RoundDown _
(52 * Application.WorksheetFunction.YearFrac _
(Application.WorksheetFunction.Max(DOH, DateValue("Jan 1, 2012")), _
DateValue("Dec 31, 2012")), 0)
Anyone have any direction as to what I'm doing wrong, it would be greatly appreciated!
Not sure why do you need to use this in VBA, here is something you can try.
In Excel:
Assuming Start Date is in A1, End Date is in A2, then A3,
=(NETWORKINGDAYS(A1,A2))/5
Now that is in the perspective of business days, thus giving 5 day week. If you need 7 day week with regular days,
=WEEKNUM(A3)-WEEKNUM(A2)
The function WEEKNUM() in the Analysis Toolpack addin calculates the correct week number for a given date, if you are in the U.S. The user defined function below will calculate the correct week number depending on the national language settings on your computer.
If you still need to use VBA try this: (as Tim pointed out DateDiff pretty handy.) Or you can even use Evaluate to trigger WEEKNUM.
Option Explicit
Function numWeeks(startDate As Date, endDate As Date)
numWeeks = DateDiff("ww", startDate, endDate)
End Function
Using Evaluate on WEEKNUM:
Function numWeeks(startDate As Range, endDate As Range)
Dim s As Integer, t As Integer
s = Application.Evaluate("=WEEKNUM(" & startDate.Address & ",1)")
t = Application.Evaluate("=WEEKNUM(" & endDate.Address & ",1)")
numWeeks = t - s
End Function
Reference for Excel VBA DataTime Functions
As suggested in the comments you could just do:
debug.print DateDiff("ww", DateValue("Jan 1, 2012"), DateValue("Dec 31, 2012"))
If for some reason you wanted to roll your own you could truncate the quotient of:
| day1 - day2 |
---------------
7
Example code:
Sub test_numWeeks_fn()
Call numWeeks(DateValue("Jan 1, 2012"), DateValue("Dec 31, 2012"))
End Sub
Function numWeeks(d1 As Date, d2 As Date)
Dim numDays As Long
numDays = Abs(d1 - d2)
numWeeks = Int(numDays / 7)
Debug.Print numWeeks
End Function
Result:
52
Try below code :
Sub example()
Dim dob As Date
dob = #7/31/1986#
Dim todaydt As Date
todaydt = Date
Dim numWeek As Long
numWeek = DateDiff("ww", dob, todaydt) ' Difference in weeks
End Sub
In vb.net I have two data values as shown below:
Dim startp as datetime
Dim endp as datetime
I have a function called ProcessData(soemdate) which processes dataporting.
In VB.net is there a way I can do something like
For each day between startp and endp
ProcessData(soemdate)
Next
Thanks
Here is another way to do this.
Dim startP As DateTime = New DateTime(2009, 1, 1)
Dim endP As DateTime = New DateTime(2009, 2, 1)
Dim CurrD As DateTime = startP
While (CurrD <= endP)
ProcessData(CurrD)
Console.WriteLine(CurrD.ToShortDateString)
CurrD = CurrD.AddDays(1)
End While
For Each Day As DateTime in Enumerable.Range(0, (endp - startp).Days) _
.Select(Function(i) startp.AddDays(i))
ProcessData(Day)
Next Day
Adding to Joel Coehoorn's answer which I personally think should be the accepted answer as I always try to avoid While loops no matter how safe they may appear. For...Each is a much safer approach although the enumerable isn't very pretty in-line. You can however move it to a function to keep things more readable, plus you can re-use as needed.
For Each Day As DateTime In DateRange(StartDate, EndDate)
ProcessData(Day)
Console.WriteLine(Day.ToShortDateString)
Next
Public Shared Function DateRange(Start As DateTime, Thru As DateTime) As IEnumerable(Of Date)
Return Enumerable.Range(0, (Thru.Date - Start.Date).Days + 1).Select(Function(i) Start.AddDays(i))
End Function
I also added 1 to Enumerable range since as Joel had it, it wouldn't return the end date and in my situation I needed it to return all dates in the range including the start and end days.
Enumerable.Range is a sort of loop in itself that adds i days to the startdate advancing i with each call from in this case 0 to the difference between start and end days + 1. So the first time it's called you get the result of Start.AddDays(0), next you'll get Start.AddDays(1) and so on until the range is complete.
You can easily loop through each day if you convert your dates to OLE Automation Date OADate where the left portion represents the day and the right portion represents the time.
For example #06/19/2018#.ToOADate converts to 43270.0
For loopDate As Double = #06/19/2018#.ToOADate To #07/01/2018#.ToOADate
Dim thisDate As Date = DateTime.FromOADate(loopDate)
' Do your stuff here e.g. ProcessData(thisDate)
Next
Yes, you can use an accumulator date:
Dim Accumulator as DateTime
Accumulator = startp
While (Accumulator <= endp)
Accumulator = Accumulator.AddDays(1)
End While
Not tested, and I'm a C# programmer, so be easy if my syntax is wrong.
For those that come looking later, I had to add a +1 to the Range endpoint to get this to work for when the start and end were the same. Here is the code I used.
For Each Day As DateTime in Enumerable.Range(0, (endp - startp).Days + 1) .Select(Function(i) startp.AddDays(i))
'Do work here
Next Day
Set a calendar table with all dates and query values from there.
SQL:
Select Date as MyDate from tblCalendar Where Date >= StartDt And Date <= EndDate
.NET:
While Reader.read
process(MyDate)
End While