2015-12-01 10 views
5

Ich habe etwa 8000+ Zeilen. Die Verwendung von Autofilter zum Löschen von Zeilen dauert einige Minuten. Ich dachte, Autofilter war die defacto FAST Weg zu löschen (statt Zeile für Zeile). Wie kann ich es beschleunigen? Gibt es einen schnelleren Weg? Um fair zu sein, die Hälfte der Zeilen XD gelöschtLöschen über Autofilter dauert zu lange

With ThisWorkbook.Worksheets("Upload") 
    lastRow = .Cells(.Rows.Count, "S").End(xlUp).Row 
    Set dataRng = .Range(.Cells(4, 1), .Cells(lastRow, 19)) 
    dataRng.AutoFilter field:=19, Criteria1:="=0" 
    Application.DisplayAlerts = False 
    dataRng.Offset(1, 0).Resize(dataRng.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete 
    Application.DisplayAlerts = True 
    .ShowAllData 
End With 
+0

Können die Daten sortiert? Wenn ja, könnten Sie eine Spalte mit einer Formel '= $ S1 = 0' oder etwas dieser Art hinzufügen, nach unten kopieren und dann zuerst sortieren und das erste Vorkommen (falls vorhanden) in die letzte Zeile löschen? – Demetri

+0

Oder was ich tue, ist die "guten" Daten zu filtern, sie in ein neues Blatt zu kopieren und dann das neue Blatt wieder in das alte zu kopieren. – Demetri

+0

Hmm Sortierung könnte funktionieren ... – findwindow

Antwort

5

Ich werde zu Grunde liegende Annahme herauszufordern, dass Autofilter der schnelle Weg zu gehen - es oft schwierig ist, eine Schleife über eine Variante Array zu schlagen

diese Demo zeigt einen Weg, dies zu tun, auf meinem System Verarbeitung 8000+ Reihen Hälfte läuft in Unter zweiten Entfernungs

Sub DEMO() 
    Dim datrng As Range 
    Dim dat, newdat 
    Dim i As Long, j As Long, k As Long 
    With ThisWorkbook.Worksheets("Upload") 
     Set datrng = .Range(.Cells(1, 1), .Cells(.Rows.Count, "S").End(xlUp)) 
    End With 
    dat = datrng.Value 
    ReDim newdat(1 To UBound(dat, 1), 1 To UBound(dat, 2)) 
    j = 1 
    For i = 1 To UBound(dat, 1) 
     If dat(i, 19) <> 0 Then ' test for items you want to keep 
      For k = 1 To UBound(dat, 2) 
       newdat(j, k) = dat(i, k) 
      Next 
      j = j + 1 
     End If 
    Next 

    datrng = newdat 
End Sub 
+0

Nun, mein Bereich beginnt in den Zellen (4,1), aber ich werde dies durchlesen, während ich teste ^^ – findwindow

+0

Untersekunde ist korrekt! Vielen Dank. – findwindow

3

getestet habe ich die Makros für die Geschwindigkeit und festgestellt, dass das Sortieren, autofiltering und Löschen ist schneller als ein Array Aufbau .

Mit dem Timing-Code here ich den ursprünglichen Code über 100k Zeilen von Zufallsdaten (25 Spalten breite Zufallszahlen zwischen 0-4).

-Original Code dauerte 78 Sekunden (nur lief 50k hier Reihen um ihn zu beschleunigen)

Das Array Code von chris 1,91 Sekunden nahm präsentiert

-Der Code unter 0,84 Sekunden dauerte (Versuchte es läuft Sortierung aufsteigend und absteigend und es machte wenig Unterschied, wenn der Bereich von Nullen nach oben oder unten sortiert wurde

Ich weiß, die eingebaute Uhr ist nicht gut in VBA, aber der Unterschied ist genug, dass ich bequem sagen Sortierung bin In diesem Fall ist Filterung, Löschen mindestens so schnell wie bei Arrays

Der folgende Code nur dataRng.Sort key1:=Range("S4"), order1:=xlDescending, Header:=xlYes auf den ursprünglichen Code hinzugefügt

Sub test() 

With Sheets("sheet1") 
    lastRow = .Range("S" & .Rows.Count).End(xlUp).Row 
    Set dataRng = .Range(.Cells(4, 1), .Cells(lastRow, 25)) 
    dataRng.Sort key1:=Range("S4"), order1:=xlDescending, Header:=xlYes 
    dataRng.AutoFilter field:=19, Criteria1:="=0" 
    Application.DisplayAlerts = False 
    dataRng.Offset(1, 0).Resize(dataRng.Rows.Count - 1).SpecialCells(xlCellTypeVisible).Rows.Delete 
    Application.DisplayAlerts = True 
    .ShowAllData 
End With 
End Sub 
+1

Huh. Sortierung macht es also schneller. – findwindow