Do-Schleifen: Unterschied zwischen den Versionen

Aus VBA-wiki
Zur Navigation springen Zur Suche springen
Keine Bearbeitungszusammenfassung
 
Zeile 1: Zeile 1:
[[Category:vba-wiki]]
== Einfache Do-Schleife ==
== Einfache Do-Schleife ==



Aktuelle Version vom 28. Januar 2023, 00:38 Uhr

Einfache Do-Schleife

Die Do-Schleife ist, wenn keine Abbruchbedingung formuliert wurde (bzw. wenn diese nicht eintrifft) eine Endlosschleife. Das bedeutet, sie wird theoretisch endlos wiederholt (praktisch wird sie vom Betriebssystem beendet ...).

Sub DoLoop()
   
   ' Do Loop ist eine Schleife, bei der nicht bekannt ist, wie oft sie durchlaufen wird
   ' (Vergleiche For Next Schleife)
   
   ' Grundgerüst einer Endlosschleife:
   Do
       ' Code
       Debug.Print Time
   Loop

End Sub

Schleife manuell beenden

Wichtig: Eine Endlosschleife kann, wenn sie ausgeführt wird, verschiedene Probleme verursachen:

  • Sie kann zu Überläufen führen, wenn Zählvariablen ihren Datenbereich verlassen
  • Sie kann die Hauptanwendung (Word, Excel, PowerPoint etc.) einfrieren
  • Sie kann den Rechner einfrieren

Wenn Sie eine Endlosschleife während der Ausführung abbrechen müssen, verwenden Sie die Tastenkombination 'STRG+SHIFT+PAUSE'. Voraussetzung: In der Schleife wird etwas ausgeführt, das einen Abbruch ermöglicht (MsgBox, InputBox, DoEvents).

Sicherer ist es, die Schleife schrittweise zu testen und zu prüfen, ob die Abbruchbedingung auf jeden Fall wie geplant erfüllt wird, bevor man sie 'durchlaufen' lässt.

Kopf- bzw. fußgesteuerte Schleifen

Die Do-Schleife stellt zwei natürliche Möglichkeiten zur Verfügung, die Schleife zu beenden. Diese unterscheiden sich darin, ob die Schleife bei Erfüllung der Bedingung gar nicht erst betreten oder mindestens einmal ausgeführt wird.

Kopfgesteuerte Schleife

Bei einer kopfgesteuerten Schleife erscheint die Bedingung, unter der die Schleife betreten bzw. wiederholt werden soll, gleich am Anfang hinter dem 'Do'.

Somit wird die Schleife unter Umständen erst gar nicht betreten, sondern übersprungen!

Diese Art der Schleife kann man sich auch als If-Abfrage mit Wiederholung vorstellen.

Fußgesteuerte Schleife

Bei einer Fußgesteuerten Schleife wird diese mindestens einmal durchlaufen, bis am Ende der Schleife hinter 'Loop' die Bedingung ausgewertet wird, unter welcher die Schleife wiederholt oder verlassen werden soll.

Das bedeutet, dass diese Schleife mindestens ein Mal durchlaufen wird!

While bzw. Until

Die Do-Schleife kennt zwei Formulierungen einer Abbruchbedingung, welche hinter 'Do' bzw. 'Loop' erscheinen können:

While ('So lange wie')

Hiermit wird angegeben, dass diese Bedingung erfüllt sein soll, um die Schleife (weiter) auszuführen. Ist die Bedingung nicht erfüllt, wird die Schleife nicht wiederholt.

Until ('Bis')

Hiermit wird die Abbruchbedingung der Schleife angegeben. Ist die Bedingung erfüllt, wird die Schleife nicht wiederholt oder erst gar nicht betreten.

Beispiele

Kopfgesteuerte Schleife mit 'While'

Die Schleife wird nur dann betreten bzw. wiederholt, wenn die Bedingung zur Ausführung erfüllt ist.

Sub DoWhileLoop()
    Dim lngRepetitions As Long
       
    Do While MsgBox("Soll die Schleife betreten / wiederholt werden?", vbYesNo) = vbYes
        lngRepetitions = lngRepetitions + 1
    Loop
    MsgBox "Die Schleife wurde " & lngRepetitions & " Mal durchlaufen."
End Sub


Kopfgesteuerte Schleife mit 'Until'

Die Schleife wird nur dann betreten bzw. wiederholt, wenn die Bedingung zur Ausführung nicht erfüllt ist.

Sub DoUntilLoop()
    Dim lngRepetitions As Long
    
    Do Until MsgBox("Soll die Schleife betreten bzw. wiederholt werden?", vbYesNo) = vbNo
        lngRepetitions = lngRepetitions + 1
    Loop
    MsgBox "Die Schleife wurde " & lngRepetitions & " Mal durchlaufen." 
End Sub

Fußgesteuerte Schleife mit 'While'

Die Schleife wird einmal ausgeführt und nur dann wiederholt, wenn die Bedingung zur Wiederholung erfüllt ist.

Sub DoLoopWhile()
    Dim lngRepetitions As Long
    
    Do
        lngRepetitions = lngRepetitions + 1
    Loop While MsgBox("Soll die Schleife wiederholt werden?", vbYesNo) = vbYes
    MsgBox "Die Schleife wurde " & lngRepetitions & " Mal durchlaufen."
End Sub

Fußgesteuerte Schleife mit 'Until'

Die Schleife wird einmal ausgeführt und nur dann wiederholt, wenn die Bedingung zur Wiederholung nicht erfüllt ist.

Sub DoLoopUntil()
    Dim lngRepetitions As Long
   
    Do
        lngRepetitions = lngRepetitions + 1
    Loop Until MsgBox("Soll die Schleife wiederholt werden?", vbYesNo) = vbNo
    MsgBox "Die Schleife wurde " & lngRepetitions & " Mal durchlaufen."
End Sub

Schleife gezielt verlassen mit 'Exit Do'

Mithilfe der 'Exit Do'-Anweisung kann eine Schleife gezielt verlassen werden. Diese Möglichkeit wird insbesondere dann eingesetzt, wenn im Verlauf der Schleife festgestellt wird, dass ein weiteres Ausführen überflüssig ist.

Sub DoExitDo()
   Dim lngContinue As Long
       
   Do
       ' Diverse Arbeitsschritt führen zur folgenden Auswertung
       lngContinue = MsgBox("Soll die Schleife weiter ausgeführt werden?", vbYesNo)
       If lngContinue = vbNo Then
           Exit Do
       End If
       ' Weitere Arbeitsschritte, die ausgeführt werden sollen, wenn die Bedingung erfüllt ist
   Loop
 
End Sub

Das gezielte Verlassen einer Schleife kann ebenfalls in einer kopf- bzw. fußgesteuerten Schleife eingesetzt werden, wenn zum Beispiel innerhalb der Schleife ein weiterer Grund zum Verlassen eintritt.

While-Schleife

Die 'While-Wend-Schleife' ist eine alternative Kurzform des 'Do-While-Loops' und verhält sich identisch:

Sub WhileWend()
    Dim lngRepetitions As Long
    
    While MsgBox("Soll die Schleife betreten / wiederholt werden?", vbYesNo) = vbYes
        lngRepetitions = lngRepetitions + 1
    Wend
    MsgBox "Die Schleife wurde " & lngRepetitions & " Mal durchlaufen." 
End Sub

Beispiele

Dateien in einem Verzeichnis finden

Die 'Dir'-Funktion wird von VBA zur Verfügung gestellt, um die Suche nach Dateien in einem Verzeichnis zu ermöglichen. Sie kann ebenfalls eingesetzt werden, um die Existenz eine Datei zu prüfen.

Die 'Dir'-Funktion verhält sich wie folgt:

  • Bei Angabe eines Pfades immer das schließende Backslash mit angeben (c:\temp\ und nicht nur c:\temp)!
  • Der Rückgabewert ist immer der Name der ersten gefundenen Datei.
  • Wenn das Verzeichnis keine Dateien enthält, wird ein Leerstring zurückgegeben.
  • Beim ersten Aufruf wird der Pfad bzw. der Pfad mit den Suchkriterien angegeben:
Debug.Print Dir("c:\temp\")                ' Erste gefundene Datei oder Leerstring, wenn keine Datei gefunden wurde.
Debug.Print Dir("c:\temp\*.txt")           ' Erste gefundene Text-Datei oder Leerstring, wenn keine Text-Datei gefunden wurde.
  • Daraufhin kann die 'Dir'-Funktion ohne Parameter aufgerufen werden. Dann werden weitere Treffer für die gleichen Suchkriterien zurückgeliefert. Wenn es keine weiteren Treffer gibt, wird ein Leerstring zurückgegeben.

Dies bedeutet folgendes:

  • Eine 'For'-Schleife kommt nicht infrage, denn die Anzahl der gefundenen Dateien ist unbekannt.
  • Eine kopfgesteuerte Schleife wird benötigt, denn das Abbruchkriterium (keine (weitere) Datei gefunden) kann auch schon beim ersten Aufruf eintreten.
Sub FindTextFilesInFolder()
    Dim strPath As String, strFile As String
    
    strPath = "c:\temp\"
    
    strFile = Dir(strPath & "*.txt")          ' Erster Aufruf mit allen Informationen
    Do Until strFile = ""                     ' Leerstring bedeutet: Keine (weitere) Datei gefunden!
        Debug.Print strPath & strFile
        strFile = Dir                         ' Wiederholter Aufruf ohne Parameter
    Loop
End Sub

Wiederholte Benutzereingabe

In einem Dialog sollen Daten eingegeben werden. Der Anwender ruft also erst einmal den Eingabedialog auf, gibt seine Daten ein und kann dann entscheiden, ob er hiermit die Einagbe abschließen oder noch weitere Daten eingeben möchte.

Durch die Aufgabenstellung ergeben sich folgende Überlegungen:

  • Eine 'For'-Schleife kommt nicht infrage, denn die Anzahl der Durchläufe ist nicht bekannt.
  • Eine fußgesteuerte Schleife wird benötigt, denn das Abbruchkriterium (keine weitere Eingabe von Daten) wird erst nach der Eingabe des ersten Datensatzes relevant.
Sub EnterData()
    Dim lngDataCount As Long
    Dim blnRepeat As Boolean
    
    blnRepeat = True
    Do
        If MsgBox("Sie müssen sich vorstellen, dass Sie hier Daten eingeben." & vbNewLine & vbNewLine & _
                  "Soll ein weiterer Datensatz eingegeben werden?", vbYesNo, "Daten eingeben") = vbNo Then
            blnRepeat = False
        End If
        ' Hier würden nun die eingegebenen Daten verarbeitet ...
        If blnRepeat = True Then lngDataCount = lngDataCount + 1
    Loop While blnRepeat = True
    MsgBox "Sie haben " & lngDataCount & " Datensätze eingegeben"
End Sub