ComboBox(number)_从VB中生成的ComboBox更改

时间:2018-07-02 19:44:01

标签: vba excel-vba combobox listbox excel

下面的代码是我遇到的一些问题。对于在VB中使用用户窗体,我非常满意。

我的目标是从“供应商出价”工作表的“供应商”栏中创建3个ComboBoxes绘图数据,并创建3个ListBoxes以选择供应商的产品。

For j = 1 To 3

    Set myCombo = Frame1.Controls.Add("Forms.ComboBox.1", "ComboBox" & j)
    Set myList = Frame1.Controls.Add("Forms.ListBox.1", "ListBox" & j)

    With myList
        .Top = 18 + (150 - 84) * (j - 1)
        .Height = 34.85
        .Left = 198
        .Width = 180
        MsgBox .Name
    End With

    With myCombo
        .Top = 18 + (150 - 84) * (j - 1)
        .Height = 22.8
        .Left = 42
        .Width = 132
    End With

    Set rData = ThisWorkbook.Worksheets("VendorBids").Range("A:A").CurrentRegion
    Me.Controls("ComboBox" & j).List = rData.Offset(1).Value
    Me.Controls("ListBox" & j).ColumnCount = 1
    Me.Controls("ListBox" & j).List = rData.Offset(1, 1).Value



Next

这部分工作正常。我对此进行了编码但未在用户窗体中进行编码的原因是,当用户按下命令按钮时,我具有添加另一行组合框和列表框的功能。效果也很好。

我遇到的问题是ComboBox_Change()。如果我在UserForm GUI编辑器中创建了组合框,则ComboBox1_Change()将起作用。下面是我尝试实现的示例,但包含所有生成的组合框,例如ComboBox2、3,等等。

Private Sub ComboBox1_Change()

Me.ListBox1.ListIndex = Me.ComboBox1.ListIndex

End Sub

如果我的逻辑或解释不太清楚,我深表歉意,这是我作为新手正在努力改进的方面。

1 个答案:

答案 0 :(得分:1)

参考:Chip Pearson - Events And Event Procedures In VBA

您需要结合使用WithEventsRaiseEvents来处理新控件的事件。

enter image description here

enter image description here

ComboBoxHandler:Class

存储对单个组合框的引用。使用WithEvents可以在ControlHandlerCollection时通知ComboBox_Change()

Option Explicit
Public ControlHandlerCollection As VBAProject.ControlHandlerCollection
Public WithEvents ComboBox As MSForms.ComboBox

Private Sub ComboBox_Change()
    ControlHandlerCollection.ComboBoxChanged ComboBox
End Sub

ListBoxHandler:Class

存储对单个ListBox的引用。使用WithEvents可以在ControlHandlerCollection时通知ListBox_Change()

Option Explicit
Public ControlHandlerCollection As VBAProject.ControlHandlerCollection
Public WithEvents ListBox As MSForms.ListBox

Private Sub ListBox_Change()
    ControlHandlerCollection.ListBoxChanged ListBox
End Sub

ControlHandlerCollection:Class

每当处理程序类之一将更改通知给它时,它同时持有ComboBoxHandlersListBoxHandlers的集合,它引发一个事件以将更改通知用户表单。

Private EventHandlers As New Collection

Public Event ComboBoxChange(ComboBox As MSForms.ComboBox)
Public Event ListBoxChange(ListBox As MSForms.ListBox)

Public Sub AddComboBox(ComboBox As MSForms.ComboBox)
    Dim ComboBoxHandler As New ComboBoxHandler
    Set ComboBoxHandler.ControlHandlerCollection = Me
    Set ComboBoxHandler.ComboBox = ComboBox
    EventHandlers.Add ComboBoxHandler
End Sub

Public Sub AddListBox(ListBox As MSForms.ListBox)
    Dim ListBoxHandler As New ListBoxHandler
    Set ListBoxHandler.ControlHandlerCollection = Me
    Set ListBoxHandler.ListBox = ListBox
    EventHandlers.Add ListBoxHandler
End Sub

Public Sub ComboBoxChanged(ComboBox As MSForms.ComboBox)
    RaiseEvent ComboBoxChange(ComboBox)
End Sub

Public Sub ListBoxChanged(ListBox As MSForms.ListBox)
     RaiseEvent ListBoxChange(ListBox)
End Sub

UserForm1:UserForm

Option Explicit
Private WithEvents ControlHandlerCollection As ControlHandlerCollection

Private Sub ControlHandlerCollection_ComboBoxChange(ComboBox As MSForms.ComboBox)
    MsgBox "Value: " & ComboBox.Value & vbNewLine & _
           "Name: " & ComboBox.Name & vbNewLine & _
           "Tag: " & ComboBox.Tag
End Sub

Private Sub ControlHandlerCollection_ListBoxChange(ListBox As MSForms.ListBox)
    MsgBox "Value: " & ListBox.Value & vbNewLine & _
           "Name: " & ListBox.Name & vbNewLine & _
           "Tag: " & ListBox.Tag
End Sub

Private Sub UserForm_Initialize()
    Set ControlHandlerCollection = New ControlHandlerCollection
End Sub

Private Sub btnAddRow_Click()
    Dim j As Long
    Dim rData As Range
    Dim myCombo As MSForms.ComboBox, myList As MSForms.ListBox
    Set rData = ThisWorkbook.Worksheets("VendorBids").Range("A:A").CurrentRegion

    For j = 1 To 3

        Set myCombo = Frame1.Controls.Add("Forms.ComboBox.1", "ComboBox" & j)
        Set myList = Frame1.Controls.Add("Forms.ListBox.1", "ListBox" & j)

        With myList
            .Top = 18 + (150 - 84) * (j - 1)
            .Height = 34.85
            .Left = 198
            .Width = 180
            .ColumnCount = 1
            .List = rData.Offset(1, 1).Value
            .Tag = rData.Offset(1, 1).Address
        End With

        With myCombo
            .Top = 18 + (150 - 84) * (j - 1)
            .Height = 22.8
            .Left = 42
            .Width = 132
            .List = rData.Offset(1).Value
            .Tag = rData.Offset(1).Address
        End With

        ControlHandlerCollection.AddComboBox myCombo
        ControlHandlerCollection.AddListBox myList
    Next
End Sub