【问题标题】:Adding OnChange event to dynamically created vba form controls将 OnChange 事件添加到动态创建的 vba 表单控件
【发布时间】:2017-11-21 12:48:13
【问题描述】:

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

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 事件?提前致谢。

【问题讨论】:

  • 你需要有一个Class模块,有ListBox EventsComboBox Events
  • 看看这个问题:stackoverflow.com/questions/44409871/… - 我确实在这里解决了。正如@ShaiRado 已经说过的那样,您需要一个额外的课程。你追求的是我放在那里的 cComboBox 类。

标签: vba excel dynamic combobox listbox


【解决方案1】:

这是 ComboBox 的示例。你可以基于它的列表框,因为原理是完全一样的。

首先创建一个名为 cComboBox 的类并将这段代码放入其中:

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_ComboBoxEvents_Change 将触发。

【讨论】:

  • ?您的类属性需要Set 而不是Let,Sub 的最后一行需要Set
  • 在 VBA 中,您使用 Let 关键字编写 set 属性。由于 Let 部分已经完成了设置,因此在设置此属性时无需使用 Set。来吧,测试一下。
  • 嗯,我从来没有那样做,但正如你所说,它工作得很好。谢谢指点。
  • 你可以给类一个 ComboBox 类型的公共变量框。然后你确实会使用'set class.box = comb'。然而,像这样保持私有是更好的做法,并提供更清晰的界面。如果需要,它还允许您在 setter 中引发事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多