【问题标题】:How to add data from a Range to an ActiveX ListBox?如何将 Range 中的数据添加到 ActiveX ListBox?
【发布时间】:2021-03-01 23:18:09
【问题描述】:

下面我有一个宏,它从一个范围形成一个数组,并将其发布到ActiveX ListBox

代码有效,但不断发布到电子表格的速度很慢。有没有办法更有效地将整个数组发布到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

【问题讨论】:

    标签: arrays excel vba listbox


    【解决方案1】:

    使用范围参考

    如果您已经在使用 ActiveX ListBox 并且您的数据在 Range 中,为什么不直接使用 ListFillRange 属性?

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


    使用列表属性

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

    ThisWorkbook.Sheets("Worksheet").Range("A1:D300").value 返回一个二维数组,因此需要将其转换为一维数组。下面是两个可以做到这一点的辅助函数。

    ' 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
    

    【讨论】:

    • List 接受二维数组(但您需要相应地设置ColumnCount 属性)
    • 您是对的,感谢您添加该花絮!如果ListBox 需要多个列,那将是一种可行的方法。如果需要单列,则使用上述方法。
    【解决方案2】:

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

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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-02
      • 1970-01-01
      • 1970-01-01
      • 2011-01-10
      • 1970-01-01
      • 2020-02-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多