Die Community zu .NET und Classic VB.
Menü

Schleifenprogrammierung

 von 

Übersicht 

Da im Forum hin und wieder die Frage nach Schleifen und deren Benutzung auftauchen, soll dieses Mysterium nun einmal in einem Tutorial ausführlich behandelt werden. In diesem kleinen Tutorial werden die unterschiedlichen Schleifentypen, deren Verwendung sowie die einen oder anderen Fallen und Zusatz-Features erklärt.

Was sind Schleifen?  

Einige werden sich fragen was Schleifen überhaupt sind bzw. wozu sie dienen. Anhand von Schleifen ist es möglich Programmanweisungen mehrmals hintereinander zu wiederholen. Man spricht hier häufig auch von Iterationen (lat. iteratio). Man stelle sich einfach mal vor, dass man die Werte von 1 bis 100 hintereinander in eine ListBox schreiben möchte. Hierbei wäre es natürlich sehr mühselig jede Anweisung einzeln wie folgt einzutippen.

List1.AddItem 1
List1.AddItem 2
...
List1.AddItem 100

Viel eleganter und wesentlich kürzer geht das mit Schleifen. Wie man dies macht wird später noch beschrieben. Vorher sollten wir jedoch erst einmal einen kleinen Blick auf die unterschiedlichen Schleifentypen sowie deren Syntax werfen.

Grundsätzlich gibt es drei unschiedliche Typen von Schleifen. Hiervon hebt sich lediglich eine von den anderen beiden ab. Die restlichen zwei sind vom Aufbau her nahezu identisch:

  • Zählergesteuerte Schleifen
  • Schleifen mit vorangestellter Bedingungsprüfung
  • Schleifen mit nachgestellter Bedingungsprüfung

Schleifentypen  

Die zählergesteuerte Schleife

Zu den zählergesteuerten Schleifen zählt lediglich die "For ... To ... Next"-Schleife. Ihre Syntax sieht wie folgendermaßen aus:

For Zaehler = Startwert To Endwert [Step Schrittgroesse]
  'Anweisungen
Next Zaehler

Die Schleife mit vorangestellter Bedingungsprüfung

Zu den Schleifen mit vorangestellter Bedingungsprüfung zählen in VB die "While ... Wend"- sowie die "Do While ... Loop"- bzw. "Do Until ... Loop"-Schleifen. Die Syntax der jeweiligen Schleifen sieht wie folgt aus:

While Bedingung
  'Anweisungen
Wend


Do While Bedingung
  'Anweisungen
Loop


Do Until Bedingung
  'Anweisungen
Loop

Die Schleife mit nachgestellter Bedingungsprüfung

Zu den Schleifen mit nachgestellter Bedingungsprüfung zählt in VB lediglich die "Do ... Loop While"- bzw. "Do ... Loop Until"-Schleife. Die Syntax dieser beiden Varianten sieht folgendermaßen aus:

Do
  'Anweisungen
Loop While Bedingung


Do
  'Anweisungen
Loop Until Bedingung

Einsatz der zählergesteuerten Schleife  

Kommen wir nun mal zu den grundsätzlichen Unterschieden der drei Schleifentypen, und wann sollte man welche Variante am besten einsetzten. Die zählergesteuerte Schleife sollte man immer dann verwenden, wenn im Vornhinein klar ist, wie viele Durchläufe gemacht werden müssen. Diese Durchläufe werden durch den Startwert und den Endwert beschränkt. Um also die zu Anfang erwähnten 100 Werte in die ListBox einzufügen kann man das sehr einfach und effektiv mit folgendem kleinen Bsp.-Code machen:

For i = 1 To 100
  List1.AddItem i
Next i

Das soll allerdings nicht heißen, dass die Schleifen mit voran- bzw. nachgestellter Bedingungsprüfung diese Aufgabe nicht bewerkstelligen können. Auch mit diesen Schleifen ist es möglich die ListBox mit den 100 Werten zu füllen. Allerdings macht das wenig Sinn, da man 1. die genaue Anzahl der Schleifendurchläufe kennt und somit ideal die zählergesteuerte Schleife verwenden kann, und 2. das eigentliche Anwendungsgebiet der anderen beiden Schleifentypen nicht richtig zum Vorschein kommt.

