以编程方式向Userform-VBA添加和删除组合框、文本框和复选框

以编程方式向Userform-VBA添加和删除组合框、文本框和复选框,vba,controls,userform,Vba,Controls,Userform,我正在创建一个userform,它有1个组合框(1)、2个文本框(2和3)和11个复选框(a-K),如图所示。所有控件的第一个实例都将出现,但当用户单击AddClass时,必须创建一组新的所有控件,并且当RemoveClass时,应该删除特定的行 我已经成功地获得了一个实例的需求,但是我不知道如何做N次,用户表单的大小也在扩展 Private Sub cmdAddClass() Dim cCheckBox As Control, r As Long, r1 As Range Set r1

我正在创建一个userform,它有1个组合框(1)、2个文本框(2和3)和11个复选框(a-K),如图所示。所有控件的第一个实例都将出现,但当用户单击AddClass时,必须创建一组新的所有控件,并且当RemoveClass时,应该删除特定的行

我已经成功地获得了一个实例的需求,但是我不知道如何做N次,用户表单的大小也在扩展

Private Sub cmdAddClass()

 Dim cCheckBox As Control, r As Long, r1 As Range

 Set r1 = Sheets("Sheet1").Range("A2:A12") 

 Set cComboBox = Me.Controls.Add("Forms.ComboBox.1")
 With cComboBox
  .Height=25.5
  .Width=102
  .Top=50
  .Left =6
 End With

 Set cTextBox = Me.Controls.Add("Forms.TextBox.1")
 With cTextBox
  .Height=25.5
  .Width=54
  .Top=50
  .Left =114
 End With

 For r = 1 To WorksheetFunction.CountA(r1)
  If r1(r) <> vbNullString Then 
   Set cCheckBox = Me.Controls.Add("Forms.CheckBox.1", "Checkbox" & r, True)
    With cCheckBox
     .Width = 21
     .Height = 11
     .Top = 50
     If r = 1 Then
       .Left = 270
     ElseIf r = 2 Then
       .Left = 348
     ElseIf r = 3 Then
       .Left = 420
     ElseIf r = 4 Then
       .Left = 492
     ElseIf r = 5 Then
       .Left = 564
     ElseIf r = 6 Then
       .Left = 636
     ElseIf r = 7 Then
       .Left = 701.95
     ElseIf r = 8 Then
       .Left = 780
     ElseIf r = 9 Then
       .Left = 876
     ElseIf r = 10 Then
       .Left = 966
     Else
       .Left = 1050
     End If
    End With
  End If
 Next r
End Sub
Private子cmdAddClass()
调暗cCheckBox作为控制,r作为长,r1作为范围
设置r1=板材(“板材1”)。范围(“A2:A12”)
Set cComboBox=Me.Controls.Add(“Forms.ComboBox.1”)
带卷标盒
.高度=25.5
.宽度=102
.Top=50
.左=6
以
设置cTextBox=Me.Controls.Add(“Forms.TextBox.1”)
使用cTextBox
.高度=25.5
.宽度=54
.Top=50
.左=114
以
对于r=1到工作表function.CountA(r1)
如果r1(r)为空字符串,则
设置cCheckBox=Me.Controls.Add(“Forms.CheckBox.1”、“CheckBox”&r,True)
用cCheckBox
.宽度=21
.高度=11
.Top=50
如果r=1,则
.左=270
如果r=2,则
.左=348
如果r=3,则
.左=420
如果r=4,则
.左=492
如果r=5,则
.左=564
如果r=6,则
.左=636
如果r=7,则
.左=701.95
如果r=8,则
.左=780
如果r=9,则
.左=876
如果r=10,则
.左=966
其他的
.左=1050
如果结束
以
如果结束
下一个r
端接头

以下是一个您可以调整的示例

Private Sub btnAddClass_Click()
    Dim ctrl As Control, newCtrl As Control, offsetTop As Integer

    offsetTop = 30

    For Each ctrl In Me.Controls

        If TypeName(ctrl) <> "CommandButton" Then
            If ctrl.Top = btnAddClass.Top - offsetTop Then
                If TypeName(ctrl) = "ComboBox" Then
                    Set newCtrl = Me.Controls.Add("Forms.ComboBox.1")
                ElseIf TypeName(ctrl) = "TextBox" Then
                    Set newCtrl = Me.Controls.Add("Forms.TextBox.1")
                ElseIf TypeName(ctrl) = "CheckBox" Then
                    Set newCtrl = Me.Controls.Add("Forms.Checkbox.1")
                End If

                With newCtrl
                    .Height = ctrl.Height
                    .Width = ctrl.Width
                    .Top = ctrl.Top + offsetTop
                    .Left = ctrl.Left
                End With

            End If
        End If
    Next ctrl

    btnAddClass.Top = btnAddClass.Top + offsetTop
    btnRemoveClass.Top = btnRemoveClass.Top + offsetTop
    Me.Height = Me.Height + offsetTop
