Vba 动态创建的用户表单,带有2个相关组合框
我正在尝试创建一个动态用户表单,其中所有Vba 动态创建的用户表单,带有2个相关组合框,vba,excel,class,userform,Vba,Excel,Class,Userform,我正在尝试创建一个动态用户表单,其中所有控件都是在运行时创建的 我有两个组合框数组,第一个组合框数组是“Catgeory”(CatCBArr),第二个组合框数组是“Item”(ItemCBArr) 我想,一旦我从“Category”的第一个组合框中选择了一个值,比如说CatCBArr(0),那么只有ItemCBArr(0)中的相关项才会显示出来 问题:我不知道如何根据在第一个组合框(CatCBArr(0))中选择的值修改第二个组合框(ItemCBArr(0)) 用户表单代码(相关章节) GUI用
控件都是在运行时创建的
我有两个组合框数组,第一个组合框数组是“Catgeory”(CatCBArr
),第二个组合框数组是“Item”(ItemCBArr
)
我想,一旦我从“Category”的第一个组合框中选择了一个值,比如说CatCBArr(0)
,那么只有ItemCBArr(0)
中的相关项才会显示出来
问题:我不知道如何根据在第一个组合框(CatCBArr(0)
)中选择的值修改第二个组合框(ItemCBArr(0)
)
用户表单代码(相关章节)
GUI用户表单屏幕截图
好的,这是基本知识。
您的类cmboboxI复制如下:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
接下来,我创建了一个UserForm1,它添加了两个组合框,其中一个是添加到cComboBox类型的局部变量中的
Public DependentBox As MsForms.ComboBox
Private InitialBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MsForms.ComboBox
Set InitialBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
InitialBox.box = cBox
Set DependentBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With DependentBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
End Sub
尽管这是可行的,但上面的方法不是很干净,因为您的类不是自包含的——它必须知道用户表单。更好的方法是链接类中的框,然后在初始化控件数组时从Userform传递它们。
那就是:
cmbobox类别:
Private WithEvents p_ComboBoxEvents As MSForms.ComboBox
Private p_DependBox As MSForms.ComboBox
Private Sub p_ComboBoxEvents_Change()
Select Case p_ComboBoxEvents.value
Case "1":
p_DependBox.Clear
p_DependBox.AddItem "3"
p_DependBox.AddItem "4"
Case "2":
p_DependBox.Clear
p_DependBox.AddItem "5"
p_DependBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let TriggerBox(value As MSForms.ComboBox)
Set p_ComboBoxEvents = value
End Property
Public Property Get TriggerBox() As MSForms.ComboBox
Set TriggerBox = p_ComboBoxEvents
End Property
Public Property Let DependBox(value As MSForms.ComboBox)
Set p_DependBox = value
End Property
Public Property Get DependBox() As MSForms.ComboBox
Set DependBox = p_DependBox
End Property
在这里,您可以看到已经在一个自包含类中链接了这些框。
在事件处理程序中,您可以为值等创建查找。
然后在UserForm1代码中按如下方式初始化它们:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
编辑:
基于它需要是一个数组的事实,您可以对userform进行如下修改:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
在数组中,您可以通过linkedmbobox(i).DependBox
和linkedmbobox(i).TriggerBox
访问每个框。您不再需要这两个独立的数组,因为所有内容都已包含在这个链接的mbobox
数组中。
您的类cmboboxI复制如下:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
接下来,我创建了一个UserForm1,它添加了两个组合框,其中一个是添加到cComboBox类型的局部变量中的
Public DependentBox As MsForms.ComboBox
Private InitialBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MsForms.ComboBox
Set InitialBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
InitialBox.box = cBox
Set DependentBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With DependentBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
End Sub
尽管这是可行的,但上面的方法不是很干净,因为您的类不是自包含的——它必须知道用户表单。更好的方法是链接类中的框,然后在初始化控件数组时从Userform传递它们。
那就是:
cmbobox类别:
Private WithEvents p_ComboBoxEvents As MSForms.ComboBox
Private p_DependBox As MSForms.ComboBox
Private Sub p_ComboBoxEvents_Change()
Select Case p_ComboBoxEvents.value
Case "1":
p_DependBox.Clear
p_DependBox.AddItem "3"
p_DependBox.AddItem "4"
Case "2":
p_DependBox.Clear
p_DependBox.AddItem "5"
p_DependBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let TriggerBox(value As MSForms.ComboBox)
Set p_ComboBoxEvents = value
End Property
Public Property Get TriggerBox() As MSForms.ComboBox
Set TriggerBox = p_ComboBoxEvents
End Property
Public Property Let DependBox(value As MSForms.ComboBox)
Set p_DependBox = value
End Property
Public Property Get DependBox() As MSForms.ComboBox
Set DependBox = p_DependBox
End Property
在这里,您可以看到已经在一个自包含类中链接了这些框。
在事件处理程序中,您可以为值等创建查找。
然后在UserForm1代码中按如下方式初始化它们:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
编辑:
基于它需要是一个数组的事实,您可以对userform进行如下修改:
Private WithEvents ComboBoxEvents As MsForms.ComboBox
Private Sub ComboBoxEvents_Change()
Select Case ComboBoxEvents.value
Case "1":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "3"
UserForm1.DependentBox.AddItem "4"
Case "2":
UserForm1.DependentBox.Clear
UserForm1.DependentBox.AddItem "5"
UserForm1.DependentBox.AddItem "6"
Case Default:
'Do Nothing
End Select
End Sub
Public Property Let box(value As MsForms.ComboBox)
Set ComboBoxEvents = value
End Property
Public Property Get box() As MsForms.ComboBox
Set box = ComboBoxEvents
End Property
Option Explicit
Private LinkedComboBox As cComboBox
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Set LinkedComboBox = New cComboBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox.TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox.DependBox = cBox
End Sub
Option Explicit
Private LinkedComboBox(0 To 4) As cComboBOx
Private Sub UserForm_Initialize()
Dim cBox As MSForms.ComboBox
Dim i As Integer
For i = 0 To 4
Set LinkedComboBox(i) = New cComboBOx
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "initial", True)
With cBox
.Left = 6
.Width = 100
.Height = 25
.Top = 6 + (i * 25)
.AddItem "1"
.AddItem "2"
End With
LinkedComboBox(i).TriggerBox = cBox
Set cBox = Me.Controls.Add("Forms.ComboBox.1", "dependent", True)
With cBox
.Top = 6 + (i * 25)
.Left = 126
.Height = 25
.Width = 100
End With
LinkedComboBox(i).DependBox = cBox
Next i
End Sub
在数组中,您可以通过linkedmbobox(i).DependBox
和linkedmbobox(i).TriggerBox
访问每个框。您不再需要这两个单独的数组,因为所有内容都已包含在此链接的mbobox
数组中。Value
返回值。您可以对该值进行选择,然后使用第二个组合框.addItem
方法添加所需的项。要清除正手拍第二张照片中的项目,请使用.clear
Ah我看到您还使用Dim
在用户表单中声明组合框。使用Public
代替第二个数组(Dim的行为与private相同),在这种情况下,您可以通过User\u表单从类访问组合框。ItemCBArr(0)
ComboBoxEvents.Value
返回值。您可以对该值进行选择,然后使用第二个组合框.addItem
方法添加所需的项。要清除正手拍第二张照片中的项目,请使用.clear
Ah我看到您还使用Dim
在用户表单中声明组合框。使用Public
代替第二个数组(Dim的行为与private相同),在这种情况下,您可以通过User\u表单从类访问组合框。ItemCBArr(0)
非常感谢您的回答,它工作得很好。如何使它适用于每种类型的组合框数组?我有5个TriggerBox
和5个DependBox
(最后将是动态的)添加此自定义类的数组,并将两个框中每个框的索引0传递给自定义类数组中的索引0,等等。我尝试过,但无法使其工作,您可以将该部分添加到第二个代码方法中吗?请参阅更新。当然,您仍然需要找出一些方法来设置每个依赖框的值。您可以为该类提供一个Lookup range属性或其他属性,然后使用该属性根据TriggerBox的值填充DependBox。然而,这是另一个问题。这是另一个问题,我稍后会给它一个托盘。同时,非常感谢你的帮助:)非常感谢你的回答,它工作得很好。如何使它适用于每种类型的组合框数组?我有5个TriggerBox
和5个DependBox
(最后将是动态的)添加此自定义类的数组,并将两个框中每个框的索引0传递给自定义类数组中的索引0,等等。我尝试过,但无法使其工作,您可以将该部分添加到第二个代码方法中吗?请参阅更新。当然,您仍然需要找出一些方法来设置每个依赖框的值。您可以为该类提供一个Lookup range属性或其他属性,然后使用该属性根据TriggerBox的值填充DependBox。然而,这是另一个问题。这是另一个问题,我稍后会给它一个托盘。同时,非常感谢您的帮助:)