Makrolaufzeit Optimierung?

Hallo zusammen,

habe ein Makro, was die Zeilen eines Blattes nach einem Wert durchsucht und diese Zeile dann löscht.
Nun hat das Tabellenblatt 45000 Zeilen und das Marko läuft ewig.
Da es bestimmt irgend nen Kniff oder eine einfachere Lösung gibt (bin leider kein VBA-Pro), könntet ihr mal gucken, wie ich ein Makro mit dieser Funktion schnell hinbekomme? Gibt es hier was günstigeres als Do Loop?(Bestimmt^^)

anbei mein Code:

Zeile = 2
PL5 = Range(„a“ & Zeile)

Do
PL5 = Range(„a“ & Zeile)
If Left(PL5, 1) = 3 Then
ActiveCell.EntireRow.Cells(Zeile, 1).Delete
Else
Zeile = Zeile + 1
End If
Loop Until PL5 = „“

habe ein Makro, was die Zeilen eines Blattes nach einem Wert
durchsucht und diese Zeile dann löscht.
Nun hat das Tabellenblatt 45000 Zeilen und das Marko läuft
ewig.

Hallo Brille,

mit Hilfsspalte, hier X, wenn belegt, nimme eine andere leere Spalte.
In ein Standardmodul, Modul1 o.ä.

Option Explicit

Sub Loesch()
Dim Zei As Long
On Error Resume Next 'wegen specialcells
Zei = Cells(Rows.Count, 1).End(xlUp).Row
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With Range("X2:X" & Zei)
 .FormulaLocal = "=WENN(LINKS(A2;1)=""3"";"""";1)"
 .Value = .Value
 .SpecialCells(xlCellTypeBlanks).EntireRow.Delete
 .ClearContents
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Gruß
Reinhard

Hallo Reinhard,

wow, das nen ich mal schnell!
Könntest du mir den Code noch ein bisschen erklären? Dann kann ichs vielleicht nächstes mal allein zurechtbasteln.

Also Prinizp ist, dass du alle die mit 3 beginnen in die Hilfsspalte ein X schreibst und dann alle die dort einen Wert enthalten löschst, oder?

Was ist „With“? Oder besser worin ist der Unterschied zu loop (Weil das X in die Zelle hätte ich wahrscheinlich auch mit Loop gebastelt)?
Und was bewirken die Applications? (Hab das in meinem Selbstkurs noch nicht behandelt^^, muss ich wohl nochmal was suchen dazu)

Vielen Dank schonmal!!

Hallo Brille,

mit Hilfsspalte, hier X, wenn belegt, nimme eine andere leere
Spalte.
In ein Standardmodul, Modul1 o.ä.

Option Explicit

Sub Loesch()
Dim Zei As Long
On Error Resume Next 'wegen specialcells
Zei = Cells(Rows.Count, 1).End(xlUp).Row
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
With Range(„X2:X“ & Zei)
.FormulaLocal = „=WENN(LINKS(A2;1)=“„3"“;"""";1)"
.Value = .Value
.SpecialCells(xlCellTypeBlanks).EntireRow.Delete
.ClearContents
End With
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Gruß
Reinhard

Hallo Brille,

Also Prinizp ist, dass du alle die mit 3 beginnen in die
Hilfsspalte ein X schreibst und dann alle die dort einen Wert
enthalten löschst, oder?

nein, genau anders rum :smile:
Gehe in den Editor zum/in den Code, drücke nacheinander F8.
Vor/nach jedem F8-Druck kannste in der Tabelle beobachten was da in X geschieht.
Kannst bei sowas auch zwei Fenster einrichten, einmal die tabelle, einmal den Editor.

Was ist „With“? Oder besser worin ist der Unterschied zu loop

Loop ist wie For eine Schleife. D.h. je nach Bedingungen werden die befehle in der Schleife oftmals dzuchlaufen.
With ist da anderst. Es sagt nur daß alle Befehle die in der With-Schleife stehen sich auf das Objekt beziehen was nach With steht.
Die Befehle die das machen sollen müssen vor sich einen Punkt haben.

Befehele ohne Punkt werden behandelt als wenn sie außerhalb der Wioth-Schleife stünden.

Nachfolgend noch Hilfen im Code.

Du hast einen Grundsatzfehler in deinem Code.
Zeilen löscht man grundsätzlich von unten nach oben.
Bei deiner Variante kommt Vba mit den Zeilennummern anscheinend durcheinander. Man kann natürlich auch von oben nach unten löschen, aber nach jeder Zeilenlöschung muß man dann die Zeilennummer im Code korrigieren.
Siehe dazu die beiden Kurzcodes unten.
Schreib dazu in A1:A10 die Zahlen 1-10 und teste dann den einen Code, dann das Glaiche nochmal für den zweiten Code.

Gruß
Reinhard

Sub Loesch()
Dim Zei As Long
' Specialcells bringt Fehler wenn keine leeren Zellen gefunden
' mit dem Befehl wird dieser Fehler ignoriert
On Error Resume Next
'letzte benutzte zelle in A
Zei = Cells(Rows.Count, 1).End(xlUp).Row
'Bildschirmaktualisierung Aus
Application.ScreenUpdating = False
'manuelle Berechnung Ein
Application.Calculation = xlCalculationManual
'die Punkte vor den Befehlen in der With-Schleife referenzieren auf diesen Bereich
With Range("X2:X" & Zei)
 .FormulaLocal = "=WENN(LINKS(A2;1)=""3"";"""";1)"
 'entspricht Strg+C dann Bearbeiten--Inghalte einfügen---Werte
 'also in Zellen werden die Formeln gelöscht und das Formelergebnis als Wert reingeschrieben
 .Value = .Value
 'Löschen im Bereich alle Zeilen wo in X nix steht
 .SpecialCells(xlCellTypeBlanks).EntireRow.Delete
 'Inhalt der Hilfsspalte wird gelöscht
 .ClearContents
End With
'automatische Berechnung Ein
Application.Calculation = xlCalculationAutomatic
'Bildschirmaktualisierung Ein
Application.ScreenUpdating = True
End Sub





Sub Falsch()
Dim Zei As Long
For Zei = 1 To 10
If Range("A" & Zei).Value "" Then
 Range("A" & Zei).EntireRow.Delete
End If
Next Zei
End Sub

Sub Richtig()
Dim Zei As Long
For Zei = 10 To 1 Step -1
If Range("A" & Zei).Value "" Then
 Range("A" & Zei).EntireRow.Delete
End If
Next Zei
End Sub
1 Like

nein, genau anders rum :smile:

hab ich auch gerad gemerkt, alles ich den code bei was anderem probiert hatte :smile:

Vielen Dank für die Tipps erstmal, die anderen beiden codes muss ich mir nochmal genau anschauen, aber nu is gleich erstmla wochenende^^

MfG

schau dir mal find() an. da wird mit hilfe der excel suche nach dem wert gesucht. die läuft nicht mit O(n) wie eine for- oder while-schleife, sondern mit O(1). denn intern speichert excel die daten nicht als tabelle…

Hallo Brille,

ich habe mal versucht, einen VBA-Code zu schreiben, der nur die eingebauten Excel-Funktionen benutzt. Er sollte also relativ schnell sein. Bei mir habe ich für 45.000 Zeilen etwa 8 sec gebraucht.
Voraussetzung ist, dass du nur Text hast (keine Zahlen, die mit 3 beginnen). Dann könnte dieser Code gehen:

Sub Löschen()
 ' deine Werte stehen in Spalte A
 Application.ScreenUpdating = False
 Range("A:A").AutoFilter Field:=1, Criteria1:="=3\*", Operator:=xlAnd
 Range("A2", Cells(2, 1).End(xlDown)).EntireRow.Delete
 Range("A:A").AutoFilter
 Application.ScreenUpdating = True
End Sub

Gruß, Andreas

Hallo zusammen,

ich ein Makro mit dieser Funktion schnell hinbekomme? Gibt es
hier was günstigeres als Do Loop?(Bestimmt^^)

Hallo Grußloser,

schau dir mal find() an.

hab ich gemacht.

da wird mit hilfe der excel suche
nach dem wert gesucht.

D.h. Find entspricht in Excel Bearbeiten—Suchen? Wußte ich nicht.

die läuft nicht mit O(n) wie eine for-
oder while-schleife, sondern mit O(1).

Kannst du das bitte mal genauer erklären was das bedeutet.

denn intern speichert
excel die daten nicht als tabelle…

Und das auch.

Gruß
Reinhard

oder while-schleife, sondern mit O(1).

Kannst du das bitte mal genauer erklären was das bedeutet.

es muss nicht von 1 zu n durchzählen sondern hat den wert wie beim assoziativen array gleich gefunden .

also nicht

1 Hamburg
2 Berlin
3 Hamburg
4 Berlin

sondern

Hamburg 1,3
Berlin 2,4

denn intern speichert
excel die daten nicht als tabelle…

könnt mir vorstellen das es quasi assoziativ ist, also direkt ansprechbar .

nur vermutung :smile:

die läuft nicht mit O(n) wie eine for-

oder while-schleife, sondern mit O(1).

Kannst du das bitte mal genauer erklären was das bedeutet.

das bedeutet, dass die laufzeit des programms nicht mit der anzahl der durchsuchten elemente ansteigt, sondern davon unabhängig bleibt und immer gleich lang ist.

beispiel for schleife zum suchen in einer tabelle:

for i = 1 to n
if cells(i, 1).value = suchstring then
'mach was
end if
next

die schleife muss n-mal durchlaufen werden. bei hoher zeilenzahl braucht das entsprechend zeit - eben die n-fache zeit eines durchlaufs mit einer zeile.