End Sub

Private Sub btnRemoveClass_Click()
    Dim ctrl As Control, offsetTop As Integer

    offsetTop = 30

    For Each ctrl In Me.Controls

        If TypeName(ctrl) <> "CommandButton" Then
            If ctrl.Top = btnAddClass.Top - offsetTop Then
                Me.Controls.Remove (ctrl.Name)
            End If
        End If

    Next ctrl

    btnAddClass.Top = btnAddClass.Top - offsetTop
    btnRemoveClass.Top = btnRemoveClass.Top - offsetTop
End Sub
Private Sub btnAddClass_Click()
Dim ctrl作为控件,newCtrl作为控件,offsetTop作为整数
偏移量=30
对于Me.Controls中的每个ctrl键
如果键入名称(ctrl)“命令按钮”,则
如果ctrl.Top=btnAddClass.Top-offsetTop,则
如果TypeName(ctrl)=“组合框”,则
Set newCtrl=Me.Controls.Add(“Forms.ComboBox.1”)
ElseIf TypeName(ctrl)=“TextBox”然后
Set newCtrl=Me.Controls.Add(“Forms.TextBox.1”)
ElseIf TypeName(ctrl)=“复选框”然后
Set newCtrl=Me.Controls.Add(“Forms.Checkbox.1”)
如果结束
使用newCtrl
.Height=ctrl.Height
.Width=ctrl.Width
.Top=ctrl.Top+offsetTop
.Left=ctrl.Left
以
如果结束
如果结束
下一个ctrl键
btnAddClass.Top=btnAddClass.Top+offsetTop
btnRemoveClass.Top=btnRemoveClass.Top+offsetTop
Me.Height=Me.Height+offsetop
端接头
私有子btnRemoveClass_Click()
将Dim ctrl设置为控件,将OFSETTOP设置为整数
偏移量=30
对于Me.Controls中的每个ctrl键
如果键入名称(ctrl)“命令按钮”,则
如果ctrl.Top=btnAddClass.Top-offsetTop,则
Me.Controls.Remove(ctrl.Name)
如果结束
如果结束
下一个ctrl键
btnAddClass.Top=btnAddClass.Top-offsetTop
btnRemoveClass.Top=btnRemoveClass.Top-offsetTop
端接头
注意事项:

要使其发挥作用,我需要解释设置:

  • 初始控件行的
    Top
    属性设置为
    12
  • 有两个按钮名为
    btnAddClass
    btnRemoveClass
    ,其中
    Top
    设置为
    42
  • 控件和按钮之间的高度偏移量为
    30

    要添加新控件,只需在每个控件上循环,创建一个新控件,并将其
    Top
    设置为现有控件
    Top
    值+偏移量(即30)。同时,将按钮向下移动30,并将userform高度增加30


    要删除控件,请通过检查与
    btnAddClass
    相关的
    Top
    属性来获取最后一行。然后删除这些控件,将按钮向上移动30,并将userform高度降低30。

    以下是一些提示,让您开始使用。首先,每次按下按钮时计算.Top的值。其次,在添加控件时不应扩展窗体的大小。相反,您希望实现滚动。第三,在添加和删除控件时,您需要重新定位按钮。您希望添加新行多少次?@AlexP可能在10次左右-15@BrianMStafford你能告诉我如何计算。Top吗?@Cody不是硬编码的Top 50,而是有一个模块级别或静态变量来跟踪Top。每次按下按钮时,在顶部添加一个数字,以保持控件的正确间距。你应该加多少?我不知道,只要不断调整它,直到你喜欢它的形状。谢谢@alexp,这很好用。但是,当我将第一行从
    Top
    12
    移动到
    42
    时,我确实遇到了一个问题,
    78处的按钮第一个文本框不合适。你能用这个指导我吗?仅供参考,我使用了
    Me.ScroolHeight=Application.Height Me.ScroolWidth=Application.Width
    。当我进入代码时,我可以看到两个文本框的位置都正确,但是for循环继续运行。您是否将偏移量调整为36(即78-42)?是的,我确实更改了偏移量。
    私有子btnAddClass_Click
    中存在错误。我已经在上面更新了它。这能解决问题吗?这太完美了!!多谢各位