创建动态复选框变量
Creating a Dynamic CheckBox Variable
我创建了一个用户表单,其中填充了基于多个工作表上的单元格值的复选框。我根据单元格值命名了复选框(none 它们是相同的)但是单元格的数量会随着时间的推移而变化所以我想用代码填充用户表单而不是手动将每个复选框放入。我如果单击其复选框但我的代码不起作用,我希望能够调用特定的单元格值信息。我想我需要创建一个每次都会更改的动态复选框变量。我目前无法调用除最后一个复选框之外的任何复选框。
Public chkBox As MSForms.CheckBox
Public Sub UserForm_Initialize()
MemNumCombo.Clear
Dim o As Long
Dim chkL As Double
Dim chkT As Double
Dim chkH As Double
Dim chkW As Double
chkL = 125
chkT = 5
chkH = 15
chkW = 80
o = 2
Do Until Worksheets("Operations").Cells(o, 1).Value = "Division:"
Set chkBox = Me.Controls.Add("Forms.CheckBox.1", Worksheets("Operations").Cells(o, 1).Value & Worksheets("Operations").Cells(o, 3).Value & "Check")
chkBox.Caption = Worksheets("Operations").Cells(o, 1).Value & " " & Worksheets("Operations").Cells(o, 3).Value
chkBox.Left = chkL
chkBox.Top = chkT + (o - 1) * 20
chkBox.Height = chkH
chkBox.Width = chkW
o = o + 1
Loop
'...
End Sub
我知道代码运行时 chkBox 的名称是正确的,但我不能稍后通过它的名称调用 chkBox。当代码完成后运行,我只能调用最后一个chkBox。
(不能)通过名称调用 chkBox...
您在循环中将 chkBox
对象设置到内存中,从而用下一个复选框覆盖了一个复选框;在代码之后的某处通过 chkBox
或 chkBox.Value
单独引用变量将 return (设置对象本身或例如值) last复选框。
通过 Controls
集合调用复选框
通过 Set chkBox = Me.Controls.Add("Forms.CheckBox.1", Worksheets("Operations").Cells(o, 1).Value & Worksheets("Operations").Cells(o, 3).Value & "Check")
使用 Controls.Add
方法,您已经定义了名称(由 worksheet "Operations" 中的两列加上后缀 "Check" 连接而成)。
您可以通过 Controls
集合调用这些名称之一的复选框;假设您的复选框之一实际上被命名为 "XY47Check"
您通过 Me.Controls("XY47Check")
.
解决它
列出复选框名称
一种非常简单且有用的方法是将所有复选框名称分配给一个 数组,您可以按预定义的 sheet 顺序按索引寻址。
只需在用户窗体代码模块的声明头中[1]
声明一个变体数组Dim ChkNames()
,[2]
添加调用代码行
FillChkNames
到您的 Userform_Initialize
程序以及 [3]
以下帮助程序 Sub FillChkNames()
到您的用户窗体模块:
Private Sub FillChkNames()
' Purpose: populate array ChkNames at userform module level
ReDim ChkNames(Me.Controls.Count - 1)
Dim ctl As MSForms.Control, i&
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then ChkNames(i) = ctl.Name: i = i + 1
Debug.Print ctl.Name, ctl.Value, TypeName(ctl)
Next ctl
ReDim Preserve ChkNames(i - 1)
End Sub
这允许您按名称获取所有复选框
用户窗体代码模块中任意位置的一些示例调用
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' List all combo names in array
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debug.Print Join(ChkNames, "|")
' List all combo names plus values
Dim chkName As Variant
For Each chkName In ChkNames
Debug.Print chkName, Me.Controls(chkName)
Next chkName
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' List single value - e.g. the third check box in array
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dim myNum As Long: myNum = 2 ' zero-based index 2 refers to third item in array
If myNum <= UBound(ChkNames) Then
Debug.Print "Index no " & myNum & " ~> Value: " & Me.Controls(ChkNames(myNum))
Else
Debug.Print "Invalid index :-(" & myNum & ")"
End If
高级方法
或者,您可以使用 对象集合 而不是单个对象,并使用 类 研究 SO 中的其他大量示例,例如在 assign event handlers to controls on userform created dynamically
我创建了一个用户表单,其中填充了基于多个工作表上的单元格值的复选框。我根据单元格值命名了复选框(none 它们是相同的)但是单元格的数量会随着时间的推移而变化所以我想用代码填充用户表单而不是手动将每个复选框放入。我如果单击其复选框但我的代码不起作用,我希望能够调用特定的单元格值信息。我想我需要创建一个每次都会更改的动态复选框变量。我目前无法调用除最后一个复选框之外的任何复选框。
Public chkBox As MSForms.CheckBox
Public Sub UserForm_Initialize()
MemNumCombo.Clear
Dim o As Long
Dim chkL As Double
Dim chkT As Double
Dim chkH As Double
Dim chkW As Double
chkL = 125
chkT = 5
chkH = 15
chkW = 80
o = 2
Do Until Worksheets("Operations").Cells(o, 1).Value = "Division:"
Set chkBox = Me.Controls.Add("Forms.CheckBox.1", Worksheets("Operations").Cells(o, 1).Value & Worksheets("Operations").Cells(o, 3).Value & "Check")
chkBox.Caption = Worksheets("Operations").Cells(o, 1).Value & " " & Worksheets("Operations").Cells(o, 3).Value
chkBox.Left = chkL
chkBox.Top = chkT + (o - 1) * 20
chkBox.Height = chkH
chkBox.Width = chkW
o = o + 1
Loop
'...
End Sub
我知道代码运行时 chkBox 的名称是正确的,但我不能稍后通过它的名称调用 chkBox。当代码完成后运行,我只能调用最后一个chkBox。
(不能)通过名称调用 chkBox...
您在循环中将 chkBox
对象设置到内存中,从而用下一个复选框覆盖了一个复选框;在代码之后的某处通过 chkBox
或 chkBox.Value
单独引用变量将 return (设置对象本身或例如值) last复选框。
通过 Controls
集合调用复选框
通过 Set chkBox = Me.Controls.Add("Forms.CheckBox.1", Worksheets("Operations").Cells(o, 1).Value & Worksheets("Operations").Cells(o, 3).Value & "Check")
使用 Controls.Add
方法,您已经定义了名称(由 worksheet "Operations" 中的两列加上后缀 "Check" 连接而成)。
您可以通过 Controls
集合调用这些名称之一的复选框;假设您的复选框之一实际上被命名为 "XY47Check"
您通过 Me.Controls("XY47Check")
.
列出复选框名称
一种非常简单且有用的方法是将所有复选框名称分配给一个 数组,您可以按预定义的 sheet 顺序按索引寻址。
只需在用户窗体代码模块的声明头中[1]
声明一个变体数组Dim ChkNames()
,[2]
添加调用代码行
FillChkNames
到您的 Userform_Initialize
程序以及 [3]
以下帮助程序 Sub FillChkNames()
到您的用户窗体模块:
Private Sub FillChkNames()
' Purpose: populate array ChkNames at userform module level
ReDim ChkNames(Me.Controls.Count - 1)
Dim ctl As MSForms.Control, i&
For Each ctl In Me.Controls
If TypeName(ctl) = "CheckBox" Then ChkNames(i) = ctl.Name: i = i + 1
Debug.Print ctl.Name, ctl.Value, TypeName(ctl)
Next ctl
ReDim Preserve ChkNames(i - 1)
End Sub
这允许您按名称获取所有复选框
用户窗体代码模块中任意位置的一些示例调用
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' List all combo names in array
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Debug.Print Join(ChkNames, "|")
' List all combo names plus values
Dim chkName As Variant
For Each chkName In ChkNames
Debug.Print chkName, Me.Controls(chkName)
Next chkName
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
' List single value - e.g. the third check box in array
' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dim myNum As Long: myNum = 2 ' zero-based index 2 refers to third item in array
If myNum <= UBound(ChkNames) Then
Debug.Print "Index no " & myNum & " ~> Value: " & Me.Controls(ChkNames(myNum))
Else
Debug.Print "Invalid index :-(" & myNum & ")"
End If
高级方法
或者,您可以使用 对象集合 而不是单个对象,并使用 类 研究 SO 中的其他大量示例,例如在 assign event handlers to controls on userform created dynamically