【问题标题】:Fill listbox with array and add next 2 array into用数组填充列表框并将下一个 2 数组添加到
【发布时间】:2021-08-09 22:52:27
【问题描述】:

我在for 循环中打开许多工作簿并将数据加载到动态array。 现在我需要从这些arrays 中获取值到列表框中,但不知道如何...

Dim rng as Variant
Set rng = wsDat.Range(Cells(2, 1), Cells(lastRow, 1).Offset(0, 10)) 'for more ws

myArray1 = rng.Value 'result of ws1 data
myArray2 = rng.Value 'result od ws2 data
.
.
.

Me.myListbox.List = myArray1
Me.myListbox.List ??? add myArray2

【问题讨论】:

  • 旁注:您需要为Cells(2, 1)Cells(lastRow, 1) 限定工作表。见thisthis
  • @BigBen 谢谢...是现在吗? Dim wsDat As Worksheet Set rng = wsDat.Range(wsDat.Cells(2, 1), wsDat.Cells(lastRow, 1).Offset(0, 10))
  • 是的,现在Cells 调用符合相应的Worksheet
  • 是否需要加载每个数组的值的列表框?我的意思是加载它的次数与存在的纸张数一样多?或者用所有这些数组的内容加载列表框?寻找“Me.myListbox.List ??? add myArray2”我想您需要在列表框中添加所有这些数组内容。在这种情况下,您不能使用list 属性添加项目。您应该以某种方式加入数组并在代码末尾立即加载list 列表框属性。如果我的理解/假设是正确的,我可以准备一段代码。

标签: arrays excel vba listbox


【解决方案1】:

假设您需要在列表框中加载这些数组的所有内容,您不能使用list 属性来以这种方式添加项目。下一个.list = array 会删除之前的列表项。您可以使用它一次,然后通过迭代添加项目,或者更优雅地加入数组并在最后使用list 加载加入的数组。要测试最后一种方式,请尝试下一个代码:

 Sub JoinArraysLoadList()
    Dim ws As Worksheet, lastRow As Long, myArray, myArrTot
    
    For Each ws In ActiveWorkbook.Sheets
            lastRow = ws.cells(ws.rows.count, 1).End(xlUp).row
            myArray = ws.Range(ws.cells(2, 1), ws.cells(lastRow, 1).Offset(0, 10)).Value
            If Not IsArray(myArrTot) Then 'if myArrTot did not receive any range value:
                myArrTot = myArray
            Else                                    'join myArrTot with the newly extracted array:
                'the arrays need to be transposed, in order to add elements (allowed only on the second dimension)
                myArrTot = JoinArrays(Application.Transpose(myArrTot), Application.Transpose(myArray))
            End If
    Next
    Me.myListbox.List = myArrTot
 End Sub

 Function JoinArrays(arrT, arr) As Variant
    Dim i As Long, j As Long, nrRows As Long
    
    nrRows = UBound(arrT, 2) 'the existing number of rows (now, columns...)
    ReDim Preserve arrT(1 To UBound(arrT), 1 To nrRows + UBound(arr, 2))
    For i = 1 To UBound(arr)
        nrRows = nrRows + 1 'increment the next row to be loaded
        For j = 1 To UBound(arr, 2)
            arrT(j, nrRows) = arr(i, j)
        Next j
    Next i
    JoinArrays = Application.Transpose(arrT)
 End Function

已编辑

下一个解决方案应该是更快/更高效的变体:

Sub JoinArraysLoadListJgArr()
    Dim wb As Workbook, ws As Worksheet, lastRow As Long
    Dim cnt As Long, noEl As Long, myArray, myArrTot, jgArr
    
    Set wb = ActiveWorkbook          'use here the necessary workbook
    ReDim jgArr(wb.Sheets.count - 1) 'redim the jagged array at the maximum necessary dimensioned (0 based array)
    For Each ws In wb.Sheets
            lastRow = ws.cells(ws.rows.count, 1).End(xlUp).row
            myArray = ws.Range(ws.cells(2, 1), ws.cells(lastRow, 1).Offset(0, 10)).Value
            noEl = noEl + UBound(myArray)       'counting the number of each array rows
            jgArr(cnt) = myArray: cnt = cnt + 1 'loading each sheet array in the jagged one
    Next
    If cnt < wb.Sheets.count Then
        ReDim Preserve jgArr(cnt - 1) 'preserve only the existing elements (if a sheet or more have been skipped)
    End If
    myArrTot = JoinJgArr(jgArr, noEl)
    Me.myListbox.List = myArrTot
 End Sub
 
 Function JoinJgArr(jgA, N As Long) As Variant
    Dim k As Long, i As Long, j As Long, iRow As Long, arrFin
    
    ReDim arrFin(1 To N, 1 To UBound(jgA(0), 2)) 'redim the array to take the jagged array elements
    
    For k = 0 To UBound(jgA)                  'iterate between the jagged array elements
        For i = 1 To UBound(jgA(k))           'iterate between each jagged array element rows
            iRow = iRow + 1                   'counting the rows or the final array to be filled!!!
            For j = 1 To UBound(jgA(k), 2)    'iterate between each jagged array element columns
                arrFin(iRow, j) = jgA(k)(i, j)'put values in the final array
            Next j
        Next i
    Next k
    
    JoinJgArr = arrFin
 End Function

【讨论】:

  • 解释得很好:+)
  • @T.M.谢谢!我有加入数组的函数,但是当试图定义上述解决方案时,我可以想象一个更快、更高效的解决方案。由于 OP 没有说什么,我失去了构建更好版本的热情。现在,如果有人(重要的......)评论了代码,我将创建优化版本。将每个工作表数组放入锯齿状数组中并计算每个数组行数将使代码使用更少的资源。没有必要用更多的ReDim Preserve 行转置和强调内存。在我的解决方案中,应该需要几分钟才能将其付诸实践。我希望... :)
  • @FaneDuru 谢谢,但这对我来说太复杂了。我可能必须先将它复制到 Activeworkbook 中的工作表中,然后添加到 Listbox.list 中。我不知道这是否可能是简单的方法。
  • @excel222: 如果我是你,我会先描述我的目的是什么...原则上,你需要加载那个特定的列表框吗? 前十列的所有工作表内容?如果是,那么它是关于什么样的列表 bos 的?它是工作表 ActiveX 类型吗?我的意思是它存在于工作表上还是表单上?根据您对上述问题的回答,我将告诉您如何使用代码。这应该很容易......
  • @FaneDuru 非常感谢您的关注。每个月我都有几本工作簿,我在其中记录客户的货物。现在我正在尝试将这些工作簿中的数据加载到 UserForm ListBox。在此列表框中,我选择项目并开具发票。在原始工作簿中,发票项目必须标记为“完成”或“storno”。我是 VBA 的初学者,这个项目对我来说很难。这就是为什么我尝试通过小部件学习简单的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 1970-01-01
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多