用户窗体以看似相反的顺序循环
Userform loops in seemingly reverse order
我有一个包含 7 个复选框和一些描述它们的标签的用户表单。对于每个相应的复选框,都有一个数组,如果复选框被选中,将从中创建一个报告。但是,它没有正确循环。
我希望它以 A, B, C, D, E, F, G
的形式循环遍历每个分别具有 TabIndex
个数字 0, 1, 2, 3, 4, 5, 6
的复选框。但是它按照 0,6,5,4,3,2,1
.
的顺序循环
我有一个定义和声明变量的主子。我的用户窗体打印代码如下:
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
顺便说一句,我在另一段代码中遇到了类似的问题,我循环遍历了工作表上的图表,它也以错误的顺序循环,所以也许可以将相同的解决方案概念应用于此。
For Each
未指定以保证枚举顺序。很可能控件被枚举 按照它们被添加到 到 Me.Controls
集合的顺序。
如果您需要特定顺序,请使用 For
循环:
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
请注意,这也消除了迭代您不感兴趣的控件的需要
这是另一种方法 ;) 这不需要您对复选框的名称进行硬编码。
逻辑:创建一个二维数组。在数组中存储 Tabindex
和 CheckBox
名称。在 Tabindex
上排序并根据需要使用它:)
代码:
Option Explicit
Private Sub Sample()
Dim CbArray() As String
Dim n As Long: n = 1
Dim cbCount As Long
Dim tindex As String, ctlname As String
Dim ctl As Control
Dim i As Long, j As Long
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then
n = n + 1
End If
Next
n = n - 1: cbCount = n
ReDim CbArray(1 To n, 1 To 2)
n = 1
'~~> Sort the Tabindex and checkbox name in the array
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then
CbArray(n, 1) = ctl.TabIndex
CbArray(n, 2) = ctl.Name
n = n + 1
End If
Next
'~~> Sort the array
For i = 1 To cbCount
For j = i + 1 To cbCount
If CbArray(i, 1) < CbArray(j, 1) Then
tindex = CbArray(j, 1)
ctlname = CbArray(j, 2)
CbArray(j, 1) = CbArray(i, 1)
CbArray(j, 2) = CbArray(i, 2)
CbArray(i, 1) = tindex
CbArray(i, 2) = ctlname
End If
Next j
Next i
'~~> Loop through the checkboxes
For i = cbCount To 1 Step -1
With Controls(CbArray(i, 2))
Debug.Print .Name
'
'~~> Do what you want
'
End With
Next i
End Sub
我有一个包含 7 个复选框和一些描述它们的标签的用户表单。对于每个相应的复选框,都有一个数组,如果复选框被选中,将从中创建一个报告。但是,它没有正确循环。
我希望它以 A, B, C, D, E, F, G
的形式循环遍历每个分别具有 TabIndex
个数字 0, 1, 2, 3, 4, 5, 6
的复选框。但是它按照 0,6,5,4,3,2,1
.
我有一个定义和声明变量的主子。我的用户窗体打印代码如下:
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
顺便说一句,我在另一段代码中遇到了类似的问题,我循环遍历了工作表上的图表,它也以错误的顺序循环,所以也许可以将相同的解决方案概念应用于此。
For Each
未指定以保证枚举顺序。很可能控件被枚举 按照它们被添加到 到 Me.Controls
集合的顺序。
如果您需要特定顺序,请使用 For
循环:
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
请注意,这也消除了迭代您不感兴趣的控件的需要
这是另一种方法 ;) 这不需要您对复选框的名称进行硬编码。
逻辑:创建一个二维数组。在数组中存储 Tabindex
和 CheckBox
名称。在 Tabindex
上排序并根据需要使用它:)
代码:
Option Explicit
Private Sub Sample()
Dim CbArray() As String
Dim n As Long: n = 1
Dim cbCount As Long
Dim tindex As String, ctlname As String
Dim ctl As Control
Dim i As Long, j As Long
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then
n = n + 1
End If
Next
n = n - 1: cbCount = n
ReDim CbArray(1 To n, 1 To 2)
n = 1
'~~> Sort the Tabindex and checkbox name in the array
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then
CbArray(n, 1) = ctl.TabIndex
CbArray(n, 2) = ctl.Name
n = n + 1
End If
Next
'~~> Sort the array
For i = 1 To cbCount
For j = i + 1 To cbCount
If CbArray(i, 1) < CbArray(j, 1) Then
tindex = CbArray(j, 1)
ctlname = CbArray(j, 2)
CbArray(j, 1) = CbArray(i, 1)
CbArray(j, 2) = CbArray(i, 2)
CbArray(i, 1) = tindex
CbArray(i, 2) = ctlname
End If
Next j
Next i
'~~> Loop through the checkboxes
For i = cbCount To 1 Step -1
With Controls(CbArray(i, 2))
Debug.Print .Name
'
'~~> Do what you want
'
End With
Next i
End Sub