简体   繁体   English

VBA Excel使用多列填充ListBox

[英]VBA Excel Populate ListBox with multiple columns

This may be a cheap question for some but I'm totally confused on how to populate my listbox. 对于一些人来说,这可能是一个便宜的问题,但我对如何填充我的列表框感到困惑。

表单与列表框

Using this line I can populate the listbox as shown below: 使用此行我可以填充列表框,如下所示:
ListBox1.List = Sheets("Sheet1").Cells(1, 1).CurrentRegion.Value
or 要么

Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
    For i = 1 To ws.Cells(ws.Rows.Count, 1).End(xlUp).Row Step 1
        If ws.Cells(i, 1).Value <> vbNullString Then Me.ListBox1.AddItem 
        ws.Cells(i, 1).Value
Next i

表单与列表框1列输出

Below is the data I'm planning to use to populate the list box and is progressive. 下面是我计划用来填充列表框的数据,并且是渐进式的。 Only the column has the fix count. 只有列具有修复计数。
数据

Someone please enlighten me on how to populate a list box adapative to multiple columns and rows using FOR LOOP as shown in my code above. 有人请告诉我如何使用FOR LOOP填充适应多个列和行的列表框,如上面的代码所示。 Any help appreciated. 任何帮助赞赏。 Thanks. 谢谢。

Methods 方法

  1. It's always better to loop through an array than a range - it's much faster . 循环一个数组总是比一个范围更好 - 它要快得多
  2. It's even faster to create a variant data field array with a one liner instead of redimensioning a predeclared array and fill it in an extra loop as proposed by Siddharth Rout (though a good method :-) Note: The code below is based on his Approach referenced in the above comment just to demonstrate the difference. 创建一个带有一个衬管的变量数据字段数组,而不是重新定义预先声明的数组并将其填充到Siddharth Rout提出的额外循环中更快(尽管一个好的方法:-) 注意:下面的代码基于他的方法在上面的评论中引用只是为了证明差异。
  3. Fill ListBox1.List with the array (same method, but reverse direction). 使用数组填充ListBox1.List (方法相同,但反向)。

Code

Private Sub CommandButton1_Click()
' Purpose:  fill listbox with range values after clicking on CommandButton1
'           (code could be applied to UserForm_Initialize(), too)
' Note:     based on @Siddharth-Rout 's proposal at https://stackoverflow.com/questions/10763310/how-to-populate-data-from-a-range-multiple-rows-and-columns-to-listbox-with-vb
'           but creating a variant data field array directly from range in a one liner
'           (instead of filling a redimensioned array with range values in a loop)
Dim ws      As Worksheet
Dim rng     As Range
Dim MyArray                 ' variant, receives one based 2-dim data field array
'~~> Change your sheetname here
Set ws = Sheets("Sheet1")

'~~> Set you relevant range here
Set rng = ws.Range("A1:C" & ws.Range("A" & ws.Rows.Count).End(xlUp).Row)

With Me.ListBox1
    .Clear
    .ColumnHeads = False
    .ColumnCount = rng.Columns.Count

    '~~> create a one based 2-dim datafield array
     MyArray = rng

    '~~> fill listbox with array values
    .List = MyArray

    '~~> Set the widths of the column here. Ex: For 5 Columns
    '~~> Change as Applicable
    .ColumnWidths = "50;50;50"
    .TopIndex = 0
End With
End Sub

Additional hints 其他提示

  • Another advantage of the array method - it overcomes the built-in limitation of only 10 columns when using the .AddItem method. 阵列方法的另一个优点 - 它在使用.AddItem方法时克服了仅10列的内置限制。

  • Furthermore, keep in mind that listbox indexing is zero based , so for example you get the e-mail address (column 3, index 2) of your first item row (index 0) via ListBox1.List(0, 2) , whereas the data field array becomes automatically a one based 2-dim array. 此外,请记住列表框索引是基于零的 ,因此例如,您通过ListBox1.List(0, 2) )获得第一个项目行(索引0)的电子邮件地址(第3列,索引ListBox1.List(0, 2) ,而数据字段数组自动成为一个基于2的dim数组。

  • You aren't restricted to use the .List method to get Information out of the listbox, you can reverse the row - column order by using ListBox1.Column" or even create a new array out of it, which remains a 2-dim object, even if there is only ONE item (note: the Application.Transpose` method would redim a 2 dimensional array with only one row to a 1-dim array). 您不限制使用.List方法从列表框中获取信息,您可以使用ListBox1.Column" or even create a new array out of it, which remains a 2-dim object, even if there is only ONE item (note: the反转行 - 列顺序ListBox1.Column" or even create a new array out of it, which remains a 2-dim object, even if there is only ONE item (note: the Application.Transpose`方法会将只有一行的2维数组重新设置为1-dim数组)。

  • A last point: you can easily dump back again the whole listbox to an Excel sheet via rng = ListBox1.List , but take care to define the correct range. 最后一点:您可以通过rng = ListBox1.List轻松地将整个列表框转储回Excel工作表,但要注意定义正确的范围。

How about this: 这个怎么样:

Sub foo()
Dim rngName As Range
Dim ws As Worksheet
Dim i As Integer
Set ws = Worksheets("Sheet1")
ListBox1.Clear
ListBox1.columnCount = 3
Dim LastRow As Long
LastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
    For i = 1 To LastRow
        If ws.Cells(i, 1).Value <> vbNullString Then ListBox1.AddItem ws.Cells(i, 1).Value
        If ws.Cells(i, 2).Value <> vbNullString Then ListBox1.List(i - 1, 1) = ws.Cells(i, 2).Value
        If ws.Cells(i, 3).Value <> vbNullString Then ListBox1.List(i - 1, 2) = ws.Cells(i, 3).Value
    Next i
End Sub

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM