Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1824to1828
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
Inhaltsverzeichnis

For, InStr + Delete sehr langsam

For, InStr + Delete sehr langsam
15.04.2021 11:06:03
Marc
Hi,
ich habe ein sehr simples kleines VBA-Skript, welches das tut was es soll. Es durchläuft ein Arbeitsblatt von unten nach oben und löscht die Zeilen sofern eine Bedingung erfüllt ist:

Sub Bereinigen()
Dim LastRow As Long, Zeile As Long
LastRow = Sheets("Übersicht").Cells(Sheets("Übersicht").Rows.Count, "A").End(xlUp).Row
For Zeile = LastRow To 2 Step -1
If InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text A") = 0 _
And InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text B") = 0 _
And InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text C\") = 0 _
Then
Sheets("Übersicht").Rows(Zeile).Delete Shift:=xlUp
End If
Next Zeile
End Sub

Was mich wundert: Wir sprechen von Was bitte braucht denn dabei so viel Zeit? Mache ich etwas falsch oder übersehe ich etwas?
Danke vorab.

11
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 11:20:07
Rudi
Hallo,
wenn du eine Zeile löschst, wird immer neu berechnet.
Erst sammeln und dann alles auf einmal löschen.
Sub Bereinigen()
Dim LastRow As Long, Zeile As Long
Dim rngDel As Range
LastRow = Sheets("Übersicht").Cells(Sheets("Übersicht").Rows.Count, "A").End(xlUp).Row
For Zeile = LastRow To 2 Step -1
If InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text A") = 0 _
And InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text B") = 0 _
And InStr(Sheets("Übersicht").Cells(Zeile, 2).Value, "\Text C\") = 0 _
Then
If rngDel Is Nothing Then
Set rngDel = Cells(Zeile, 1)
Else
Set rngDel = Union(rngDel, Cells(Zeile, 1))
End If
Next Zeile
If Not rngDel Is Nothing Then rngDel.EntireRow.Delete
End Sub

Gruß
Rudi
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 11:21:52
Marc
Super Hinweis - danke!
Wenn du schreibst "wird immer alles neu berechnet" bedeutet das, dass die Schleife dann wieder von vorne anfängt oder was genau ist damit gemeint?
AW: For, InStr + Delete sehr langsam
15.04.2021 11:27:11
Rudi
vorhandene Formeln, bed. Formatierungen etc.
AW: For, InStr + Delete sehr langsam
15.04.2021 16:27:26
Daniel
Hi
grundsätzlich gilt:
wann immer du in Excel etwas änderst, laufen eine Reihe von Hintergrundprozessen ab.
die wichtigsten wären:
- Bildschirm anpassen
- Prüfen, ob die Änderung für die Ausführung eines Eventmakros relevant ist
- Prüfen, ob in dieser oder einer anderen Datei Formeln gibt, die sich auf diese Zellen beziehen und dann ggf neu berechnet werden müssen
- prüfen, ob es bedingte Formatierungen gibt, die sich auf diese Zellen beziehen und neu berechnet werden müssen
- beim löschen oder einfügen von Zellen prüfen, ob es Formeln gibt die auf den betroffenen Zellbereich referenzieren und dann die Zellbereiche in diesen Formeln anpassen
usw.
das wird bei jeder Änderung ausgeführt.
einen Teil dieser Aufgaben kann man ausschalten (Application.Calculation, Application.EnableEvents, Application.ScreenUptating)
eine andere Methode die sache zu beschleunigen ist, wenn es möglich ist nicht jede Zelle einzeln zu bearbeiten, sondern möglichst gemeinsam im Block mit einem Bearbeitungsschritt.
Dann kann Excel diese Aufgaben für den ganzen Block gemeinsam ausführen.
Im Prinzip so wie beim Einkaufen, wenn du für jeden Artikel den du brauchst, extra in den Laden gehst, dauert das länger, als wenn du einmal in den Laden gehst und dann alle Artikel zuammen kaufst.
auf diesem Ansatz basiert auch die Empfehlung von Rudi.
alledings hat die Sache beim Einfügen oder Löschen einen Haken.
da wird das gemeinschaftliche Löschen oder einfügen nur dann schneller, wenn die zu löschenden Zeilen möglichst wenige, dafür aber große lückenlos zusammenhängende Zellblöcke bilden.
sobald das einzelne Zeilen sind, bringt das Zusammenfassen in einer Rangevariable nur wenig.
oder so forumliert:
Range("1:1000").Delete dauert genauso lange wie Range("1:1").Delete, weil beide Zellbereiche nur einen einzigen lückenlos zusammenhängenden Zellblock enthalten
Range("1:1,3:3") hingegen dauert doppelt so lang, weil es zwei Zellblöcke sind.
der Grund hierfür ist das Anpassen der Formeln, die auf den gelöschten Zellbereich referenzieren.
Das kann Excel immer nur für einen Lückenlosen Block ausführen und muss beim nächsten Block neu anfangen.
dh um das Löschen von Zeilen wirkungsvoll zu beschleunigen, gibt es zwei wege:
a) man sortiert die Tabelle vor dem Löschen so, dass alle zu löschenden Zeilen einen lückenlos zusammenhängenden Zellblock bilden, der dann in einem Schritt gelöschte werden kann.
hierzu kann es erforderlich sein, für die Sortierung die Zeilen in einer Hilfsspalte per Formel zu kennzeichnen (Formeln kann man in einem Schritt für alle Zeilen gleichzeitig einfügen)
b) man kennzeichnet die zu löschenden Zellen mit einer Formel, hierbei bekommen die zu löschenden Zeilen eine 0, die anderen Zeilen die akuelle Zeilennummer (Zeile())
dann wendet man auf die Tabelle die Menüfunktion DATEN - DATENTOOLS - DUPLIKATE ENTFERNEN an, mit der Hilfsspalte als Kriterium.
Hierfür muss die Tabelle nicht sortiert werden.
Das ist sehr schnell, weil beim Duplikate-Entfernen die Anpassung der Zellbezüge in den Formeln nicht stattfindet und Excel dadurch viel Zeit spart.
Gruß Daniel
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 18:14:50
onur
Das mit den zusammenhängenden Ranges ist nicht sooo relevant.
Wenn du auch mal testest:
Überprüfen von 2000 Zeilen x 6 Spalten (alle mit Formeln) und 1000 komplette Zeilen davon löschen (nicht zusammenhängend - jede zweite): 91 sec.
Mit Screenupdate aussschalten: 81 sec
Automatische Berechnung ausschalten und Screenupdate einsschalten: 11 sec
Beides ausgeschaltet: 3,26 sec.
In allen Fällen natürlich alles wieder (vor Zeiterfassung) eingeschaltet.
AW: For, InStr + Delete sehr langsam
15.04.2021 18:50:33
Daniel
Hi Onur
teste mal das Löschen der Zeilen mit RemoveDuplicates
zum kennzeichnen der Zeilen wenn jede zweite gelöscht werden soll kann man die Formel: =Zeile()*IstGerade(Zeile()) verwenden.
gerne auch mit und ohne den "Bremsen"
Gruß Daniel
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 19:35:13
onur
Hi Daniel,
Ist ja schon ultraschnell (0,12 bis 0,15 sec), aber leider werden dabei nicht die kompletten Zeilen geköscht, sondern nur die Zellen, die im Bereich liegen. Man kann ja aber den Bereich bis z.B. ZZ erweitern, und man müsste noch mind. eine Hilfsspalte anlegen, um Doppelte zu produzieren.
Gruß
Onur
AW: For, InStr + Delete sehr langsam
15.04.2021 19:48:15
Daniel
naja, das mit den kompletten Zeilen erledigt ein .EntireRow. und das einfügen einer Hilfsspalte sollte auch nicht das Problem sein, wenn man damit die Zeiten damit nochmal um den Faktor 20! reduzieren kann.
ich mach das Löschen von Zeilen nur noch so, alles andere ist zu langsam und zu aufwendig.
und wenn man die ganzen "GetMoreSpeed" - Einstellungen weglassen kann sowie die Absicherung des Fehlerfalls, dann reduziert das den Programmieraufwand wesentlich mehr, als das temporäre Einfügen einer zusätzlichen Spalte.
Gruß Daniel
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 19:52:50
onur
Hi Daniel,
Ach - RemoveDuplicates.EntireRow geht auch noch ?
Gut zu wissen - Danke für den Tip !
Gruß
Onur
AW: For, InStr + Delete sehr langsam
15.04.2021 20:09:17
Daniel
warum sollte das nicht gehen?
hier siehst du mal meinen StandardCode für das löschen von Zeilen mit Bedingung:
https://www.herber.de/forum/archiv/1824to1828/t1826060.htm#1826082
kann man universell so verwenden, sofern man in der Lage ist, sich eine Formel auszudenken, die die zu löschenden Zeilen erkennt und mit 0 kennzeichnet, dh im Code muss eigentlich nur die Formel angepasst werden.
Etwas komplizierter wirds noch, wenn sich die Formel auf die darüber liegende Zeile beziehen muss, dann darf die Formel nicht in die Überschriftenzeile, was man aber mit diesem Zusatz erreichen kann:
.Resize(.Rows.Count - 1).Offset(1, 0).FormulaR1C1 = "..."

Gruß Daniel
Anzeige
AW: For, InStr + Delete sehr langsam
15.04.2021 19:53:49
onur
RemoveDuplicates.EntireRow - natürlich umgekehrt.

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige