Multiple Apps

Function to Find the date of the 'Nth' Weekday of a Given Month

Ease of Use

Intermediate

Version tested with

2000, 2002 

Submitted by:

matthewspatrick

Description:

This function will find the date of a weekday in any arbitary position within a given month, specified by number 1-5, or by "L" for last. Function as written is for Excel, but with minor changes will work in Access, other VBA-supported applications, or in VB 

Discussion:

Suppose you have to build a schedule of events that will always occur on the 3rd Wednesday of a month, or the last Saturday. Figuring this out can be tedious, and can lead to some extremely complicated formulas. This function makes determining such positional days very fast and easy, and allows you to specify the last instance of a given weekday without first making you figure out if it's the 4th or the 5th instance. 

Code:

instructions for use

			

Option Explicit Public Function NthWeekday(Position, DayIndex As Long, TargetMonth As Long, Optional TargetYear As Long) ' Returns any arbitrary weekday (the "Nth" weekday) of a given month ' Position is the weekday's position in the month. Must be a number 1-5, or the letter L (last) ' DayIndex is weekday: 1=Sunday, 2=Monday, ..., 7=Saturday ' TargetMonth is the month the date is in: 1=Jan, 2=Feb, ..., 12=Dec ' If TargetYear is omitted, year for current system date/time is used ' This function as written supports Excel. To support Access, replace instances of ' CVErr(xlErrValue) with Null. To use with other VBA-supported applications or with VB, ' substitute a similar value Dim FirstDate As Date ' Validate DayIndex If DayIndex < 1 Or DayIndex > 7 Then NthWeekday = CVErr(xlErrValue) Exit Function End If If TargetYear = 0 Then TargetYear = Year(Now) Select Case Position 'Validate Position Case 1, 2, 3, 4, 5, "L", "l" ' Determine date for first of month FirstDate = DateSerial(TargetYear, TargetMonth, 1) ' Find first instance of our targeted weekday in the month If Weekday(FirstDate, vbSunday) < DayIndex Then FirstDate = FirstDate + (DayIndex - Weekday(FirstDate, vbSunday)) ElseIf Weekday(FirstDate, vbSunday) > DayIndex Then FirstDate = FirstDate + (DayIndex + 7 - Weekday(FirstDate, vbSunday)) End If ' Find the Nth instance. If Position is not numeric, then it must be "L" for last. ' In that case, loop to find last instance of the month (could be the 4th or the 5th) If IsNumeric(Position) Then NthWeekday = FirstDate + (Position - 1) * 7 If Month(NthWeekday) <> Month(FirstDate) Then NthWeekday = CVErr(xlErrValue) Else NthWeekday = FirstDate Do Until Month(NthWeekday) <> Month(NthWeekday + 7) NthWeekday = NthWeekday + 7 Loop End If ' This only comes into play if the user supplied an invalid Position argument Case Else NthWeekday = CVErr(xlErrValue) End Select End Function

How to use:

  1. Paste the code above into a regular module in your project
  2. If you are using this code in Access, use Find/Replace (Ctrl-H in the VB Editor) to replace the three instances of CVErr(xlErrValue) with Null. If you are using this code in another VBA-supported application or in VB, substitute a similarly-appropriate return value indicating invalid inputs
  3. Use the function in your code, in your worksheet formulas (Excel; see the attached file for examples), or in your queries, forms, and reports (Access).
  4. Be advised that if you ask for the 5th instance of a given weekday, and the target month has only four instances, you will get either an error (as written for Excel) or Null (with modification for Access)!
 

Test the code:

  1. Try entering various values of the given arguments and compare the results to a calendar.
  2. See the example file for samples on how to use this function in Excel.
 

Sample File:

NthWeekdayExample.zip 10.01KB 

Approved by mdmackillop


This entry has been viewed 295 times.

Please read our Legal Information and Privacy Policy
Copyright @2004 - 2020 VBA Express