2016-11-29 2 views
1

Ich habe die unten snippit für Excel 2013 VBAExcel VBA Listrow zu Array

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 

Mein Ziel ist es, alle sichtbaren Zeilen aus einer gefilterten Tabelle in ein Array zu erhalten.

Die Tabelle kann eine beliebige Anzahl von Zeilen, aber immer 23 Spalten enthalten.

Ich fand, dass die Höhe Null ist, wenn es ausgeblendet ist. Aber für das Leben von mir kann ich nicht herausfinden, wie man die ganze Reihe in die Reihe bringt.

r = listrow rr = ListRows

JA, ich weiß, ein Looping ReDim saugt.

Special (xlCellTypeVisible)

nicht funktioniert, weil es entweder stoppt beim ersten ausgeblendete Zeile/Spalte.

Ich kann nur die gesamte Tabelle in das Array ausgeben und dann das Array filtern. Ich habe nicht herausgefunden, wie man den aktiven Filter vom Tisch zieht, um ihn anzuwenden, aber ich habe noch nicht tief in das Thema hineingeschaut. Das werde ich jetzt tun, weil ich für den anderen Weg feststecke.

Alle und alle Ratschläge sind willkommen.

DM

+1

Was ist rr? Ich glaube nicht, dass Ihr Code trotzdem wie gewünscht funktionieren kann, da Redim Preserve nur die letzte Dimension verändert. – SJR

+0

Wie groß ist dein Tisch? –

Antwort

0

Dank all, führte mich eine Combo von Antworten zu: (nicht sehr elegant, aber schnell)

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 
0

Können Sie Schleife über die Zellen in rr anstatt den Reihen? Wenn ja, wie @SJR sagt, können Sie nur die endgültige Dimension Redim Preserve, also werden wir Ihre Dimensionen wechseln müssen. Sie können dann r.EntireRow.Hidden verwenden, um zu überprüfen, ob wir in einer sichtbaren Zeile sind, und die Grenze Ihres Arrays um eins zu erhöhen, wenn wir es sind.

Im Folgenden wird angenommen, dass Ihre Daten beginnt in Spalte 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 

Edit:

Alternativ können Sie ListRows halten verwenden, aber Schleife zweimal durch, sobald die Grenzen Ihres Arrays zu setzen, und sobald das Array zu füllen (das seine eigene interne Schleife haben wird durch die Reihe zu laufen ...):

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 
+0

Wenn das Array noch nicht zugewiesen wurde, wird 'If UBound (testArr, 2) = 0 Then 'einen Type Mismatch Error auslösen. –

+0

Entschuldigung, ja, ich nahm früher eine 'Dim testArr (1 bis 3, 0 bis 0) 'an. – bobajob

2

REDIM oder Doppelschleifen vermeiden Sie so verwenden können, meting wie Application.WorksheetFunction.Subtotal(3, Range("A2:A500000")), um schnell die Anzahl der sichtbaren Zeilen zu zählen.

Siehe this question

1

ich meine Target Bereich mit .SpecialCells(xlCellTypeVisible) definieren. Target.Cells.Count/Target.Columns.Count gibt Ihnen die Zeilenanzahl. Schließlich iteriere ich über die Zellen im Bereich Target und inkrementiere meine Zähler basierend auf der 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 
1

Der folgende Code wird ein Array für alle Zeilen und speichern jede dieser in ein anderes Array erstellen, die alle Informationen in Blatt gespeichert werden:

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