Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
向动态创建的vba表单控件添加OnChange事件_Vba_Excel_Dynamic_Combobox_Listbox - Fatal编程技术网

向动态创建的vba表单控件添加OnChange事件

向动态创建的vba表单控件添加OnChange事件,vba,excel,dynamic,combobox,listbox,Vba,Excel,Dynamic,Combobox,Listbox,我在excel中有一个表单,需要动态创建组合框和列表框。这样,每个列表框都链接到combobox。第一个是默认设置的,用户可以按“添加”按钮,如果他需要添加另一个组合+列表框。因此,“添加”按钮的代码如下: Private Sub AddCountry_Click() aaa = "a" Set comb = Controls.Add("Forms.Combobox.1", "CountryList" & Val(CountryLabel.Caption) + 1) With comb

我在excel中有一个表单,需要动态创建组合框和列表框。这样,每个列表框都链接到combobox。第一个是默认设置的,用户可以按“添加”按钮,如果他需要添加另一个组合+列表框。因此,“添加”按钮的代码如下:

Private Sub AddCountry_Click()
aaa = "a"
Set comb = Controls.Add("Forms.Combobox.1", "CountryList" & Val(CountryLabel.Caption) + 1)
With comb
.Top = CountryList1.Top
.Width = CountryList1.Width
.Height = CountryList1.Height
.Left = (CountryList1.Width + 3) * Val(CountryLabel.Caption) + CountryList1.Left
.AddItem ("--Choose country--")
For i = 3 To 20
.AddItem Worksheets("Countries").Range("B" & i).Value
Next i
.Text = "--Choose country--"
End With

Set listb = Controls.Add("Forms.Listbox.1", "Countries" & Val(CountryLabel.Caption) + 1)
With listb
.Top = Countries1.Top
.Width = Countries1.Width
.Height = Countries1.Height
.Left = (Countries1.Width + 3) * Val(CountryLabel.Caption) + Countries1.Left
.ColumnCount = 2
.MultiSelect = 1
End With
CountryLabel.Caption = Val(CountryLabel.Caption) + 1
End Sub
其想法是,组合框必须有名称“CountryList”和一个数字,该数字存储在不可见的标签中(每次按下按钮时,该标签加上+1),因此它将是CountryList1、CountryList2等。列表框也是如此

所以问题是,组合框是建立的,值(国家名称)是正确添加的。但是我没有得到,以后怎么用呢?我需要的是——当一个组合框被更改(用户选择不同的国家)时,下面的列表框必须填入特定的值(每个国家不同)


我想,问题可能在于定义组合/列表框的名称。那么,是否可以添加动态名称(CountryList1、CountryList2等),然后以某种方式添加OnChange事件?提前感谢。

下面是组合框的示例。您可以基于它的列表框,因为原理是完全相同的

首先创建一个名为CmboBox的类,并将以下代码放在其中:

Private WithEvents p_ComboBoxEvents As MSForms.ComboBox
Private Sub p_ComboBoxEvents_Change()
    'Here you can handle the events.
End Sub
Public Property Let Box(value As MSForms.ComboBox)
    Set p_ComboBoxEvents = value
End Property
Public Property Get Box() As MSForms.ComboBox
    Set Box= p_ComboBoxEvents
End Property
接下来,在现有代码中,您可以添加此cComboBox,只需放置您正在添加的Combobox:

'Add the custom box!
Private customBox as cComboBox
Private Sub AddCountry_Click()
    aaa = "a"
    Set comb = Controls.Add("Forms.Combobox.1", "CountryList" & Val(CountryLabel.Caption) + 1)

    With comb
        .Top = CountryList1.Top
        .Width = CountryList1.Width
        .Height = CountryList1.Height
        .Left = (CountryList1.Width + 3) * Val(CountryLabel.Caption) + CountryList1.Left
        .AddItem ("--Choose country--")
        For i = 3 To 20
            .AddItem Worksheets("Countries").Range("B" & i).Value
        Next i
        .Text = "--Choose country--"
    End With

Set customBox = New cComboBox
customBox.Box = comb

End Sub

当然,您可能希望创建这些元素的数组,这样您就可以拥有任意数量的元素,而不管它们是如何命名的。但是:您将看到,如果更改添加的ComboBox值,将触发
p\u ComboboBox Events\u change

您需要有一个类模块,其中包含
列表框事件
,以及
ComboBox事件
,看看这个问题:-我在这里解决了它。正如@ShaiRado已经说过的,你需要额外的课程。你想要的是像我放在那里的cComboBox类的东西。?需要在类属性上设置
Set
not
Let
,并在子类的最后一行中设置
Set
。在VBA中,使用Let关键字编写Set属性。由于Let零件已经完成了设置,因此在设置此属性时不需要使用set。来吧,测试一下。嗯,我从来没有这样做过,但正如你所说,它工作得很好。谢谢你的指针。你可以给这个类一个ComboBox类型的公共变量框。然后您将使用“set class.box=comb”。然而,这样保持它的私密性是更好的做法,并提供了更清晰的界面。如果需要,它还允许您在setter中引发事件。