Populate Months Between Two Dates
- The following is an automated version which uses the
Worksheet Change event
i.e. it runs only if you manually or via VBA
change the values (not by formula). You don't have to run anything just copy the codes to the appropriate modules and adjust the values in the constants section.
- If for some reason you don't want the automation, you can delete the code in the sheet module, delete the three constants below
Option Explicit
in the standard module and uncomment the three constants in populateMonths
. Now it will only work with populateMonthsInit
.
- If the start date is the last date of the month, the month will not be included. Similarly, if the end date is the first date of the month, the month will not be included. This can easily be adjusted.
Sheet Module e.g. Sheet1
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim rng As Range
Set rng = Intersect(Union(Range(StartDateCell), Range(EndDateCell)), Target)
If Not rng Is Nothing Then
populateMonths
End If
End Sub
Standard Module e.g. Module1
Option Explicit
Public Const StartDateCell As String = "B1"
Public Const EndDateCell As String = "B2"
Private Const FirstCell As String = "B4"
Sub populateMonthsInit()
populateMonths
End Sub
Sub populateMonths(Optional ws As Worksheet)
'Const StartDateCell As String = "B1"
'Const EndDateCell As String = "B2"
'Const FirstCell As String = "B4"
If ws Is Nothing Then
Set ws = ThisWorkbook.ActiveSheet
End If
With ws.Range(FirstCell)
Dim Data As Variant
Data = getMonthNumbers(.Worksheet.Range(StartDateCell).Value, _
.Worksheet.Range(EndDateCell).Value)
.Resize(.Worksheet.Rows.Count - .Row + 1).ClearContents
.Value = 0 ' Not sure what that's all about.
If Not IsEmpty(Data) then
.Offset(1).Resize(UBound(Data, 1)).Value = Data
End if
End With
End Sub
Function getMonthNumbers( _
ByVal StartDate As Date, _
ByVal EndDate As Date) _
As Variant
On Error GoTo clearError
Dim Months As Long: Months = DateDiff("m", StartDate, EndDate)
Dim StartMonth As Long
If Month(StartDate + 1) = Month(StartDate) Then
Months = Months + 1
StartMonth = modMonth(Month(StartDate))
Else
StartMonth = modMonth(Month(StartDate) + 1)
End If
If Month(EndDate - 1) <> Month(EndDate) Then
Months = Months - 1
End If
Dim Data() As Long: ReDim Data(1 To Months, 1 To 1)
Data(1, 1) = StartMonth
Dim i As Long
For i = 2 To Months
Data(i, 1) = modMonth(Data(i - 1, 1) + 1)
Next i
getMonthNumbers = Data
ProcExit:
Exit Function
clearError:
Resume ProcExit
End Function
Function modMonth( _
m As Long) _
As Long
modMonth = IIf(m Mod 12, m Mod 12, 12)
End Function
Sub TESTgetMonthNumbers()
Dim Data As Variant: Data = getMonthNumbers(Range("B1"), Range("B2"))
If Not IsEmpty(Data) Then
Debug.Print Join(Application.Transpose(Data), vbLf)
Else
Debug.Print "Nope."
End If
End Sub
SEQUENCE
function? If it does you can use=SEQUENCE(B3-B2,,0,1)
where B3 and B2 are your dates. – Darren Bartrup-Cook