Live-Forum - Die aktuellen Beiträge
Anzeige
Archiv - Navigation
1844to1848
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

Re: Spalten vergleichen von Oliver

Re: Spalten vergleichen von Oliver
26.08.2021 16:35:27
Oliver
Hallo Leute,
Ich möchte mich beziehen auf die Antwort von Thorsten (Oberschlumpf) auf obiges Posting hier von Oliver:
https://www.herber.de/forum/messages/1845120.html
Erstmal vorneweg: Thorstens Code als Lösung funktioniert tadellos für das Problem vom Oliver:

Sub sbTest()
Dim lloRow As Long
With Sheets("Tabelle1") 'anpassen, wenn anders als "Tabelle1"
For lloRow = .Cells(.Rows.Count, 6).End(xlUp).Row To 1 Step -1
If LCase(Left(.Range("F" & lloRow).Value, 2)) = LCase(Sheets("Tabelle2").Range("Q4").Value) Then 'anpassen, wenn anders als "Tabelle2"
If LCase(.Range("G" & lloRow).Value) = "12a" Or _
LCase(.Range("G" & lloRow).Value) = "12b" Then
.Rows(lloRow).Delete
End If
End If
Next
End With
End Sub
Ich bin hier ja noch nicht so lange aktiv aber mir ist schon oft aufgefallen, dass viele Anfragenden und viele Lösungsvorschläge
- Berechnete Zellreferenzen oft mit Range und Buchstabe+Zahl zusammenbauen
- Als Blattreferenz immer den änderbaren Namen wie Sheets("Tabelle1") benutzen anstatt dem Blatt einen festen Namen zu geben
Der Umweg über Strings (wo eben nicht notwendig) kostet immens Rechenzeit! Insbesondere Konstrukte wie "Range("F" & lloRow)" legen einen ersten String "F" an, konvertieren eine Zahl "lloRow" in einen zweiten String und erzeugen durch Verbinden der beiden einen dritten!
Wenn wir hier von 100 Feldern reden, sicher völlig belanglos - aber auch nicht einfacher als mit dem Befehl "Cells()" zu arbeiten!?
Bei großen Mengen macht sich das aber deutlich in der Rechenzeit bemerkbar!
Deshalb meine Frage: Warum also? Gibt es Gründe, die sich mir nicht erschließen, das immer auf diese Weise zu machen?
Den einzigen Nachteil den ich bei "Cells(lloRow, 6)" vs. "Range("F" & lloRow)" erkenne ist, dass man wissen muss, das 6 für Spalte "F" steht. Bei höheren Zahlen braucht man deshalb oft alle Finger zum überprüfen :--)
Ich löse das für mich durch die Angabe der Spalte in einem Kommentar nach dem Befehl.
Ich habe jetzt mal eine Testmappe gebaut
https://www.herber.de/bbs/user/147803.xlsm
in der ich Varianten von Thorstens Code auf 100.000 Datensätze (zwei Werte in Spalten F und G) losgelassen habe.
Die Datensätze musste ich leider vor dem Hochladen hier löschen, sonst hätte ich die hier zulässige Größe von 300 kByte überschritten.
Deshalb bitte nach dem Start in Tabelle 2 mit Button "Tabelle1 neu füllen" neue Zufallsdaten erzeugen.
Hier die von mit verwendeten Codeteile.
Original von Thorsten an die Mappe angepasst:
[Ich habe den Befehl ".Rows(lloRow).Delete" durch " .Cells(lloRow, 8) = "X"" ersetzt, weil ja sonst eine Wiederholung des Tests nicht möglich wäre.]

Sub sbTest(Zeit As Long)
'Orginialsyntax
Dim lloRow As Long
Call ClearH
lngTime = GetTickCount '====================
With Sheets("Tabelle1")
For lloRow = .Cells(.Rows.Count, 6).End(xlUp).Row To 1 Step -1 'Spalte F
If LCase(Left(.Range("F" & lloRow).Value, 2)) = LCase(Sheets("Tabelle2").Range("C3").Value) Then
If LCase(.Range("G" & lloRow).Value) = "12a" Or LCase(.Range("G" & lloRow).Value) = "12b" Then
.Cells(lloRow, 8) = "X" 'Spalte H   Original: .Rows(lloRow).Delete
End If
End If
Next
End With
Zeit = GetTickCount - lngTime '==================== Testzeit in ms
End Sub
Mein optimierter Code:

Sub sbTestF(Zeit As Long)
'Final Syntax
Dim lloRow As Long, A$
Call ClearH
lngTime = GetTickCount '====================
With Application
.ScreenUpdating = False
.Calculation = xlCalculationManual
End With
A$ = shtAus.Cells(3, 3)
With shtTab1
For lloRow = .Cells(Rows.Count, 6).End(xlUp).Row To 1 Step -1 'Spalte F
If StrComp(Left(.Cells(lloRow, 6), 2), A$, vbTextCompare) = 0 Then
Select Case LCase(.Cells(lloRow, 7)) 'Spalte G
Case "12a", "12b"
.Cells(lloRow, 8) = "X" 'Spalte H
End Select
End If
Next
End With
With Application
.Calculation = xlCalculationAutomatic
.ScreenUpdating = True
End With
Zeit = GetTickCount - lngTime '==================== Testzeit in ms
End Sub
Mit den letzten Zufallsdaten ergab sich eine durchschnittliche Zeitersparnis von fast 77%!
Da das Betriebssystem Excel nicht immer die gleichen Rechenzeitscheiben zur Verfügung stellt, mache ich immer 5 Durchläufe und ein Mittel in Millisekunden.
Neben den beiden habe ich noch zwei Fälle getestet und dadurch sieht man deutlich, dass die Hauptersparnis durch Weglassen der Stringberechnungen und dem unnötigen mehrfachen Zugriff auf ein und dieselbe Zelle im Blatt gemacht wird.
Ihr könnt ja im Code auch andere Varianten testen.
Ich dachte, ich teile diese Erkenntnisse mal mit Euch.

2
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Re: Spalten vergleichen von Oliver
26.08.2021 16:49:41
Oliver
Hallo,
das ist nichts neues.
Noch schlimmer als Range("F" &loRow) finde ich Cells(loRow,"F"). In jedem Fall muss der String zu einer konkreten Zelladresse n der Form Cells(ZeileNr, SpalteNr) interpretiert werden und das kostet, wie du schon bemerkt hast, Rechenzeit.
Wenn man ausschließlich mit festen Daten arbeitet, sollte man das mit Arrays machen. Ist das weitaus schnellste.
Zeilen wie in deinem Beispiel, einzeln zu löschen, ist die lahmste Methode überhaupt. Immer im Block!
Zur Blattreferenz: Ich arbeite fast ausschließlich mit den Codenamen, die ich mir auch an meine Bedürfnisse anpasse.
Gruß
Rudi
Anzeige
AW: Re: Spalten vergleichen von Oliver
26.08.2021 17:41:49
Oliver
Hi Rudi,
"Zeilen wie in deinem Beispiel, einzeln zu löschen, ist die lahmste Methode überhaupt. Immer im Block!"
Ja sicher, aber das hätte jetzt zu weit geführt und man weiß ja nicht, wieviele Zeilen immer zu löschen sind. Wenn das statistisch nur jede 10. Zeile betrifft, wäre der Aufwand die Mühe nicht wert, weil Mehrfachzeilen viel zu selten vorkommen würden...
Aber schön, dass du das auch so siehst wie ich!

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige