Autor: Peter Haserodt --- Aus Excel VBA - Gruppe:
TutorialsPerformance (1) - Vorwort + Schleifen die keiner braucht
Autor: Peter Haserodt - Erstellt: -- - Letzte Revision: --Gruppenthema: 4 Folgen 1 2 3 4 Sie sind in Folge:1
Performance - Schnelligkeit - Kein Problem für Excel, aber ...
oder:
Schleifen, die kein Mensch braucht
Der erste Teil hier ist nur mal als Einstieg gedacht und soll auch ein bisserl zum Schmunzeln sein (wenn es nicht so
traurig wäre)
Die Rechner werden immer schneller aber auch die zu bearbeitenden Datenmengen werden immer größer.
Nicht selten hört man Leute klagen, wie langsam Excel oder VBA doch ist.
Tatsächlich sitzt in 99 % aller Fälle die Bremse vor dem Computer.
Undurchdachte Codes, Nichtausnutzung von eingebauten Excelfunktionalitäten, Makrorekorder produzierter Müll und vieles mehr sind mögliche Ursachen für Geschwindigkeitsprobleme.
Mit allem möglichen Unfug wird versucht, die Geschwindigkeit zu erhöhen, anstatt an der Wurzel zu arbeiten.
Erschwert wird für den VBA Einsteiger das ganze aber noch durch völlig perverse Beispiele in manchen Excelbüchern oder in irgendwelchen Artikeln.
Wollen wir uns ein paar solcher negativ Beispiele anschauen.
(Die HorrorBeispiele stammen alle aus einem VBA-Buch eines bekannten VBA Autoren, die er dort durchaus ernst gemeint veröffentlicht hat. Ich nutze dieses Machwerk gerne, wenn ich nach schlechtem Code suche für Beispiele, wie man es nicht machen soll)
(Ich habe die Beispiele zum Teil gekürzt - ohne aber den Sinn zu entstellen - weil es wirklich weh tut, soetwas abzuschreiben)
Fangen wir mit einem wunderschönen Beispiel an:
Hier geht es darum, ausgeblendete Zeilen im aktiven Tabellenblatt wieder einzublenden
Sub ZeilenEinblendenHorror()
Dim zeile As Object
For Each zeile In ActiveSheet.UsedRange.Rows
zeile.Hidden = False
Next zeile
End Sub
Sub ZeilenEinblendenAnders()
ActiveSheet.UsedRange.Rows.Hidden = False
End Sub
Um die beiden Codes in ihrer Geschwindigkeit miteinander zu vergleichen, füllen Sie einfach mal eine Spalte mit möglichst vielen Werten, damit möglichst viele Zeilen im UsedRange sind.
Während Sie die HorrorProzedur dann ausführen, gehen Sie ruhig einen Kaffee trinken.
Hier ist die Performancebremse, dass jede einzelne Zeile angesprochen und ihr hidden Status auf false gesetzt wird.
Dabei stellt mir der UsedRange das Rows Objekt zur Verfügung, mit welchem ich direkt alle Zeilen einblenden kann.
Wenn es nur irgendwie zu vermeiden geht, niemals einzele Objekte ansprechen sondern Objektgruppen.
Das nächste Beispiel zeigt die völllig sinnlose Verwendung einer Schleife, anstatt Excel Bordmittel zu benutzen.
(Dazu kommt noch, dass der Code von der Deklaration her völlig unsinnig ist)
Thema ist es, in einem selektierten Bereich den Durchschnittswert zu berechnen.
Sub DurchSchnittHorror()
Dim Zelle As Range
Dim Avg As Long ' Falsche Deklaration sollte double sein
Dim i As Integer ' falsche Deklaration sollte long sein
Avg = 0 ' Nicht notwendig
i = Selection.Cells.Count ' und ab hier die völlig sinnlose Schleife
For Each Zelle In Selection
Avg = Avg + Zelle.Value
Next Zelle
' Aufgrund falscher Deklaration falsche Ergebnisse (z.B. 3/4 wird zu 1)
Avg = Avg / i
MsgBox Avg
End Sub
Sub DurchschnittAnders()
MsgBox WorksheetFunction.Average(Selection)
End Sub
Das Horrorbeispiel entspricht etwa folgendem Szenario:
Ein Anwender will in Excel von einem Bereich den Durchschnitt ermitteln und ich sage ihm:
Nimm einen Taschenrechner und zähle alle Zellen zusammen. Ermittle die Anzahl der Zellen und teile die Summe dann durch diese ermittelte Zahl.
Anstatt ganz einfach die Funktion Mittelwert zu benutzen.
(Ganz davon abgesehen, dass in dem Beispiel auch fehlerhaft berechnet wird, sobald eine Kommazahl als Durchschnitt herauskommt!)
Zuerst immer prüfen ob nicht eine Excelfunktion die Arbeit für mich erledigen kann.
Dieses ist immer schneller.
Das nächste Beispiel ist mein Favorit.
Hier zeigt sich das völlige Unverständnis für vom Makrorekorder produzierten Code.
Ziel dieses Meisterwerkes ist es, in einem selektierten Bereich Umlaute zu ersetzen (ich habe dies auf ä reduziert)
Sub UmlautHorror()
Dim Zelle As Range
For Each Zelle In Selection
With Selection
.Replace What:="ä", Replacement:="ae", LookAt:=xlPart
End With
Next Zelle
End Sub
Man muss sich dies wirklich in Ruhe zu Gemüte führen.
Hier wird nun eine ganz und gar völlig verblödete Schleife produziert.
Tatsächlich ist die Arbeit schon nach dem ersten Schleifendurchlauf getan
Mit der Anweisung:
With Selection
.Replace What:="ä", Replacement:="ae", LookAt:=xlPart
End With
erledige ich die Ersetzung schon für den ganzen Bereich.
Aber weil es so schön ist, machen wir das halt so oft, soviele Zellen in dem Bereich sind.
Die Schleife kann ich einfach weglassen!
Man sollte seinen Code immer daraufhin überprüfen ob er überhaupt Sinn macht!
Dieser erste Teil soll überhaupt erstmal das Gefühl vermitteln, dass man an Geschwindigkeit arbeiten kann.
Weiterhin soll er aufzeigen, dass ich mit Beispielen, egal woher ich sie beziehe, sehr vorsichtig sein muss.
Traurig in diesem Fall ist aber, dass ein Einsteiger in Excel VBA solchen geschriebenen Mist für bare Münze nimmt und dafür auch noch viel Geld bezahlt.
Wie soll ein Anfänger je das Gefühl für das Excel Objekt bekommen, wenn er schwarz auf weiß lesen muss, wie man es eigentlich nicht macht.
Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben