如何将数据从范围添加到 ActiveX 列表框?

How to add data from a Range to an ActiveX ListBox?

下面我有一个宏,它从一个范围形成一个数组,post将它变成一个 ActiveX ListBox

该代码有效,但不断 post 访问电子表格很慢。有没有办法更有效地post整个数组到ListBox

查看下面的代码:

Sub Test()
    'Lets format and populate the Listbox102
    Dim p as integer, i as integer, j as integer, FinalCombinedArray as variant
    FinalCombinedArray=ThisWorkbook.Sheets("Worksheet").Range("A1:D300")
    'Keep track of where the scrollbar is currently
    p = ThisWorkbook.Sheets("Worksheet").ListBox102.TopIndex
    ThisWorkbook.Sheets("Worksheet").ListBox102.Clear
    'Inset array element by element
    For i = 1 To UBound(FinalCombinedArray, 2)
        For j = 1 To UBound(FinalCombinedArray, 1)
            If i = 1 Then
                ThisWorkbook.Sheets("Worksheet").ListBox102.AddItem
            End If
            'Format array numbers
            If ((j + 1) Mod 14) = 0 Then
                ThisWorkbook.Sheets("Worksheet").ListBox102.List(j - 1, i - 1) = Format(FinalCombinedArray(j, i), "#,##0.0000")
            Else
                ThisWorkbook.Sheets("Worksheet").ListBox102.List(j - 1, i - 1) = Format(FinalCombinedArray(j, i), "#,##0.00")
            End If
        Next j
    Next i
    ThisWorkbook.Sheets("Worksheet").ListBox102.AddItem
    'If possible, bring scrollbar back to where it was
    If ThisWorkbook.Sheets("Worksheet").ListBox102.ListCount - 1 > p Then
        ThisWorkbook.Sheets("Worksheet").ListBox102.TopIndex = p
    End If
End Sub

使用范围参考

如果您已经在使用 ActiveX ListBox 并且您的数据在一个范围内,为什么不直接使用 ListFillRange 属性?

使用此方法将用所有值填充您的 ListBox 并保留常规格式。


使用列表属性

再看一眼,我发现您的示例使用了多列数据。在这种情况下,如果您需要单列 ListBox,则可以使用 ListBox.List Property 并从单维数组加载值。

ThisWorkbook.Sheets("Worksheet").Range("A1:D300").value returns是二维数组,所以需要转为一维数组。下面是执行此操作的两个辅助函数。

' Helper function to get the number
' of elements from an array from a specific dimension
Public Function ArrayLength(source As Variant, Optional dimension As Long = 1) As Long
    ArrayLength = UBound(source, dimension) - LBound(source, dimension) + 1
End Function

' Convert two dim array to a single dim array
Public Function ToSingleArray(twoDimArray As Variant) As Variant
    ' Get an empty array with needed number of elements
    ' (row * column)
    Dim temp As Variant
    ReDim temp(0 To (ArrayLength(twoDimArray, 1) * ArrayLength(twoDimArray, 2)))
    
    ' Loop first columns then rows.
    Dim column As Long
    For column = LBound(twoDimArray, 2) To UBound(twoDimArray, 2)
        Dim row As Long
        For row = LBound(twoDimArray, 1) To UBound(twoDimArray, 1)
            Dim current As Long
            
            ' Add item to the single dim array.
            temp(current) = twoDimArray(row, column)
            current = current + 1
        Next row
    Next column
    
    ' Return the new single dim array.
    ToSingleArray = temp
End Function

格式不会保留在这些文件中,因此如果需要,可以创建函数的修改版本,或者可以映射和格式化数组。

一旦您有了项目列表,它就像 .List = yourArray 一样简单。以下是您示例的简化版本

Public Sub test()
    With ThisWorkbook.Sheets("Worksheet").ListBox102
        .Clear
        .List = ToSingleArray(ThisWorkbook.Sheets("Worksheet").Range("A1:D300").Value)
    End With
End Sub

您可以通过分配整个数组而不是逐项分配来一次填充列表框

非常基本的示例:使用所选范围填充列表框

Dim rng As Range, arr
    
Set rng = Selection
arr = rng.Value
    
'optionally run over arr and format values if required

Me.ListBox1.ColumnCount = rng.Columns.Count
Me.ListBox1.List = arr