创建动态复选框变量

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 对象设置到内存中,从而用下一个复选框覆盖了一个复选框;在代码之后的某处通过 chkBoxchkBox.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