如何将数据从范围添加到 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
下面我有一个宏,它从一个范围形成一个数组,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