Hier sei noch kurzer Hand erwähnt, dass es mit der zählergesteuerten Schleife ebenfalls möglich ist eine Schrittweite festzulegen. Somit hat man z. B. auch die Möglichkeit nur jeden zweiten Wert in die ListBox zu schreiben. Auch hierzu kurz ein Bsp.:

For i = 1 To 100 Step 2
  List1.AddItem i
Next i

Somit erhalten wir in der ListBox die Einträge "1, 3, 5, 7...99". Mit der Anweisungen Step ist es ebenfalls möglich die Schleife rückwärts zu durchlaufen. Hierfür muss man lediglich einen negativen Wert angeben, sowie den Start- und Endwert tauschen:

For i = 100 To 1 Step -1
  List1.AddItem i
Next i

Somit erhält man in der ListBox die Einträge "100, 99, 98...1".

Update: Änderung der Zählervariablen innerhalb der Schleife

Es ist selbstverständlich auch möglich die Zählervariable innerhalb der Schleife zu manipulieren. D. h. man kann den Durchlauf der zählergesteuerten Schleife, selbst nachdem diese bereits gestartet wurde, noch ändern. Hier zu ein kleines Bsp.:

For i = 1 To 100
  If i > 50 Then
     i = i + 1
  End If

  List1.AddItem i
Next i

Was erhalten wir bei diesem Bsp. für ein Ergebnis? Im Schleifenkopf weisen wir die zählergesteuerte Schleife an von 1 bis 100, also 100 Mal, durchzulaufen. In der Tat läuft die Schleife aber lediglich nur 75 Mal durch. Manche werden sich nun fragen warum?, wo wir doch im Schleifenkopf ausdrücklich angegeben haben, dass die Schleife 100 Mal durchlaufen werden soll.
Des Rätsels Lösung ist einfach: Sobald die Zählervariable einen Wert größer 50 angenommen hat, setzen wir die Zählervariable jeweils noch einmal um eins höher, d.h. wir bekommen in unserer ListBox folgendes Ergebnis: 1, 2, 3...50, 52, 54, 56...100!

Update: Wert der Zählervariablen nach der For...To...Next-Schleife

Ebenfalls interessant zu erfahren ist, welchen Wert die Zählervariable nach Beendigung der Schleife an sich genommen hat. Dazu muss nicht viel gesagt werden, denn die Zählervariable hat immer den Wert des letzten Schleifendurchlaufs addiert mit der jeweils definierten Schrittgröße. Somit ergibt sich für folgendes Bsp.:

For i = 1 To 100 Step 3
  List1.AddItem i
Next i
Der Wert der Zählervariablen beim letzten Schleifendurchlauf ist 100 und hierzu wird dann nochmals die Schrittgröße (in unserem Bsp. "3") hinzuaddiert. Folglich hat die Variable i nach Beendigung der Schleife den Wert 103!

Einsatz der Schleifen mit vorangestellter Bedingungsprüfung  

Bei der Verwendung von Schleifen mit vorangestellter Bedingungsprüfung sollte man grundsätzlich beachten, dass die Bedingung immer erst VORHER geprüft wird, bevor die Anweisungen im Schleifenrumpf ausgeführt werden. Trifft die Bedingung also nicht zu, so werden auch die Anweisungen in der Schleife nicht ausgeführt. Deshalb sollte man bei diesem Schleifentyp vorher immer sicherstellen, dass die Bedingung nicht im Vorfeld schon einen Wert angenommen hat, welcher gleich zu Beginn zum Abbruch der Schleife führt. Hierzu ein paar kleine Bsp.

Beispiel mit While ... Wend:

Erg = ""
While Erg <> "E"
  Erg = InputBox("Bitte Wert eingeben ('E' zum Beenden):")

  If Erg <> "E" Then
    List1.AddItem Erg
  End If
Wend

Beispiel mit Do While ... Loop:

Erg = ""
Do While Erg <> "E"
  Erg = InputBox("Bitte Wert eingeben ('E' zum Beenden):")

  If Erg <> "E" Then
    List1.AddItem Erg
  End If
Loop

Beispiel mit Do Until ... Loop:

Do Until Erg = "E"
  Erg = InputBox("Bitte Wert eingeben ('E' zum Beenden):")

  If Erg <> "E" Then
    List1.AddItem Erg
  End If
