| Eine der größten Stärken eines Computers ist die Fähigkeit, Anweisungen rasch und oft zu in Schleifen (loops) wiederholen. | Diese Seite demonstriert einige Möglichkeiten, Schleifen mit VBA zu programmieren. |
VBA
|
Visual Basic for Applications - Programm-Fluß-Kontrolle |
| For ... Next | Schleife mit Zähler |
| For Each | Schleife für alle Elemente einer Liste |
| Bedingungen | Schleife mit Bedingung (Allgemein) |
| While ... Wend | Standard-Schleife mit Bedingung |
| Varianten |
Varianten der Schleife mit Bedingung: Do While ... Loop, Do ... Loop While, Do Until ... Loop, Do ... Loop Until Abbruch mit Exit Do |
| OnTime | Zeit-Schleife (z.B. zu jeder Sekunde . . ) |
| GoTo | Schlechte Programmierung . . |
| Verwandte Themen | Bedingte Verzweigungen, Unterprogramme, Arrays |
For ... Next - Schleife mit Zähler |
|
|
Diese Anweisung bewirkt, dass ein Programm-Block mehrfach wiederholt ausgeführt wird. ► Eine ganzzahlige Variable (Integer) wird als Schleifen-Zähler verwendet. Sie wird vor Beginn der Schleife auf einen Anfang-Wert gesetzt und in jedem Schleifen-Durchlauf um +1 erhöht. Die Schleife wird so oft durchlaufen, bis der Zähler den Ende-Wert erreicht hat. ► Optional kann man die Schritt-Weite (Standard +1) auch auf andere ganze Zahlen setzen. Bei negativer Schrittweite wird abwärts gezählt (countdown), in diesem Fall ist der Endwert (meist 0) kleiner als der Anfangswert. ► Innerhalb der Schleife befindet sich der Programm-Block Anweisungen, der in jedem Schleifen-Durchlauf ausgeführt wird. Wenn sich darunter eine Exit For Anweisung befindet, wird die Schleife sofort beendet, auch vor dem Erreichen des Ende-Werts. ► Anweisung Next beendet die Schleife. Danach folgende Anweisungen werden nur einmal ausgeführt. |
For Zähler = Anfang To Ende [Step Schritt]
[Anweisungen]
Next [Zähler]
[Exit For] [Anweisungen] |
|
In diesem (vereinfachten) Beispiel wird eine For-Schleife zur
Berechnung der Faktoriellen-Funktion verwendet.
Dabei werden alle Zahlen 1..n miteinander multipliziert. Für n=1 wird die Schleife 1mal durchlaufen und ergibt faktorielle=1 Für n=2 wird die Schleife 2mal durchlaufen und ergibt faktorielle=2 Wenn man f mit dem Typ Integer anlegt, kann die Funktion maximal bis faktorielle(7)=5040 rechnen, mit dem Typ Long bis faktorielle(12)=479001600 |
Function faktorielle(n)
Dim i As Integer Dim f As Long
f = 1
End Function
For i = 1 To n f = f * i
Next
faktorielle = f
|
Verschachtelte Schleifen:Innerhalb einer Schleife können weitere Schleifen eingesetzt werden. Jede davon muss ihren eigenen Zähler führen. Der Programm-Block des Beispiels besteht aus einer einzigen Zeile, in der beide Schleifen-Zähler (i und j) verwendet werden. Die Schleifen-Anweisungen werden hier 100mal durchlaufen, z.B.Für i=0 und j=5 wird m=5 Für i=3 und j=6 wird m=36 usw. |
For i = 0 To 9
For j = 0 To 9
Next i
m = 10 * i + j
Next j
|
Arrayswerden oft in Schleifen verarbeitet. Das Beispiel füllt die Elemente eines Arrays z mit den Quadraten der Index-Zahlen, z.B. wird z(5)=25 gesetzt usw.♦ Details zu Arrays in VBA |
Dim i As Integer
Dim z(100) As Double For i = 0 To 100 z(i) = i * i
Next i
|
Vorsicht !► Ändern sie niemals den Wert des Schleifen-Zählers durch Programm-Anweisungen (obwohl das von VBA erlaubt wird). Das Ergebnis ist in anderen Programmiersprache unterschiedlich. Sie können den Zähler jedoch problemlos lesen.► Nach dem Ende der Schleife ist der Wert des Schleifen-Zählers in den meisten Programmier-Sprachen (nicht in VBA) unbestimmt. Wenn sie den Wert nachher noch benötigen, sollten sie ihn rechtzeitig an eine andere Variable (hier an j ) zuweisen. |
Sub nixgut()
Dim i, jAs Integer
For i = 0 To 4
End Sub
MsgBox ("i=" & i)
Nexti = i + 1
j = i
' j kann verwendet werden
|
For Each ... Next - Schleife über alle Elemente einer Liste |
|
Lösung mit Standard-MethodenSchleifen werden oft dazu verwendet, alle Bestandteile einer Liste (alle Sub-Elemente eines Objekts) zu durchlaufen. Dazu kann man die Anzahl der Elemente (Eigenschaft Count) ermitteln und in einer 'gewöhnlichen' For-Schleife einsetzen.Im Beispiel wird ein Bereich (Range) an die Function sumrange übergeben, z.B. als Kalkulations-Formel =sumrange(A1:C3) Die Funktion ermittelt die Anzahl der Zellen ( r.Count oder r.CellsCount ) und durchläuft alle Zellen Cells(i) in einer For-Schleife. Dabei werden die enthaltenen Zahlen-Werte (Value) addiert und zurückgegeben. Dieses Beispiel hat nur Demo-Wert, da es das gleiche Ergebnis gibt wie die Standard-Funktion =SUMME(A1:C3) - Es kann allerdings leicht mit dieser Funktion kontrolliert werden. |
Function sumrange(r As Range)
Dim i As Integer Dim s As Double
s = 0
End Function
For i = 1 To r.Cells.Count s = s + r.Cells(i).Value
Nextsumrange = s |
|
VBA bietet für diesen Fall die spezialisierte
Anweisung For Each Vorteil und Nachteil zugleich ist, dass man den Index (die fortlaufende Nummer) der Sub-Elemente nicht kennt / kennen muss: |
For Each Element In Gruppe
[Anweisungen]
Next [Element]
[Exit For] [Anweisungen] |
Lösung mit For EachDas Beispiel ist genauso aufgebaut wie im vorigen Absatz. Die Anweisung For Each weist der Variablen rc bei jedem Durchlauf ein Element der Menge r.Cells zu, d.h. rc symbolisiert je eine Zelle des Bereichs rAnalog kann man alle Arbeitsblätter oder Diagramme eines Kalkulations-Dokuments durchlaufen, alle Befehle eines Menüs, alle Säulen eines Diagramms, usw. usw. |
Function sumrange2(r As Range)
Dim s As Double Dim rc As Range
For Each rc In r.Cells
End Function
s = s + rc.Value
Nextsumrange2 = s |
Vorsicht mit ArraysArrays kann man ebenfalls mit For Each verarbeiten. In diesem Fall kann man die Array-Elemente jedoch nur lesen, nicht schreiben (ändern) !Das Beispiel durchläuft ein Array ia und kopiert (!) in jedem Durchlauf ein Element ia(*) in die Variable i Dabei wird in der Variablen is die Summe aller Elemente berechnet. Auch der zweite Befehl in der Schleife (Erhöhung von i um +1) läuft fehlerfrei, ändert jedoch nur die Variable i und nicht das gerade bearbeitete Array-Element ! ♦ Details zu Arrays in VBA |
Dim i, ia(10), is As Integer
. . . is = 0 For Each i In ia
is = is + i
Next
i = i + 1 |
|
|
|
Schleifen in dieser Form werden von jeder gängigen Programmiersprache angeboten. Daher ist diese Syntax jeder anderen Variante vorzuziehen: Die Prüfung der Bedingung erfolgt in positiver Logik am Anfang jedes Schleifen-Durchgangs. Das bedeutet Ausführung der Anweisungen, wenn (solange) die Bedingung True ist. ♦ Allgemeine Angaben zu Schleifen mit Bedingung |
While Bedingung
[Anweisungen]
Wend
|
|
Beispiel für eine genau 100mal ausgeführte Schleife. Tipp: Vergessen sie bei der Programmierung nicht darauf, den Zähler zu erhöhen, sonst erzeugen sie eine Endlos-Schleife. Setzen sie diese Anweisung entweder als erste (unüblich) oder als letzte Programmzeile (Standard) in die Schleife, niemals 'versteckt' zwischen andere Anweisungen. |
Dim i As Integer
i = 0 While i < 100 'Anweisungen
i = i + 1
|
|
Dieses Beispiel zeigt eine typische Anwendung der While-Schleife.
Die Funktion bits_for berechnet die Anzahl Bits,
welche für die Darstellung einer ganzen Zahl x notwendig sind. Dazu wird die Zahl x so oft halbiert, bis ihr Wert x<=1 ist. Ein Zähler z zählt die Anzahl der Durchläufe und wird als Ergebnis zurückgegeben. MathematikerInnen formulieren lieber bits_for(x) = ceil(ln(x)/ln(2))
aber erstens bietet VBA keine
ceiling-(Aufrunden)-Funktion
und zweitens dauert die Berechnung der Logarithmen für
kleine x länger als ein paar Schleifen . .
|
Function bits_for(x)
Dim z As Integer
z = 0
End Function
While x > 1
x = x / 2
Wendz = z + 1 bits_for = z |
AnimationIn Animationen werden oft bewusst Endlos-Schleifen eingesetzt. Sie werden längere Zeit hindurch ausgeführt, z.B. solange ein Kalkulations-Blatt geöffnet ist.♦ Details zu Animationen in VBA |
Wenn eine Animation interaktiv gesteuert wird, dann muss man sie mit einem Ereignis (event) abschalten, z.B. bei Klick auf eine Stop-Taste. |
Do While .. Loop - Schleife |
|
|
Die Prüfung der Bedingung erfolgt in positiver Logik am
Anfang jedes Schleifen-Durchgangs. Das bedeutet Ausführung der Anweisungen, wenn (solange) die Bedingung True ist. Diese Variante entspricht genau der While-Schleife und wird am besten durch diese ersetzt. ♦ Allgemeine Angaben zu Schleifen mit Bedingung |
Do While {Bedingung]
[Anweisungen]
Loop
[Exit Do] [Anweisungen] |
| Beispiel für eine genau 100mal ausgeführte Schleife |
Dim i As Integer
i = 0 Do While i < 100 'Anweisungen
i = i + 1
|
AbbruchAlle Varianten der Do-Schleife werden abgebrochen, wenn in den Anweisungen der Schleife ein Exit Do enthalten ist. Das ist natürlich nur in einer bedingten Verzweigung sinnvoll:If ... Then Exit Do
|
Alternativ können sie jede Schleife abbrechen, wenn an Stelle der Exit Do Anweisung eine der Schleifen-Bedingungen so geändert wird, dass sie abgebrochen wird. Das mag umständlicher erscheinen, zwingt jedoch zu sauberer Programmierung und lässt sich problemlos in jede andere Programmiersprache übertragen. |
Do .. Loop While - Schleife |
|
|
Die Prüfung der Bedingung erfolgt in positiver Logik am
Ende jedes Schleifen-Durchgangs. Das bedeutet Fortsetzung der Anweisungen, wenn (solange) die Bedingung True ist. ♦ Allgemeine Angaben zu Schleifen mit Bedingung |
Do
[Anweisungen]
Loop While [Bedingung]
[Exit Do] [Anweisungen] |
|
Beispiel für eine genau 100mal ausgeführte Schleife. Vorsicht - Diese Schleife wird in jedem Fall mindestens 1mal ausgeführt, auch dann wenn die Bedingung niemals True ist. |
Dim i As Integer
i = 0 Do 'Anweisungen
i = i + 1
|
Do Until .. Loop - Schleife |
|
|
Die Prüfung der Bedingung erfolgt in umgekehrter Logik am
Anfang jedes Schleifen-Durchgangs. Das bedeutet Ausführung der Anweisungen, wenn (solange) die Bedingung False ist. ♦ Allgemeine Angaben zu Schleifen mit Bedingung |
Do Until [Bedingung]
[Anweisungen]
Loop
[Exit Do] [Anweisungen] |
| Beispiel für eine genau 100mal ausgeführte Schleife |
Dim i As Integer
i = 0 Do Until i >= 100 'Anweisungen
i = i + 1
|
Do Loop .. Until - Schleife |
|
|
Die Prüfung der Bedingung erfolgt in umgekehrter Logik am
Ende jedes Schleifen-Durchgangs. Das bedeutet Fortsetzung der Anweisungen, wenn (solange) die Bedingung False ist. ♦ Allgemeine Angaben zu Schleifen mit Bedingung |
Do
[Anweisungen]
Loop Until [Bedingung]
[Exit Do] [Anweisungen] |
|
Beispiel für eine genau 100mal ausgeführte Schleife. Vorsicht - Diese Schleife wird in jedem Fall mindestens 1mal ausgeführt, auch dann wenn die Bedingung niemals False ist. |
Dim i As Integer
i = 0 Do 'Anweisungen
i = i + 1
|
Zeit - 'Schleife' |
|
|
Wenn sich ein Programm nach einer Wartezeit selbst aufruft, dann wirkt das wie eine
(endlose) Schleife, obwohl es sich um Ereignis-Programmierung handelt. Das Beispiel-Sub wird - einmal gestartet - pro Sekunde einmal ausgeführt. ♦ Details zur Programmierung von Zeit-Ereignissen (events) in VBA. |
Sub jede_sekunde()
' Anweisungen
Application.OnTime Now + TimeValue("00:00:01"),
"jede_sekunde"
|