Autor: Peter Haserodt  --- Aus Excel VBA - Gruppe: Tutorials

Performance (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. sm3 (1K)

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) sm3 (1K)
(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 sm3 (1K)
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.


Dieses Thema hat weitere Beiträge

Performance (1) - Vorwort + Schleifen die keiner braucht
Performance (2) - Select Activate Bremsen und ein Beispiel
Performance (3) - Syntax Schnelligkeit
Performance (4) - Frames

Weitere Artikel der Gruppe: Tutorials Aus Excel VBA
Nach oben