以编程方式向用户窗体添加和删除组合框、文本框和复选框 - VBA
Programmatically add and delete Combobox, Textbox and Checkbox to Userform - VBA
我正在创建一个用户窗体,它有 1 个组合框 (1)、2 个文本框(2 和 3)和 11 个复选框 (A-K),如图所示。所有控件的第一个实例将出现,但当用户单击添加 Class 时,必须创建一组新的所有控件,而当删除 Class 时应删除特定行。
我已经设法满足了一个实例的要求,但是我不知道如何做 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 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
备注:
为了让它工作,我需要解释设置:
- 您的初始控件行的
Top
属性 设置为 12
- 有两个按钮名为
btnAddClass
和 btnRemoveClass
,Top
设置为 42
控件和按钮之间的 offset
高度为 30
。
要添加新控件,您只需遍历每个控件,创建一个新控件,并将其 Top
设置为现有控件 Top
值 + 偏移量(即 30)。同时将按钮向下移动 30,并将用户窗体高度增加 30。
要删除控件,您可以通过检查 Top
属性 相对于 btnAddClass
获得最后一行。然后删除这些控件并将按钮向上移动 30,并将用户窗体高度降低 30。
我已经设法满足了一个实例的要求,但是我不知道如何做 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 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
备注:
为了让它工作,我需要解释设置:
- 您的初始控件行的
Top
属性 设置为12
- 有两个按钮名为
btnAddClass
和btnRemoveClass
,Top
设置为42
控件和按钮之间的 offset
高度为 30
。
要添加新控件,您只需遍历每个控件,创建一个新控件,并将其 Top
设置为现有控件 Top
值 + 偏移量(即 30)。同时将按钮向下移动 30,并将用户窗体高度增加 30。
要删除控件,您可以通过检查 Top
属性 相对于 btnAddClass
获得最后一行。然后删除这些控件并将按钮向上移动 30,并将用户窗体高度降低 30。