VBA 控件集合(数组?)

VBA Collection (Array?) of Controls

在寻找一种在用户表单上模拟可填充网格的方法时,我遇到了 this on the Mr. Excel 网站:

Dim Grid(1 To 10, 1 To 5) As MSForms.TextBox

Private Sub UserForm_Initialize()

Dim x As Long
Dim y As Long

For x = 1 To 10
    For y = 1 To 5
        Set Grid(x, y) = Me.Controls.Add("Forms.Textbox.1")
        With Grid(x, y)
            .Width = 50
            .Height = 20
            .Left = y * .Width
            .Top = x * .Height
            .SpecialEffect = fmSpecialEffectFlat
            .BorderStyle = fmBorderStyleSingle
        End With
    Next y
Next x

End Sub

我认为这很棒。不要告诉我的客户,但我不知道您可以使用 Dim Groupname(1 to x, 1 to y) As MSForms.TextBox.

创建这样的文本框“数组”

我试图了解更多相关信息,但搜索“Array of Controls”并未向我指出此功能。所以我在这里问:

  1. “阵法”是这个能力的真正称呼吗? (所以我可以更好地搜索更多信息。)
  2. 这个“网格”中的所有控件都是文本框。我假设我可以像一组标签、按钮等那样做。但是有没有办法包含不同类型的控件? (例如,我希望第一列是标签,最后一列是组合框)

您可以像下面那样做:

Option Explicit

Dim Grid(1 To 10, 1 To 5) As Object  ' declare as object so it can take any control you like

Private Sub UserForm_Initialize()
    Dim iCol As Long
    For iCol = LBound(Grid, 2) To UBound(Grid, 2)  ' loop through all columns 1 to 5

        Dim iRow As Long
        For iRow = LBound(Grid, 1) To UBound(Grid, 1)  ' loop through all rows 1 to 10

            Select Case iCol                
                Case LBound(Grid, 2)  ' first column
                    Set Grid(iRow, iCol) = Me.Controls.Add("Forms.Label.1")
                    With Grid(iRow, iCol)
                        .Width = 50
                        .Height = 20
                        .Left = iCol * .Width
                        .Top = iRow * .Height
                        .Caption = iRow
                        .SpecialEffect = fmSpecialEffectFlat
                        .BorderStyle = fmBorderStyleSingle
                    End With
                    
                Case UBound(Grid, 2)  ' last column
                    Set Grid(iRow, iCol) = Me.Controls.Add("Forms.Combobox.1")
                    With Grid(iRow, iCol)
                        .Width = 50
                        .Height = 20
                        .Left = iCol * .Width
                        .Top = iRow * .Height
                        .SpecialEffect = fmSpecialEffectFlat
                        .BorderStyle = fmBorderStyleSingle
                    End With
                    
                Case Else  ' all other columns
                    Set Grid(iRow, iCol) = Me.Controls.Add("Forms.Textbox.1")
                    With Grid(iRow, iCol)
                        .Width = 50
                        .Height = 20
                        .Left = iCol * .Width
                        .Top = iRow * .Height
                        .SpecialEffect = fmSpecialEffectFlat
                        .BorderStyle = fmBorderStyleSingle
                    End With
                    
            End Select
        Next iRow
    Next iCol
End Sub

但是您需要在循环中按列进行处理。所以首先是列循环和行循环内部。使用 Select Case 您可以将列从标签切换到组合框再到文本框。

所以在你的情况下你仍然有 5 列,每 10 个控件,但第一列是标签,最后一列是组合框:

实际上,表单有一个名为“控件”的 属性,它是一个集合(不是数组)。当您通过代码动态添加控件时,它会自动进入“控件”集合。您当然可以制作一个控件数组(如您在问题中所示),但是当您使用代码动态创建控件时,不涉及数组。这是一个 post,显示以编程方式添加标签:

Adding labels with code

这是一个讨论添加 combo-boxes:

的页面

Adding combo-boxes with code

如果需要为动态添加的控件添加事件处理程序,则有局限性,而且有点绕。这是一个link谈论它

adding event handlers to dynamically generated controls

祝这个项目好运。