I hope you guys can help me. I have an Excel sheet with data that I want to copy some some values and move them to another column.
The data currently is something like this:
A B
...
20:00:00 2456
21:00:00 2147
22:00:00 5623
23:00:00 1247
00:00:00 3549
01:00:00 1234
...
I have data from several days, and when I found the string "00:00:00" which is the beginning of another day, I want to copy the prior 24 values to the next column.
The result should be something like this:
A B C D
...
20:00:00 2456
21:00:00 2147
22:00:00 5623
23:00:00 1247
00:00:00 3549
01:00:00 1234
...
22:00:00 2418
23:00:00 3245
00:00:00 3549
01:00:00 5437
I've started to try found the row number of the values equal to "00:00:00", save them in an array and then make the difference between row value(i+1) "00:00:00" and row value(i) "00:00:00"
Thanks and regards,
Daniel Duarte
this has been tested just now:
Sub move()
Dim column As Integer
column = 3
For i = 1 To Cells(Rows.Count, 1).End(xlUp).Row
If Cells(i + 1, 1).Value > Cells(i, 1).Value and Cells(i + 1, 1).Value <> "" Then
Cells(i, column).Value = Cells(i, 2).Value
Cells(i, 2).Value = ""
Else
column = column + 1
Cells(i, column).Value = Cells(i, 2).Value
Cells(i, 2).Value = ""
End If
Next
End Sub
one caveat in this is the case that it is checking if the next hour is less than current, i.e. hour goes back to zero at midnight and it increases the column where it pastes too. It will work for any times within 24 hours window, irrelevant from minutes/seconds
You made a mention of the '24', so I thought it was 24 elements consistently. Is the timing consistent, or variable?
The solution in VBA is below.
Given something like this:
time value
20:00 100
21:00 200
22:00 300
23:00 400
0:00 500
1:00 600
2:00 700
3:00 800
4:00 900
5:00 1000
6:00 1100
7:00 1200
8:00 1300
9:00 1400
10:00 1500
11:00 1600
12:00 1700
13:00 1800
14:00 1900
15:00 2000
16:00 2100
17:00 2200
18:00 2300
19:00 2400
20:00 2500
21:00 2600
22:00 2700
23:00 2800
0:00 2900
1:00 3000
2:00 3100
3:00 3200
4:00 3300
5:00 3400
6:00 3500
7:00 3600
8:00 3700
9:00 3800
10:00 3900
11:00 4000
12:00 4100
13:00 4200
14:00 4300
15:00 4400
16:00 4500
17:00 4600
18:00 4700
19:00 4800
20:00 4900
21:00 5000
22:00 5100
23:00 5200
Is this what you are looking for?
Option Explicit
Sub shift()
Dim Test As String
Dim NumRows As Integer
Dim CurrentRow As Integer
Dim ToCopy As String
Dim x As Integer
Dim i As Integer
' Set numrows = number of rows of data.
NumRows = Range("A2", Range("A2").End(xlDown)).Rows.Count
' loop around
For x = 0 To NumRows - 1
Range("A2").Offset(x, 0).Select
Test = ActiveCell.Text
If Val(Test) = 0 Then
CurrentRow = ActiveCell.Row
If ((CurrentRow - 24) > 1) Then
For i = 1 To 24
If ((CurrentRow - i - 24) > 0) Then
ToCopy = ActiveCell.Offset(-i - 24 + 1, 1).Text
ActiveCell.Offset(-i + 1, 2).Value = ToCopy
End If
Next i
End If
Else
End If
Next
End Sub
Modifying this for the arbitrary case; for example, with time differences of 0:15.
This is a bit wordy/pendantic, but gives you the idea.
Option Explicit
Sub shift_arb()
Dim Test As String
Dim StartRow As Integer
Dim EndRow As Integer
Dim NumRows As Integer
Dim nZeroRows As Integer
Dim CurrentRow As Integer
Dim ToCopy As String
Dim x As Integer
Dim i As Integer
' Set numrows = number of rows of data.
NumRows = Range("A2", Range("A2").End(xlDown)).Rows.Count
' Establish "For" loop to loop "numrows" number of times.
For x = 0 To NumRows - 1
Range("A2").Offset(x, 0).Select
Test = ActiveCell.Text
' If we meet the critera; store the row values of the zero rows
If TimeValue(Test) = "12:00:00 AM" Then
nZeroRows = nZeroRows + 1
StartRow = EndRow
EndRow = ActiveCell.Row
' Only do this if you've hit the second zero row
' After this, we have to backfill the first, since we don't know the
' gap between the zeros
If (nZeroRows > 1) Then
' Go from one zero row to the next
For i = 0 To (EndRow - StartRow)
If ((StartRow - i) > 1) Then
ToCopy = Cells(StartRow - i, 2).Text
Cells(EndRow - i, 3).Value = ToCopy
End If
Next i
End If
End If
Next x
' At the end, cleanup, and do the rest.
Debug.Print StartRow, EndRow, ActiveCell.Row
For i = 0 To (EndRow - StartRow)
If ((i + EndRow - 1) < ActiveCell.Row) Then
ToCopy = Cells(StartRow + i, 2).Text
Cells(EndRow + i, 3).Value = ToCopy
End If
Next i
End Sub
Related
I am trying to calculate a 6 month running sum of "Points" for each badge number. The sum only applies to fields with points greater than 0.
I have been trying to do this using an array and a For statement, but I'm not getting anywhere.
Sub TestArray()
'
'
'
' Test Array Macro
Dim Badges() As Long
Dim Badge As Variant
Dim i As Long
Dim x As Double
Dim Worksheet1 As Worksheet
Dim AbsCode As Long
Dim sht As Worksheet
Dim LastRow As Long
Set sht = ActiveSheet
'Using Find Function
LastRow = sht.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
Set Worksheet1 = ActiveWorkbook.Worksheets("Attendance Data") ' Change name of sheet if necessary
BadgeNo = 1
AbsCode = 3
Hours = 5
Points = 9
Rules = 10
test = 15
ReDim Badges(2 To LastRow, 1 To 1)
For Each Badge In Badges
For i = 2 To LastRow
If Worksheet1.Cells(i, Points).Value > 0 Then
Worksheet1.Cells(i, test).Value = Application.WorksheetFunction.Sum(Worksheet1.Cells(i, Points).Value)
Else: Worksheet1.Cells(i, test).Value = 0
End If
Next i
Next Name
End Sub
The answer that I'm looking for is in the "6 Month Points" column below.
Badge No. Incident Date Points 6 Month Points
30004832 1/13/2018 0.5 0.5
30004832 1/27/2018 0.0 0
30004832 4/5/2018 1.0 1.5
30004832 7/19/2018 0.0 0
30004832 7/22/2018 0.5 1.5
30004832 9/22/2018 1.0 2.5
30005505 8/4/2018 0.5 0.5
30005505 12/6/2018 0.5 1
30005914 12/20/2018 0.0 0
30004641 1/18/2018 0.5 0.5
30004641 2/2/2018 0.5 1
30004641 7/17/2018 0.0 0
30004641 10/16/2018 0.0 0
30000503 4/12/2012 0.0 0
30000503 5/3/2012 0.0 0
30000503 6/14/2012 0.0 0
I automated a montecarlo simulation for stock and option prices that runs 10 thousand paths for 606 trading days. All and all it works fine, the problem is that is slow. The slow part of the code is when it has to write an array of say 400 x 10000 to the spreadsheet, then export it into a new CSV file and save it.
It does this for a 25 option portfolio (it takes 1 minute per option.) So overall it takes 25 minutes, which is unacceptable. How can I write directly to CSV the arrays of data that I am filling with the simulation? I need to keep all stock prices, option prices and total portfolio value. Below is the code that I have created for this.
Sub Background_simulation()
0 Application.ScreenUpdating = False
1 Windows("Option Portfolio Simulation v7.xlsm").Activate
2 Sheets("Export").Activate
3 Dim Arr() As Variant
4 ArrStock = Range("F11:NTU616")
6 ArrOption = Range("F621:NTU1226")
7 Sheets("Export").Activate
8 Dim DestinationStock As Range
9 Set DestinationStock = Range("F11")
10 Dim DestinationOption As Range
11 Set DestinationOption = Range("F621")
12 Dim RAND(1 To 606, 1 To 10000) As Variant
13 Paths = Range("D6").Value
15 Dim Option_Paths(1 To 606, 1 To 10000) As Variant
16 Dim St_Paths(1 To 606, 1 To 10000) As Variant
17 Dim Options_Total(1 To 606, 1 To 10000) As Variant
18 FromOption = Range("D7").Value
19 UpToOption = Range("D8").Value
20 Sheets("Portfolio").Select
21 Let MaxExpirationOfSet = Application.WorksheetFunction.Max(Range("BC2:BC26").Value)
22 Sheets("Export").Select
23 For a = 2 To 606
24 For b = 1 To Paths
25 Randomize
26 RAND(a, b) = Application.WorksheetFunction.NormInv(RND(), 0, 1)
27 Next
28 Next
31 For Option_Nr = FromOption To UpToOption
32 Sheets("Export").Select
33 Range("F11:NTU616").Select
34 Selection.ClearContents
35 Range("F621:NTU1226").Select
36 Selection.ClearContents
38 Range("B1").Select
39 ActiveCell.FormulaR1C1 = Option_Nr
42 Calls = Range("L3").Value
43 If Calls = 0 Then GoTo 2010
44 St = Range("G2").Value
45 Rf = Range("G3").Value
46 Sigma = Range("G4").Value
47 dt = 1 / 250
48 mrn = Rf - (1 / 2) * Sigma ^ 2
49 X = Range("L5").Value
50 Expiration_Date = Range("D4").Value
120 For b = 1 To Paths
130 RAND(1, b) = 1
140 St_Paths(1, b) = St
150 Option_Paths(1, b) = Application.WorksheetFunction.Max(St - X, 0) * Calls
160 Options_Total(1, b) = Options_Total(1, b) + Option_Paths(1, b)
170 Next
190 For a = 2 To Expiration_Date
200 For b = 1 To Paths
600 St_Paths(a, b) = St_Paths(a - 1, b) * Exp(mrn * dt + Sigma * (dt) ^ (1 / 2) * RAND(a, b))
700 Option_Paths(a, b) = Application.WorksheetFunction.Max(St_Paths(a, b) - X, 0) * Calls
701 Options_Total(a, b) = Options_Total(a, b) + Option_Paths(a, b)
703 Next
704 Next
705 For a = (Expiration_Date + 1) To MaxExpirationOfSet
706 For b = 1 To Paths
707 St_Paths(a, b) = St_Paths(a - 1, b)
710 Option_Paths(a, b) = Option_Paths(a - 1, b)
711 Options_Total(a, b) = Options_Total(a - 1, b)
712 Next
730 Next
740 Sheets("Export").Select
750 Range("F11:NTU616").Select
760 Selection.ClearContents
770 Range("F621:NTU1226").Select
780 Selection.ClearContents
790 Range("A1").Select
800 DestinationStock.Resize(UBound(ArrStock, 1), UBound(ArrStock, 2)).Value = St_Paths
810 DestinationOption.Resize(UBound(ArrOption, 1), UBound(ArrOption, 2)).Value = Option_Paths
830 Sheets("Export").Copy
840 Range("F620").Select
845 ActiveWorkbook.BreakLink Name:= _
"C:\Users\pmesples\Desktop\Options\Option Portfolio Simulation v7.xlsm", Type _
:=xlExcelLinks
850 ChDir "C:\Users\pmesples\Desktop\Options"
860 ActiveWorkbook.SaveAs Filename:="C:\Users\pmesples\Desktop\Options\" & Option_Nr & ".csv", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
900 ActiveWindow.Close
1000 Sheets("Export").Select
1001 Range("F" & 620 + MaxExpirationOfSet & ":NTU" & 620 + MaxExpirationOfSet).Select
1002 Selection.Copy
1003 Sheets("Results").Select
1004 Cells(5, Option_Nr + 3).Select
1005 Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True
1006 Sheets("Export").Select
1010 Range("F11").Select
1020 Range(Selection, Selection.End(xlToRight)).Select
1030 Range(Selection, Selection.End(xlDown)).Select
1040 Selection.ClearContents
1050 Selection.End(xlDown).Select
1060 Range("F621").Select
1080 Range(Selection, Selection.End(xlDown)).Select
1090 Range(Selection, Selection.End(xlToRight)).Select
2000 Selection.ClearContents
2005 Range("A1").Select
2010 Next
2015 Range("B1").Select
2016 ActiveCell.FormulaR1C1 = 26
2020 DestinationOption.Resize(UBound(ArrOption, 1), UBound(ArrOption, 2)).Value = Options_Total
2030 Sheets("Export").Copy
2040 Range("F620").Select
2045 ActiveWorkbook.BreakLink Name:= _
"C:\Users\pmesples\Desktop\Options\Option Portfolio Simulation v7.xlsm", Type _
:=xlExcelLinks
2050 ChDir "C:\Users\pmesples\Desktop\Options"
2060 ActiveWorkbook.SaveAs Filename:="C:\Users\pmesples\Desktop\Options\26.csv", _
FileFormat:=xlOpenXMLWorkbook, CreateBackup:=False
2100 ActiveWindow.Close
2110 Sheets("Export").Select
2215 Range("B1").Select
2120 ActiveCell.FormulaR1C1 = 1
End Sub
You could probably get rid of selects and selections to speed up the macro, like:
32 Sheets("Export").Select
33 Range("F11:NTU616").Select
34 Selection.ClearContents
could be replaces by
32 Sheets("Export").Range("F11:NTU616").ClearContents
but you probably lost most of valuable seconds while saving file, as you already have noticed. Indeed, you could try export to file, see my subroutine:
Private Sub PrintToCSV(sFileName As String, rng As Range)
Dim TextFile As Integer
Dim FilePath As String
Dim FileContent As String
Dim cl As Range
FilePath = ThisWorkbook.Path & "\something something\" & sFileName & ".csv"
TextFile = FreeFile
Open FilePath For Output As TextFile
For Each cl In rng
Print #TextFile, cl.Value
Next cl
Close TextFile
End Sub
But, generally speaking, VBA is scripting language, so it is slow. I am not sure if writing to file will be faster than saving as, but you may try.
I currently read a 2-dimensional range into an Excel VBA array like so:
Set Ws = Sheet1
Ws.Activate
LastRow = Ws.Cells.Find("*", searchorder:=xlByRows, searchdirection:=xlPrevious).Row
LastCol = Ws.Cells.Find("*", searchorder:=xlByColumns, searchdirection:=xlPrevious).Column
ReDim elements(0 To LastRow - 2, 0 To LastCol - 2)
elements = Ws.Range(Cells(2, 1), Cells(LastRow, LastCol))
The range is 25 rows by 11 columns. However, not all cells in the range have values so some of the values in the array are 'empty'.
col A has 25 items
col B has 16
col K has 12...
I need to loop through this array and create a second array, which will be a "Cartesian product" of the values from the first one. In order to determine how many times I need to loop I need to figure out how many items there are in each of the arrays columns ("dimensions"?).
Here is an attempt of my loop:
Row = 0
For i = 1 To 25 'numElements in column 1
For j = 1 To 3 'numElements in column 6
For k = 1 To 5 'numElements in column 7
For l = 1 To 14 'numElements in column 8
For m = 1 To 6 'numElements in column 10
For n = 1 To 12 'numElements in column 11
cartesian(Row, 0) = elements(i, 0)
cartesian(Row, 1) = elements(i, 1)
cartesian(Row, 2) = elements(i, 2)
cartesian(Row, 3) = elements(i, 3)
cartesian(Row, 4) = elements(i, 4)
cartesian(Row, 5) = elements(j, 5)
cartesian(Row, 6) = elements(k, 6)
cartesian(Row, 7) = elements(l, 7)
cartesian(Row, 8) = elements(l, 8)
cartesian(Row, 9) = elements(m, 9)
cartesian(Row, 10) = elements(n, 10)
Row = Row + 1
Next n
Next m
Next l
Next k
Next j
Next i
Any help appreciated :)
EDIT 1:
This is the range that I read into array1:
Austria sem jan
Belgium gdn feb
France mar
US apr
may
jun
I need to be able to count how many "items" there are in column 1, column 2 and column 3 in order to multiply them. That way I will know how big I need to ReDim second array.
This is what I need in the array 2 and to finally write back into another sheet:
Austria sem jan
Austria sem feb
Austria sem mar
Austria sem apr
Austria sem may
Austria sem jun
Austria gdn jan
Austria gdn feb
Austria gdn mar
Austria gdn apr
Austria gdn may
Austria gdn jun
Belgium sem jan
Belgium sem feb
Belgium sem mar
Belgium sem apr
Belgium sem may
Belgium sem jun
Belgium gdn jan
Belgium gdn feb
Belgium gdn mar
Belgium gdn apr
Belgium gdn may
Belgium gdn jun
etc.
This should do it like you need it in a decent amount of time... still will take some time for ~300k entries:
Option Explicit
Sub getMyList()
'set input
Dim inputVal As Variant
'get input values
With ThisWorkbook.Worksheets("Sheet1")
inputVal = .Range(.Cells(1, 1), .Cells(.Cells.Find("*", , , , 1, 2).Row, .Cells(1, 1).End(xlToRight).Column)).Value
End With
'set count array
Dim xCounts() As Variant
ReDim xCounts(1 To UBound(inputVal, 2))
Dim i As Long, j As Long
For i = 1 To UBound(xCounts)
j = 1
While inputVal(j, i) <> "" And j < UBound(inputVal)
j = j + 1
Wend
'xCounts(i) = j - 1 'will skip last value if it is at the last row
xCounts(i) = j + (inputVal(j, i) = "") 'new one will work as wanted
Next
'set output sizes
Dim outVal() As Variant
ReDim outVal(1 To Application.Product(xCounts), 1 To UBound(xCounts))
'runner sets
Dim colRunner As Long, rowRunner As Long, copyRunner As Long
Dim itemRep As Long, listRep As Long
For colRunner = 1 To UBound(xCounts)
rowRunner = 1
itemRep = 1
listRep = 1
'repeat whole list
For i = 1 To colRunner - 1
listRep = listRep * xCounts(i)
Next
'repeat each item
For i = colRunner + 1 To UBound(xCounts)
itemRep = itemRep * xCounts(i)
Next
'run the list for output
copyRunner = 1
For i = 1 To listRep
For copyRunner = 1 To xCounts(colRunner)
For j = 1 To itemRep
outVal(rowRunner, colRunner) = inputVal(copyRunner, colRunner)
rowRunner = rowRunner + 1
Next
Next
Next
Next
'output everything
ThisWorkbook.Worksheets("Sheet2").Cells(1, 1).Resize(UBound(outVal), UBound(outVal, 2)).Value = outVal
End Sub
The code should be easy to read (there is no real magic inside) :P
However, if any questions are left, just ask :)
EDIT
The xCounter simply hold the counts of all items for each column because this numbers are used lots of times.
For clarification: Let's assume you have a list like this:
A B C D E
1 1 1 1 1
2 2 2 2 2
3 3 3 3
4 4 4
5 5 5
6 6 6
7 7
8
(Used numbers for easy counting, also works with any strings)
xCounter will now be {8,2,6,7,3}. Now if you want to write down the column C then you need to know how many times each item needs to be repeated. This can be calculated by multiplying the counts of all columns which come later. For this case it would be 7 * 3 = 21 times. Also, you need to know how many items are in the list to loop through which will be 6. Then the whole list also needs to repeat itself which can be calculated by multiplying all counts of rows which are in front of it. That would be 8 * 2 = 16 times. This way also the 3 inner For ... Next loops are build up. ListRepeat(EachItem(ItemRepeat)).
To know which line in the output array is to be written you need a simple up counting value which is the RowCounter. Doing this directly into the sheet you would use a range which simply offsets one row down every time a value is written in a cell.
By this system you do every column completely seperated from the others because all you need are the products of the item counts of the leading and following columns (for which we have xCounter). Still we need to do this for each column so the outer loop is the column (colRunner).
Simply for not getting confused by having 4 loops using i, j, k, l inside each other I renamed the "runner" for the rows in the outVal to rowRunner and the one for the columns to colRunner. Having the upper and lower limits for the repeats directly set in front of the inner loops, I stayed with i and j. (Also they are not used for anything in that loops, they simply ensure the repeats by doing the same action mutiple times)
If I missed something or other questions pop up, just do it as it is always the right thing to do: ask. ;)
Below I have a list of “ID” numbers with their associated “Number “and their “values”. I am trying to create sub function that crates a dynamic array that collects all the “Values” that have a “Number” that is equal to and lesser than 30. After the array is filled it is summed and placed under the heading titled “30 or less”. I have been trying do this using VBA with no luck. I have read a bunch of posts and documents telling me how to do this but I can’t make sense of it. Could someone show me how to get this done. Its driving me crazy and I am sure its simple I eventually want to expand this to do the same with “Numbers ” that are greater than 30 but less than 60 and so on. Thank you
ID Number Value
0 60 100
1 31 101
2 12 102
3 30 103
4 21 104
5 60 105
30 or less
Try pasting this into a new module in VB.
This presumes that your Raw data is in Sheet(1) and sorted data will be in a new blank worksheet Sheet(2)
Sub AddNumbers()
Dim RowNo, ColNo As Long
'Skip Header Row
RowNo = 2
Do Until Sheets(1).Cells(RowNo, 1) = ""
If Sheets(1).Cells(RowNo, 2) <= 30 Then
Sheets(2).Cells(1, 1) = "30 or less"
ColNo = 1
Sheets(2).Cells((Sheets(2).Cells(Rows.Count, 1).End(xlUp).row + 1), ColNo) = Sheets(1).Cells(RowNo, 3)
ElseIf Sheets(1).Cells(RowNo, 2) > 30 And Sheets(1).Cells(RowNo, 2) <= 60 Then
Sheets(2).Cells(1, 2) = "Between 30 and 60"
ColNo = 2
Sheets(2).Cells((Sheets(2).Cells(Rows.Count, 2).End(xlUp).row + 1), ColNo) = Sheets(1).Cells(RowNo, 3)
ElseIf Sheets(1).Cells(RowNo, 2) > 60 And Sheets(1).Cells(RowNo, 2) <= 90 Then
Sheets(2).Cells(1, 3) = "Between 60 and 90"
ColNo = 3
Sheets(2).Cells((Sheets(2).Cells(Rows.Count, 3).End(xlUp).row + 1), ColNo) = Sheets(1).Cells(RowNo, 3)
End If
RowNo = RowNo + 1
Loop
' Add Subtotals
ColNo = 1
Do Until Sheets(2).Cells(1, ColNo) = ""
Sheets(2).Cells((Sheets(2).Cells(Rows.Count, ColNo).End(xlUp).row + 1), ColNo).Formula = "=SUM(" & Col_Letter(ColNo) & "2:" & Col_Letter(ColNo) & (Sheets(2).Cells(Rows.Count, ColNo).End(xlUp).row) & ")"
Sheets(2).Cells((Sheets(2).Cells(Rows.Count, ColNo).End(xlUp).row), ColNo).Font.Bold = True
ColNo = ColNo + 1
Loop
End Sub
Function Col_Letter(lngCol As Long) As String
Dim vArr
vArr = Split(Cells(1, lngCol).Address(True, False), "$")
Col_Letter = vArr(0)
End Function
I am trying to create an array of arrays inside of the macros of Excel. Here is my problem... I am creating a year calendar and want to highlight dates inside that calendar.
I have a range of dates in a worksheet. These would be any type of dates I want to remember, etc. I read them in and then create the calendar and make these a different dates a different background color.
9/24/2015
1/20/2015
4/5/2015
9/30/2015
1/1/2015
In my limited thinking I would read them in, Group them by month (year doesn't matter) and then put the dates associated with that month.
9 -> 24, 30
1 -> 20, 1
4 -> 5
Here is what I have so far
'Set Variables
Dim ImportantDays As Variant
Dim id As Integer
Dim tempSplitDateArray() As Integer
'Grab the dates from the entered WorkSheet
ImportantDays = Worksheets("MainData").Range("E4:E19")
'Loop through the dates entered
For id = LBound(ImportantDays, 1) To UBound(ImportantDays, 1)
If ImportantDays(id, 1) <> "" Then
tempSplitDateArray() = Split(ImportantDays(id, 1), "/")
'--I now have tempSplitDateArray(0) = month
'--tempSplitDateArray(1) = day
'------------------------------------
'-- Not sure of my next step here
'------------------------------------
End If
Next id
I know I can have a 2D array, but how do I keep track of which array slot is open? I have this variable (the 12 is the months, the 16 is the total number of dates allowed).
Dim monthlyDates(12, 16) As Variant
Ideally I would store all the September months in monthlyDates(9) or something like that, but I am at a loss as to ...
How to keep track when storing them?
How to access and loop through the values when that particular month is being created?
Any thoughts?
If I understand correctly, I think this option is right for you ...
Sub test()
Dim id&, z&, oCell As Range, Key, MKey
Dim I_Month As Object: Set I_Month = CreateObject("Scripting.Dictionary")
Dim I_Day As Object: Set I_Day = CreateObject("Scripting.Dictionary")
Dim Cnt As Object: Set Cnt = CreateObject("Scripting.Dictionary")
Dim Month_count As Object: Set Month_count = CreateObject("Scripting.Dictionary")
id = 1
'Grab the dates from the entered WorkSheet
For Each oCell In Worksheets("MainData").Range("E4:E19")
I_Month.Add id, Month(oCell.Value)
I_Day.Add id, Day(oCell.Value)
id = id + 1
Next
id = 12
z = 0
While id <> 0
For Each Key In I_Month
If I_Month(Key) = id Then z = z + 1
Next
Cnt.Add id, z
id = id - 1: z = 0
Wend
For Each Key In I_Month
For Each MKey In Cnt
If MKey = I_Month(Key) Then
id = Cnt(MKey)
Exit For
End If
Next
Month_count.Add Key, id
Next
For Each Key In I_Month
Debug.Print Key, I_Month(Key), I_Day(Key), Month_count(Key)
Next
End Sub
result
Key Month Day Count of the Month iteration
1 6 22 4
2 10 24 2
3 6 15 4
4 10 28 2
5 1 14 3
6 1 9 3
7 11 15 1
8 1 24 3
9 6 2 4
10 3 21 1
11 12 26 2
12 5 25 2
13 2 23 1
14 12 7 2
15 5 31 2
16 6 5 4