Loop

Die obenstehenden Beispiele erwarten jeweils vom Benutzer die Eingabe eines Wertes, welcher dann einer ListBox hinzugefügt wird. Die Eingabe bzw. die Schleifen werden beendet, wenn der Benutzer ein "E" eingibt. Vor jeder Schleife wird die Variable Erg erst einmal gelöscht, um sicher zustellen, dass darin nicht fälschlicherweise bereits ein "E" enthalten sein könnte.

Einsatz der Schleifen mit nachgestellter Bedingungsprüfung  

Bei der Verwendung von Schleifen mit nachgestellter Bedingungsprüfung sollte man grundsätzlich beachten, dass die Bedingung immer erst NACH Ausführung der Anweisungen im Schleifenrumpf geprüft wird. Dies bedeutet somit, dass die Anweisungen in der Schleife mindestens EINMAL ausgeführt werden, bevor eine Bedingungsprüfung stattfindet. Auch hierzu ein kleines Bsp.:

Do
  Erg = InputBox("Bitte Wert eingeben ('E' zum beenden):")

  If Erg <> "E" Then
    List1.AddItem Erg
  End If
Loop While Erg <> E
Die Schleife läuft solange durch, bis vom Benutzer ein "E" eingegeben wird. Es wird also zuerst einmal die Anweisung im Schleifenrumpf ausgeführt und somit ein Wert für die nachstehende Bedingungsprüfung ermittelt. Wichtig! Die Anweisungen in der Schleife werden auf jeden Fall EINMAL ausgeführt.

Unterschiede zwischen Do While...Loop und Do Until .... Loop  

Nicht nur, dass die Do ... Loop-Schleife so wohl als Schleife mit vorangestellter als auch als Schleife mit nachgestellter Bedingungsprüfung benutzt werden kann, gibt es hier noch einen gravierenden Unterschied. Egal ob als Schleife mit vorangestellter oder als Schleife mit nachgestellter Bedingungsprüfung, gibt es bei der Do ... Loop-Schleife einmal die Möglichkeit mit While zu arbeiten, und zum anderen besteht die Möglichkeit mit Until zu arbeiten. Der Unterschied stellt sich gewissermaßen bereits in der deutschen Übersetzung heraus (While = solange, Until = bis). Bei der Schleife mit der While-Klausel werden die Anweisungen also solange ausgeführt SOLANGE eine Bedingung gegeben ist. Bei der Schleife mit der Until-Klausel werden die Anweisungen solange ausgeführt, BIS ein Bedingung gegeben ist. Die beiden Klauseln stehen also im Gegensatz zueinander, folglich sollte man hier bei auch bei der Abfrage mit logischen Operatoren bzw. logischen Verknüpfungen drauf achten. Dies ist eine beliebte Fehlerquelle!

Will man folgende Schleife:

Do While x < 5
  x = x + 1
Loop
umschreiben in eine Until-Klausel, so lautet die Bedingung folgendermaßen:
Do Until x >= 5
  x = x + 1
Loop
Das gleiche Spielchen gilt natürlich auch für die nachgestellte Bedingungsprüfung. Aus:
Do
  x = x + 1
Loop While x < 5
wird:
Do
  x = x + 1
Loop Until x >= 5

Besondere Schleifen  

Außer den herkömmlichen drei Schleifentypen gibt es noch ganz besondere Schleifen, wovon die eine oder andere den Programmierer manchmal regelrecht in den Wahnsinn treiben kann. Die Rede ist hier natürlich von folgenden Schleifen:

  • Schleifen mit Leeranweisungen
  • Endlosschleifen
  • Geschachtelte Schleifen
  • For Each ... In ... Next-Schleife

Schleifen mit Leeranweisungen

So blödsinnig es auch klingen mag, aber es gibt tatsächlich Schleifen mit Leeranweisungen. Das bedeutet, dass innerhalb der Schleife keinerlei Anweisungen stehen. Diese Schleifen wurden in früheren Zeiten oftmals als sogenannte Warteschleifen benutzt. Heutzutage gibt es hierfür allerdings effektivere Möglichkeiten, um seine Programm vorübergehen stillzulegen. Eine Warteschleife sieht demzufolge so aus:

