如何使Combobox项目列表动态化?

时间:2016-11-15 14:30:59

标签: excel vba excel-vba combobox

我正在使用'生成'我的工作表上的按钮。当我点击按钮时,会出现一个弹出窗口(窗体),其中包含两个组合框。根据第一个组合框中的选择,填充第二个组合框选项列表。

对于第一个组合框,当我对项目值进行硬编码时,它可以正常工作。表单代码如下:

Private Sub UserForm_Initialize()

With ComboBox_DL
    .AddItem "DL1"
    .AddItem "DL2"
End With

End Sub

我试图通过使用以下表单代码从Excel工作表中的列中获取组合框项值来使此项目列表动态化:

Private Sub UserForm_Initialize()

With ComboBox_DL
For Each c In ActiveSheet.Range(Range("AE"), Range("AE").End(xlDown))
 .AddItem c.Value
Next
End With

End Sub

但是上面的代码会抛出错误:运行时错误' 1004':方法'范围'对象' _Global'失败

I modified the code adding sheet details: 
With ComboBox_DL
    For Each c In ThisWorkbook.Worksheets("Business_Input_Data").Range(Range("AE"), Range("AE").End(xlDown))
        .AddItem c.Value
Next

它仍然会抛出同样的错误。

有人可以帮忙吗?另外,我想知道如何在combobox1中查找与选择对应的值并在combobox2中填充列表?

4 个答案:

答案 0 :(得分:1)

没有对此进行测试,因为我没有创建用户表单以在相同条件下进行测试,但是应该进行微小的更改。

Dim n As Long
n = Sheets("Business_Input_Data").Cells(Rows.Count, "AE").End(xlUp).Row

With ComboBox_DL
    For Each c In ThisWorkbook.Worksheets("Business_Input_Data").Range("AE" & n)
        .AddItem c.Value
Next

答案 1 :(得分:1)

你错过了“AE”中的行索引 此外,在任何Range参考

中始终使用显式工作表资格
Private Sub UserForm_Initialize()
    Dim c As Range

    With ComboBox_DL
        For Each c In For Each c In ThisWorkbook.Worksheets("Business_Input_Data").Range(ThisWorkbook.Worksheets("Business_Input_Data").Range("AE1"), ThisWorkbook.Worksheets("Business_Input_Data").Range("AE1").End(xlDown))
         .AddItem c.Value
        Next
    End With
End Sub

但更优雅的解决方案是:

Private Sub UserForm_Initialize()        
    With ThisWorkbook.Worksheets("Business_Input_Data")
        ComboBox_DL.RowSource = .Range("AE1", .Range("AE1").End(xlDown)).Address
    End With        
End Sub


Private Sub UserForm_Initialize()        
    With ThisWorkbook.Worksheets("Business_Input_Data")
        ComboBox_DL.List = .Range("AE1", .Range("AE1").End(xlDown)).Value
    End With        
End Sub

其中:

  • 将您的ComboBox列表绑定到范围值,其地址为ComboBox RowSource属性

  • 后者将给定范围的值视为Combobox

答案 2 :(得分:0)

如果您的组合框条目是工作表上的列表,则根本不需要使用VBA来填充它们。相反,您可以创建一个动态命名范围,并将其用作组合框的Rowsource。

假设您的列表从Sheet3,单元格A1开始。去公式|名称管理器创建命名范围。给它一个有用的名称,如" Combo",然后将以下公式放入RefersTo:=OFFSET(Sheet3!$A$1,0,0,COUNTA(Sheet3!$A:$A),1)保存并关闭命名范围对话框。

在组合框的属性中,查找" RowSource"行。将其设置为=Combo,或您用于指定范围的任何名称。

列表的任何更改,包括延长或缩短,现在都会立即自动反映在组合框中。

编辑添加:

要使用在第一个组合框中选择的值来确定在第二个组合框中使用的列表,我们需要做两件事。

第一种是为第一个列表中的所有可能选择创建命名范围:
enter image description here

在图像中,A列是我们第一个组合框的来源;其他列包含第二个组合框的可能来源。

然后我们只需要在第一个组合框的Change事件中加入一些代码:

Private Sub ComboBox1_Change()
    Me.ComboBox2.Value = ""
    Me.ComboBox2.RowSource = "=" & Me.ComboBox1.Value
End Sub

只要更改了ComboBox1,就会触发此代码。首先它清除ComboBox2中的任何现有值,然后它将ComboBox2的行源属性设置为=符号和在第一个框中选择的任何值的组合。由于这些值也是命名范围,因此第二个框现在将使用选定的命名范围作为其列表源。

如果需要,可以添加更多级别的级联选项,每个选项具有不同的命名范围。但是,超过几个级别可能变得无法管理 - 此时我们可能想要查看另一种方法。

答案 3 :(得分:0)

这是一种使用一列范围内的电子邮件动态更新comboBox的解决方案。

    Dim c As Range

ComboBox1.Value = ""
ComboBox1.Clear
For Each c In Sheets("emails").Range("F5:F5000")
    If c Like "*@*" Then
        ComboBox1.AddItem c
    End If
Next

'ComboBox.Value'设置初始值。 'ComboBox.Clear'清除comboBox中的前几行。