Search code examples
excelvbaloopsuserform

Userform loops in seemingly reverse order


I have a userform of 7 checkboxes and some labels that describe them. For each corresponding checkbox there is an array from which there will be created a report if the checkbox is checked as true. However, it doesn't loop through correctly.

I want it to loop through as A, B, C, D, E, F, G for for each checkbox who have the TabIndex numbers of 0, 1, 2, 3, 4, 5, 6 respectively. However it loops through in the order of 0,6,5,4,3,2,1.

I have a main sub that defines and declares variables. My userform print code is as follows:

Sub Get_PDF_Click()
' Creating PDF

Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual

PDFUserForm.Hide
i = 0
j = 0
For Each ctl In Me.Controls
    If TypeName(ctl) = "CheckBox" Then
        If ctl.Value = True Then
            j = j + 1
            Name_of_File = Array(i + 1, 1) & " report" & YYMM & ".xlsx"
            Workbooks.Open Filename:=OutputPath & Name_of_File
            Set Wkb = Workbooks(Name_of_File)
                For Each ws In Wkb.Worksheets
                    PDF_Name = Array(i + 1, 1) & " " & ws.Name & " " & YYMM
                    ws.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
                    OutputPath & PDF_Name, Quality _
                    :=xlQualityStandard, IncludeDocProperties:=True, IgnorePrintAreas _
                    :=False, OpenAfterPublish:=False
                Next ws
            Wkb.Close SaveChanges:=False
        End If ' See if checked
    i = i + 1
    Debug.Print ctl.Name
    End If ' See if checkbox
Next ctl

If j > 0 Then
    ' Notification on process time
    SecondsElapsed = Round(Timer - StartTime, 0)
    MsgBox "PDF succesfully published after " & SecondsElapsed & " seconds." & Chr(10) & "Location: " & OutputPath, vbInformation
Else
    MsgBox "No file was selected.", vbInformation
End If

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

End Sub

As an aside I have a similar problem in another piece of code where I loop through charts on a worksheet which is also looping in the wrong order, so perhaps the same solution concept can be applied to that.


Solution

  • For Each isn't specified to guarantee an enumeration order. In all likelihood the controls are being enumerated in the order they were added to the Me.Controls collection.

    If you need a specific order, use a For loop:

    Dim checkboxNames As Variant
    checkboxNames = Array("chkA", "chkB", "chkC", "chkD", "chkE", ...)
    
    Dim current As Long, checkboxName As String, currentBox As MSForms.CheckBox
    For current = LBound(checkboxNames) To UBound(checkboxNames)
        checkboxName = checkboxNames(current)
        Set currentBox = Me.Controls(checkboxName)
        'work with the currentBox here
    Next
    

    Note that this also removes the need to iterate controls you're not interested in