Excel VBA Listrow数组
我有以下的excel 2013 VBA snippit
For Each r In rr If Not r.Range.Height = 0 Then FNum = FNum + 1 ReDim Preserve testArr(1 To FNum, 1 To 23) testArr(FNum) = r End If Next r
我的目标是从一个过滤的表中获取所有可见的行到一个数组中。
该表可以是任意数量的行,但总是23列。
我发现,如果它隐藏,高度将为零。 但是对于我的生活,我无法弄清楚如何将整行放入数组中。
r = listrow rr = listrows
是的,我知道循环redim糟透了。
SpecialCells(xlCellTypeVisible)
不工作,因为它停在第一个隐藏的行/列。
我可能只是将整个表转储到数组中,然后过滤数组。 我还没有想出如何从表中拉动有源滤波器来应用它,但我还没有深入了解。 那就是我现在要做的,因为我被其他方式困住了。
任何和所有的build议是受欢迎的。
DM
要避免REDIM
或双循环,可以使用Application.WorksheetFunction.Subtotal(3, Range("A2:A500000"))
快速计算可见行数。
看到这个问题
我使用.SpecialCells(xlCellTypeVisible)
来定义我的Target
范围。 Target.Cells.Count / Target.Columns.Count
会给你行数。 最后,我遍历Target
范围内的单元格,基于Target.Columns.Count
增加我的计数器。
Public Sub FilteredArray() Dim Data As Variant, r As Range, Target As Range Dim rowCount As Long, x As Long, y As Long Set Target = WorkSheets("Sheet1").ListObjects("Table1").DataBodyRange.SpecialCells(xlCellTypeVisible) If Not Target Is Nothing Then rowCount = Target.Cells.Count / Target.Columns.Count ReDim Data(1 To rowCount, 1 To Target.Columns.Count) x = 1 For Each r In Target y = y + 1 If y > Target.Columns.Count Then x = x + 1 y = 1 End If Data(x, y) = r.Value Next End If End Sub
下面的代码将为所有行创build一个数组,并将这些数据存储到另一个数组中,这些数组将存储表中的所有信息:
Function RowsToArray() Dim lastRow: lastRow = ActiveWorkbook.ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row Dim lastCol: lastCol = ActiveWorkbook.ActiveSheet.Cells(1, Columns.Count).End(xlToLeft).Column Dim newArr() ReDim newArr(lastRow) For r = 0 To lastRow - 1 Dim rowarr() ReDim rowarr(lastCol) For c = 0 To lastCol - 1 rowarr(c) = Cells(r + 1, c + 1).Value Next c newArr(r) = rowarr Next r End Function
你可以在rr而不是行中循环单元格吗? 如果是这样,就像@SJR所说的那样,你只能Redim Preserve
最后的维度,所以我们将不得不切换你的维度。 然后可以使用r.EntireRow.Hidden
来检查我们是否在可见行中,如果是的话就增加数组的边界。
以下假设您的数据在列A中开始:
For Each r In rr If Not r.EntireRow.Hidden Then If r.Column = 1 Then If UBound(testArr, 2) = 0 Then ReDim testArr(1 To 23, 1 To 1) Else ReDim Preserve testArr(1 To 23, 1 To UBound(testArr, 2) + 1) End If End If testArr(r.Column, UBound(testArr, 2)) = r End If Next r
编辑:
或者,你可以继续使用ListRows,但循环两次,一次设置数组的边界,一次填充数组(它将有自己的内部循环,通过行…):
For Each r In rr If Not r.Range.Height = 0 Then Fnum = Fnum + 1 ReDim testArr(1 To Fnum, 1 To 3) End If Next r Fnum = 0 For Each r In rr If Not r.Range.RowHeight = 0 Then Fnum = Fnum + 1 dumarray = r.Range For i = 1 To 3 testArr(Fnum, i) = dumarray(1, i) Next i End If Next r
谢谢大家,一个答案的组合导致我:(不是很优雅,但很快)
For Each r In rr If Not r.Range.Height = 0 Then TNum = TNum + 1 End If Next r ReDim testArr(TNum, 23) For Each r In rr If Not r.Range.Height = 0 Then FNum = FNum + 1 For i = 1 To 23 testArr(FNum, i) = r.Range.Cells(, i) Next i End If Next r