For i = 1 To 10000: Next i
Diese Schleife macht rein überhaupt nix. Außer das Programm anzuhalten, und das nicht mal richtig lange! Bei den Prozessoren mit der heutigen MHz-Leistung sieht es lediglich so aus, als ob diese Zeile in Programmen völlig ignoriert wird. Anbei wird hier kurz auf den Abschnitt "Einfrieren von Programmen" verwiesen.

Endlosschleifen

Das zweite Problem bei der Anwendung von Schleifen gestaltet sich bei den Endlosschleifen. Diese Schleifen werden immer dann fabriziert, wenn eine Bedingung niemals zutreffen kann. Somit hängt man in der Schleife fest und das Programm kommt ebenfalls zum Stillstand (hierbei aber für immer). Meist hilft hier zur noch das Abschissen des Programms. Wie kommen solche Schleifen jedoch zustande? Auch hierfür gibt es ein paar deutlich Beispiele:

For i = 1 To 100
  i = i - 1
Next i
Bei dem obenstehenden Beispiel liegt der Fehler klar auf der Hand. Die Variable i wird im Schleifenkopf als Zähler verwendet und somit bei jedem Durchlauf um eins erhöht. Im Schleifenrumpf jedoch wird dieselbe Variable um eins erniedrigt. Fazit: Der Zähler kann niemals den Endwert 100 erreichen, da er ständig zwischen 0 und 1 hin und her schwankt.

While x < 100
  y = y + 1
Wend
Auch hier sollte der Fehler sofort zu erkennen sein. Entweder hat der Benutzer die Erhöhung der Variable x komplett vergessen mit in die Schleife zu schreiben, oder was der häufigste Grund für diesen Fehler ist, man hat kurzer Hand mal die falsche Variable genommen.

Do
  Erg = InputBox("Bitte Wert eingeben:")
Loop Until Erg < 100 And Erg > 200
Oftmals kann eine Endlosschleife auch durch falsche Verknüpfungen von Bedingungen entstehen. Die Schleife soll solange durchlaufen, bis das Ergebnis kleiner 100 und größer 200 ist. Logischerweise kann der Benutzer keinen Wert eingeben, der einerseits die Bedingung Erg < 100 sowohl auch die Bedingung Erg > 200 erfüllt. Hier kann man auf zweierlei Arten Abhilfe schaffen. Entweder man ändern die Verknüpfung And durch ein Or ab, oder man gestaltet die Bedingungen passend. Dieser Fehler tritt häufig dann auf, wenn man mit der While- bzw. Until nicht aufpasst.

Update: Fehlerquelle "MoveNext" (Datenbank-Kenntnisse erforderlich)

Um den Inhalt dieses Abschnitts richtig verstehen zu können sind ein paar grundlegende Datenbank-Kenntnisse erforderlich. All diejenigen, die noch nie mit Datenbanken gearbeitet haben, sollten sich diesen Abschnitt allerdings auch durchlesen, und sich für die Zukunft vielleicht schon mal diese Fehlerquelle merken.
Gerade ein häufiger Grund für Endlosschleifen im Zusammenhang mit Datenbanken ist das versehentliche weglassen der Methode "MoveNext". Auch hierzu erst einmal ein anschauliches Beispiel:

While Not EOF(rstKunden)
  List1.AddItem rstKunden!Name
Wend
Diese Schleife durchläuft alle Datensätze (rstKunden) und legt den Namen des jeweiligen Kunden in der ListBox ab. Sollte man zumindest meinen, ist aber nicht so! Es wird hierbei lediglich immer der erste Kunde in der ListBox abgelegt, denn die Schleife läuft endlos. Das liegt daran, dass man die Methode "MoveNext" vergessen hat. MoveNext sorgt dafür, wie der Name schon sagt, dass es immer einen Datensatz vorwärts geht. Da man sich allerdings innerhalb der Schleife nicht vorwärts bewegt, wird somit auch das Ende (EOF) der Datensätze niemals erreicht. Der richtige Code müsste also folgendermaßen lauten:
While Not EOF(rstKunden)
  List1.AddItem rstKunden!Name

  rstKunden.MoveNext
Wend
Das gleiche gilt selbstverständlich auch für die Gegen-Methode "MovePrevious". Hierbei bewegt man sich bei den Datensätzen rückwärts bis zum Anfang (BOF). Fehlt diese Methode kommt man dort nie an!

Geschachtelte Schleifen

Bei geschachtelten Schleifen sollte man besonders vorsichtig sein, da sich hier ein Fehler ggf. nicht nur auf eine Schleife sondern auch auf die darin geschachtelte Schleife auswirken kann. Fehler werden somit potenziert, ohne das man das bei der Programmierung merkt. Dies kann eventuell enormen Performance-Verlust bedeuten, besonders wenn man in den Schleifen Anweisungen hat, die dort im Grunde genommen überhaupt nix zu suchen haben. Ein passendes Beispiel wäre der Aufruf einer Funktion. Diese wird bei jedem Schleifendurchlauf erneut aufgerufen, obwohl das ggf. gar nicht gewollt ist. Hierzu ein kleines Bsp. zu unnötigen Funktionsaufrufen (ohne Schachtelung):

For i = 1 To 10
  Erg = Addiere(2 + 3)

  List1.AddItem Erg
Next i
Bei dem obenstehenden Beispiel wird die Funktion addiere bei jedem Schleifendurchlauf erneut ausgeführt, obwohl als Ergebnis immer dasselbe rauskommt. Hier wäre es doch ratsam die Funktion aus der Schleife rauszunehmen: Erg = Addiere(2 + 3)

For i = 1 To 10
  List1.AddItem Erg
Next i
Das zweite Bsp. bewirkt genau das gleich, hat allerdings keine unnötigen Funktionsaufrufe zur Folge. Wie die Performance somit bei verschachtelten Schleifen runtergeht, kann man sich ja wohl denken.
Des weiteren kommt bei geschachtelten Schleifen auf die Schachtelung selbst an. Schachtelung ist nicht gleich Schachtelung, wie uns folgende zwei Bsp. zeigen werden:

Bsp. 1: Eine geschachtelte Do...Loop Until-Schleife in einer For...To...Next-Schleife

For i = 1 To 10
  j = 0

  Do
    List1.AddItem i

    j = j + 1
  Loop Until j = 10
Next i

Bsp. 2: Eine geschachtelte For...To...Next-Schleife in einer Do...Loop Until-Schleife

Do
  For i = 1 To 10
    List1.AddItem i
  Next i

  j = j + 1
Loop Until j = 10

Worin besteht bei den beiden Schleifen-Konstellationen der Unterschied? Bei beiden Varianten werden die Werte 1...10 zehn Mal hintereinander in die ListBox geschrieben. Bei der ersten Version muss man bei jedem Durchlauf der äußeren Schleife sicherstellen, dass die Bedingung für die innere Schleife zurückgesetzt wird. Des weiteren befindet sich der Zähler für die innere Schleife gleichzeitig auch noch in der äußeren Schleife und es muss somit doppelt so oft auf die Variable zugegriffen werden.

Beispiel 2 zeigt eine elegantere Version. Auch hier werden die Werte 1...10 zehn Mal hintereinander in die ListBox eingefügt, doch der Ablauf gestaltet sich hier ein klein wenig anders. Zum einem entfällt hier das Zurücksetzen der Zählervariable für die innere Schleife und zum anderen wird der nur in der äußeren Schleife auf die Variable j zugegriffen und somit ein wenig Zugriffszeit gespart.

Update: Geschachtelte Schleifen und Performance

Als Bedingung kann man bei den drei Schleifen nicht nur fixe Werte bzw. vom Benutzer eingegebene Werte angeben, sondern auch komplexere Ausdrücke. So ist es zum Beispiel möglich als Bedingungsprüfung anstelle von i < 10 z. B. auch i + 1 < 100 / 10 + 1 anzugeben. Logischerweise würde das kein normaler Mensch machen, aber es wäre durchaus möglich. Aber wie verhält sich die Bedingung bei den einzelnen Schleifen? Hier zu erst einmal ein paar kleine Bsp. mit der zählergesteuerten sowie der Schleife mit vorangestellter Bedingungsprüfung:

Bsp. 1: For...To...Next-Schleife

j = 100

For i = 1 To j / 10
  List1.AddItem i

  j = 200
Next i

Bsp. 2: While...Wend-Schleife

i = 1
j = 100

While i <= j / 10
  List1.AddItem i

  i = i + 1
  j = 200
Wend

Analysieren wir nun zunächst einmal Beispiel 1. Im Schleifenkopf weißen wir die Schleife an von 1 bis j / 10 also 100 / 10 und somit 10 Durchgänge zu machen. Innerhalb der Schleife erhöhen wir j auf 200. Somit sollte man eigentlich meinen, dass die Schleife nun nicht mehr 10 Durchgänge hat, sondern j / 10 also jetzt 200 / 10 und somit gleich 20 Durchgänge macht. Dies ist aber ein bedauerlicher Irrtum, denn die Anzahl der Schleifendruchläufe wird nur bei der zählergesteuerten Schleife lediglich ein Mal zu Beginn des ganzen Schleifen-Vorgangs festgelegt. Man kann zwar den Zähler der Schleife innerhalb noch manipulieren, nicht aber die Grenz-Ausdrücke. Diese Regel gilt ebenfalls für die Schrittgröße. Wurde diese einmal festgelegt, lässt sich daran nichts mehr rütteln.

Schauen wir uns nun einmal Beispiel 2 an. Dieses Beispiel soll zu Beginn, genauso wie das erste Beispiel auch, die Werte von 1 bis 10 der ListBox hinzufügen. Auch innerhalb dieser Schleife verändern wir den Ausdruck der Bedingung wieder auf 200 und erhalten somit eine neue Bedingungsprüfung. Der Unterschied zur zählergesteuerten Schleife liegt lediglich darin, dass die Bedingung bei jedem Schleifendurchlauf neu generiert wird. Somit erhalten wir bei diesem Beispiel ein anderes Ergebnis, nämlich die Werte von 1...20 in unserer ListBox. Selbiges gilt auch für die Schleife mit nachgestellter Bedingungsprüfung!

For Each ... In ... Next-Schleife  

Eine besondere Art der For ... To ... Next-Schleife stellt die For Each ... In ... Next-Schleife dar. Mit dieser Variante ist es möglich in einer bestimmten Auflistung jedes Element zu erfassen. Am einfachsten lässt sich das wohl an den Controls einer Form erklären. Angenommen wir haben eine Form mit unterschiedlichen Controls (TextBox, ListBox, CommandButton usw.) darauf. So kann man mir folgendem Bsp. alle Controls der Form durchlaufen und z. B. deren Namen ausgeben lassen:

For Each Ctrl In Me.Controls
  MsgBox Ctrl.Name
Next Ctrl

Die Schleife wird betreten, wenn mindestens ein Element in der angegebenen Gruppe (Me.Controls) vorhanden ist. Sie läuft solange durch, wie Elemente vorhanden sind. Eine weitere Bedeutung gewinnt diese Variante bei der Bearbeitung von Arrays. Hierfür ein Bsp. mit einer normalen For ... To ... Next-Schleife und anschließend die gleiche Version als For Each ... In ... Next-Schleife.

Bsp. mit For ... To ... Next

Dim aTest(1 To 10) As Integer

For i = LBound(aTest) To UBound(aTest)
  aTest(i) = i
Next i

Bsp. mit For Each ... In ... Next

Dim aTest(1 To 10) As Integer

For Each i In aTest
  aTest(i) = i
Next i

Im ersten Bsp. werden mit Hilfe der Funktionen LBound und UBound die untere bzw. die obere Grenze des Arrays abgefragt und anhand dieser Grenzen das Array durchlaufen und gefüllt. Das zweite Bsp. macht sich hierbei einfach das Each zu nutze und benötigt somit keine Arraygrenzen mehr. Es wird einfach jedes Element (beim Array der Index) durchlaufen.

Update: Fehlerquelle bei For Each...In...Next-Schleife

So praktisch diese Variante der zählergesteuerten Schleife auch sein mag, sollte man sie nur mit Vorsicht genießen. Auch hier verbirgt sich eine Fehlerquelle. Wie im Hauptteil dieses Abschnitts bereits erwähnt, kann man mit diese Schleife Auflistungen (engl. Collections) bearbeiten. Aber gerade bei diesen Collections gibt es ein Problem, wenn man daraus mittels einer For Each...In...Next-Schleife Elemente löschen möchte. Der Schleifenkopf wird ein einziges Mal zu Beginn der Schleife initialisiert und erhalt dabei die maximale Anzahl an Elementen in der Collection. Löscht man innerhalb der Schleife ein Element, so verringert sich die maximale Anzahl der Elemente, als Initialisierung der Schleife bleibt jedoch der alte Wert bestehen. Folglich läuft die Schleife über den Maximalwert der Collection hinaus und verursacht einen Fehler. Abhilfe hierfür bietet die Standard-Version der zählergesteuerten Schleife. Auch hier kann dieser Fehler passieren, da auch hier die Initialisierung nur einmal zu Beginn vorgenommen wird. Allerdings hat man hier die Möglichkeit die Auflistung mittels "Step - 1" von hinten nach vorne durchlaufen zukönnen, so dass man am Ende der Liste überhaupt nicht drüber hinaus laufen kann.

Bsp. 1: For Each...In...Next-Schleife mit Fehler

For Each i In List1
  List1.RemoveItem i
Next i

Bsp. 2: For...To...Next-Schleife rückwärts ohne Fehler

For i = List1.ListCount - 1 To 0 Step - 1
  List1.RemoveItem i
Next i

Vorzeitiger Abbruch einer Schleife  

In gewissen Fällen ist es erforderlich eine Schleife vorzeitig zu beenden, noch bevor eine Bedingung für das normale Beenden in Kraft tritt. Dieser Vorgang wird durch das Schlüsselwort Exit eingeleitet. Hieraus ergeben sich folgende Möglichkeiten:

  • Exit For zum Abbruch einer For ... To ... Next- bzw. For Each ... In ... Next-Schleife
  • Exit Do zum Abbruch einer Do While ... Loop-, Do Until ... Loop, Do ... Loop While bzw. Do ... Loop Until-Schleife.

Einzige Ausnahme bildet hier die While ... Wend-Schleife. Für diese gibt es keine Abbruch-Anweisung. Auch hierzu ein kleines Bsp.:

Found = False

For Each Ctrl In Me.Controls
  If Ctrl.Name = "Command1" Then
    Found = True

    Exit For
  End If
Next Ctrl

If Found = True Then
  MsgBox "Control gefunden"
Else
  MsgBox "Control nicht gefunden"
End If

Obiges Beispiel sucht nach einem Control namens "Command1". Falls dieses auf der Form sein sollte, so wird ein Status-Flag gesetzt, dass das gesuchte Control gefunden wurde und die Schleife wird vorzeitig beendet. Der nachfolgende If-Block soll lediglich eine Ausgabe auf dem Bildschirm machen, ob das gesuchte Control gefunden wurde oder nicht.

DoEvents  

Eine extrem wichtige Anweisung, gerade wenn es um Schleifen geht, ist "DoEvents". Diese Anweisung hat im Zusammenhang mit Schleifen eine große Bedeutung und sollte grundsätzlich in jeder Schleife mit verwendet werden. Sobald eine Schleife gestartet wird, wird der Rest vom Programm sozusagen eingefroren, d. h. das Programm reagiert auf keinerlei andere Events mehr. Am einfachsten lässt sich das beim Verschieben der Form feststellen. Sobald eine Schleife durchläuft und der Benutzer die Form an einen andere Stelle des Bildschirms bewegt, passiert erst einmal überhaupt nix. Erst nach Beendigung der Schleife, kann man die Aktion sehen. Setzt man jedoch die "DoEvents"-Anweisung in die Schleife, so wird das Programm dazu veranlasst auch während der Schleifendurchläufe mal nach anderen Aktionen zu schauen und diese ggf. ebenfalls zu berücksichtigen.

i = 0
While i < 100
  DoEvents

  'Restliche Anweisungen

  i = i + 1
Wend

Schlusswort  

Ich hoffe, dass der eine oder andere mit meinem kleinen Tutorial etwas anfangen kann, und dass es verständlich genug beschrieben war. Über Verbesserungsvorschläge bzw. Kritiken in jeder Form würde ich mich freuen.

Gruß
Uwe Jorgel (Flipshot)

Mit moralischer Unterstützung von Dennis Schaaf

Ihre Meinung  

Falls Sie Fragen zu diesem Tutorial haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.