Results 1 to 20 of 22

Thread: Update Calendar Fills by Revolving Sequence Using VBA

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #15
    VBAX Guru Kenneth Hobs's Avatar
    Joined
    Nov 2005
    Location
    Tecumseh, OK
    Posts
    4,954
    Location
    I made some changes to make sure that the new sheet calculates after the change. The last version had some tests for the change cycle which left the dates as 0. It is a bit slower that way but still ok. If not, I can tweak it for the other sheets to not update until after the run.

    I also added a routine, at the end, to make restoring function after an error easier. Hopefully, this is just needed for the development version.

    Sub FillMenus()    
        Dim rC As Range, rSLd As Range, aSLd
        Dim i As Integer, j As Integer, d As Double, s As String
        Dim ws As Worksheet, ws2 As Worksheet
        Dim f As Range, c As Range, v, aa(1 To 31)    
        Set ws = Worksheets("Year Planner")
        Set rC = ws.[A9:W65]
        Set ws2 = Worksheets("SHOPPING LIST")    
        With ws2
            Set rSLd = .[D6:AH6]
            aSLd = WorksheetFunction.Transpose(rSLd)        
            ' Array a with Dates for Shopping List day numbers.
            For i = 1 To 31
                s = .[C2]     'needed due to merge cell issue
                d = Month(DateValue("01-" & s & "-1900"))
                ' d = DateSerial(.[E2], d, aSLd(i, 1))
                ' If not a full year, find year and set d value
                For Each c In ws.Range("A7, I7,Q7,A22,I22,Q22,A37, I37, Q37, A52, I52, Q52")
                    If Month(c.Value) = d Then
                        d = DateSerial(Year(c.Value), d, aSLd(i, 1))
                        Exit For
                    End If
                Next c
                aSLd(i, 1) = d
           Next i
           ' Find the month/year in ws, use cell interation due to merged cells.
           For Each c In ws.Range("A7, I7,Q7,A22,I22,Q22,A37, I37, Q37, A52, I52, Q52")
                If c = aSLd(1, 1) Then
                    Set f = c
                    Exit For
                End If
            Next c        
            On Error Resume Next
            Set f = f.Offset(3).Resize(11, 7) 'Month block on ws
            For i = 1 To f.Rows.Count Step 2 'menu rows
                Set c = f.Rows(i)
                For j = 1 To 7
                    v = Day(c.Cells(j).Offset(-1)) 'day number on ws
                    If v >= 1 And v <= 31 Then
                        d = CInt(c.Cells(j))
                        If d <> 0 Then aa(v) = d
                    End If
                Next j
            Next i        
            rSLd.Offset(2) = aa
            'MsgBox Join(aa, vbCrLf)
        End With
    End Sub
    
    
    Sub Del12Months()
        Dim i As Integer, j As Integer, r As Range, c As Range    
        Application.EnableEvents = False
        Application.ScreenUpdating = False
        ' Application.Calculation = xlCalculationManual
        With Worksheets("Year Planner")
        ' With ActiveSheet
              For i = 7 To 52 Step 15
                  ' 1st row of 3 months menus
                  Set r = Range(.Cells(i, "A"), .Cells(i, "W")).Offset(3)
                  For j = 0 To 10 Step 2
                      Set c = r.Offset(j)
                      c.ClearContents
                  Next j
              Next i
          End With    
          Application.EnableEvents = True
          Application.ScreenUpdating = True
          Application.Calculation = xlCalculationAutomatic
    End Sub
    
    
    Sub Fill12Months()
        Dim i As Integer, j As Integer, r As Range, c As Range
        Dim fm As Integer, k As Integer, a, cc As Range    
        Application.EnableEvents = False
        Application.ScreenUpdating = False
        Application.Calculation = xlCalculationManual
        With Worksheets("Year Planner")
        ' With ActiveSheet
              For Each c In .Range("A7,I7,Q7,A22,I22,Q22,A37,I37,Q37,A52,I52,Q52")
                  Set r = MonthMenuRange(c) 'month range of menu cells
                  ' Ordered array of menu numbers
                  a = oA28(c.Value, r.Count)
                  Debug.Print
                  ' Fill calendar with ordered menu numbers
                  i = 0
                  For Each cc In r
                      i = i + 1
                      cc = a(i, 1)
                  Next cc
              Next c
        End With    
        Application.EnableEvents = True
        Application.ScreenUpdating = True
        Application.Calculation = xlCalculationAutomatic
    End Sub
    
    
    Function MonthMenuRange(rD As Range) As Range
        Dim c As Range, r As Range, d As Date, v    
        For Each c In AMonthMenuRange(rD).Cells
            If Not IsDate(c.Offset(-1)) Then GoTo NextC
            If r Is Nothing Then
                Set r = c
                Else
                Set r = Union(r, c)
            End If
            NextC:
        Next c    
        Set MonthMenuRange = r
    End Function
    
    
    Function AMonthMenuRange(rD As Range) As Range
        Dim i As Integer, r As Range, c As Range    
        Set r = rD.Offset(3).Resize(, 7)
        For i = 0 To 10 Step 2
            Set c = rD.Offset(3 + i).Resize(, 7)
            Set r = Union(r, c)
        Next i
        Set AMonthMenuRange = r
    End Function
    
    
    Function oA28(d As Date, aSize As Integer)
        Dim a, ws3 As Worksheet, r As Range, f As Range
        Set ws3 = Worksheets("Start Menu")
        Set r = ws3.Range("B2", ws3.Cells(Rows.Count, "B").End(xlUp))
        Set f = r.Find(d, ws3.Cells(Rows.Count, "B").End(xlUp), xlValues, , xlNext)
        Set r = f.Resize(aSize).Offset(, -1)
        oA28 = r
    End Function
    
    
    
    
    '--------------------------- Tests and Routines Not Used -----------------
    'https://stackoverflow.com/questions/45564927/first-monday-of-current-month-in-vba
    Function FirstMonday(myDate As Date) As Date
        Dim d As Date, w As Long
        d = DateSerial(Year(myDate), Month(myDate), 1)
        w = Weekday(d, vbMonday)
        FirstMonday = d + IIf(w <> 1, 8 - w, 0)
    End Function
    
    
    Function NoDaysInMonth(d As Date) As Integer
        NoDaysInMonth = Day(DateAdd("m", 1, d - Day(d) + 1) - 1)
    End Function
    
    
    Sub Test_oA281()
        Dim a
        a = oA281(7, 31)
        Debug.Print Join(a, vbCrLf)
    End Sub
    
    
    'Order of 28 day menu items with i as first Monday of the month day number.
    'aSize is number of days in the month to fill the array.
    Function oA281(i As Integer, aSize As Integer)
        Dim a, k As Integer, j As Integer
        ReDim a(1 To aSize)
        k = 30 - i
        For j = 1 To aSize
            If k > 28 Then k = 1
            a(j) = k
            k = k + 1
        Next j
        oA281 = a
    End Function
    
    
    Sub Test_oA28()
        Dim a
        'a = oA28(DateSerial(2019, 1, 1), 31)
        a = oA28(DateSerial(2019, 2, 1), 28)
        'MsgBox Join(WorksheetFunction.Transpose(a), vbCrLf)
    End Sub
    
    
    
    
    Sub RestoreAfterError()
        Application.EnableEvents = True
        Application.ScreenUpdating = True
        Application.Calculation = xlCalculationAutomatic
    End Sub
    Attached Files Attached Files
    Last edited by Aussiebear; 02-05-2025 at 12:15 PM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •