同様な処理を繰り返し実行するためにプログラミング言語にはループ処理の機構が用意されています。ここではVBAでループ処理を行う方法を解説します。
Whileのバリエーション
もっとも一般的なループはWhileです。Whileにはいくつかのバリエーションがありますので順に説明します。
条件を満たす間処理を繰り返す(Do While…Loop)
Do While…Loopステートメントは、条件式がTrueの間、処理を繰り返し実施します。条件式がFalseになったらWhileの次のステートメントに制御が移ります。
Do While 条件式
処理
Loop
次のコードは、イミディエイトウィンドに0から4を表示します。
Sub sample()
Dim i As Integer
i = 0
Do While i < 5
Debug.Print i
i = i + 1
Loop
End Sub
条件を満たさない間処理を繰り返す(Do Until…Loop)
Do Until…Loopステートメントは、条件式がFalseの間、処理を繰り返し実施します。条件式がTrueになったらUntilの次のステートメントに制御が移ります。
Do Until 条件式
処理
Loop
次のコードも前述のDo While…Loopステートメントの例と同様、イミディエイトウィンドに0から4を表示します。
Sub sample()
Dim i As Integer
i = 0
Do Until i = 5
Debug.Print i
i = i + 1
Loop
End Sub
少なくとも1回は処理を実行する(Do…Loop While、Do…Loop Until)
Do…Loop WhileとDo…Loop Untilステートメントは処理を実行した後に条件式を評価します。そのため本体の処理は少なくとも1回は実行されます。
Do…Loop Whileステートメントは処理を実行したあと条件式を評価し、Trueであれば処理を繰り返します。
Do
処理
Loop While 条件式
Do…Loop Untilステートメントは処理を実行したあと条件式を評価し、Falseであれば処理を繰り返します。
Do
処理
Loop Until 条件式
次のコードはそれぞれイミディエイトウィンドに0を表示します。
Sub sample()
Dim i As Integer
i = 0
Do
Debug.Print i
Loop While i = 1
Do
Debug.Print i
Loop Until i = 0
End Sub
While、Untileのループから抜ける(Exit Do)
繰り返し処理を実行している途中でループを抜けたい場合があります。例えば特定の条件が成立した場合にループを場合などです。
Forのバリエーション
WhileやUntileループは汎用的に使用できますが、特定の状況ではForループを使用したほうが便利です。ここではVBAで用意されているForのバリエーションを解説します。
指定した回数だけ処理を繰り返す(For…Next)
特定の回数だけ処理を繰り返し実行するにはFor…Nextステートメントを使うのが便利です。
Dim カウンタ変数 [As 数値データ型]
For カウンタ変数 = 初期値 To 最終値 [Step 加算値]
繰り返し実行する処理
next [カウンタ変数]
For…Nextステートメントはカウンタ変数が初期値から最終値(以下)になるまで処理を繰り返します。カウンタ変数には数値型の変数を指定します。
次の例はイミディエイトウィンドウに0から5までを表示します。Step引数を省略するとループを繰り返すたびにカウンタ変数に1が加算されます。
Sub sample()
Dim i As Integer
For i = 0 To 5
Debug.Print i
Next i
End Sub
Step引数には、ループを繰り返すたびにカウンタ変数に加算する値を指定します。次の例は10以下の奇数を表示します。
Sub sample()
Dim i As Integer
For i = 1 To 10 Step 2
Debug.Print i
Next i
End Sub
Step引数には負の値も指定できます。次のコードは5から0をイミディエイトウィンドウに表示します。
Sub sample()
Dim i As Integer
For i = 5 To 0 Step -1
Debug.Print i
Next i
End Sub
配列やコレクションの要素に処理を繰り返す(For Each…Next)
配列やコレクションの要素に対して繰り返す処理を実施する場合は、For Each…Nextステートメントを使います。構文は次の通りです。
Dim 要素を格納する変数 [As データ型]
For 要素を格納する変数 In コレクションまたは配列
繰り返し実行する処理
next [要素を格納する変数]
コレクションをループする場合、要素を格納する変数には、Variant変数、ジェネリックオブジェクト変数、または特定のオブジェクト変数が指定できます。配列の場合はVariant変数だけが指定できます。
次のコードは、「A1:C5」のセル範囲で値が空のセルの背景色を赤色にします。
Sub sample()
Dim r As Range
For Each r In Range("A1:C5")
If r.Value = "" Then
r.Interior.Color = RGB(255, 0, 0)
End If
Next
End Sub
次の例は配列の要素をループする例です。配列の場合、要素を格納する変数はVariant型である必要があります。
Sub sample()
Dim arr(3) As String
Dim elem As Variant
arr(0) = "One"
arr(1) = "Two"
arr(2) = "Three"
For Each elem In arr
Debug.Print elem
Next
End Sub
ループを途中で抜ける
Exitステートメントを使用すると、ループの途中でループから抜けたり、プロシージャを途中で抜けることが出来ます。ループを途中で抜けるにはExitステートメントには次の種類があります。
ステートメント | 説明 |
---|---|
Exit Do | Do…Loopステートメントから抜ける |
Exit For | For…NextまたはFor Each…Nextステートメントから抜ける |
次のコードは無限ループですが、iが10のときにループから抜けます。そのためイミディエイトウィンドウには0から10までが表示されます。
Sub sample()
Dim i As Integer
Do While True
Debug.Print i
If i = 10 Then
Exit Do
End If
i = i + 1
Loop
End Sub
ループを抜けるのではなく、その外側のプロシージャを抜けるExitステートメントもあります。ループの中で使用すれば、結果としてループ処理だけでなく外側のプロシージャの処理も終了することになります。
ステートメント | 説明 |
---|---|
Exit Sub | Subプロシージャを終了する |
Exit Function | Functionプロシージャを終了する |
End | プログラムの実行を終了する |
次のコードは先ほどと同様にイミディエイトウィンドウには0から10までを表示しますが、「Exit Sub」に出会うとSubプロシージャを終了するのでメッセージボックスは決して表示されません。
Sub sample()
Dim i As Integer
Do While True
Debug.Print i
If i = 10 Then
Exit Sub
End If
i = i + 1
Loop
MsgBox "決して表示されない!"
End Sub
次のループを開始する(VBAにcontinueはない)
多くのプログラミング言語には、ループの先頭に戻り次の繰り返しを行うcontinueという機構があります。しかし、VBAにはこのような機構はありません。VBAで同様なことを行うにはGoToが使えます。「GoTo ラベル」を使ってループの末尾までの処理をスキップします。
次のコードはiが2で割り切れたとき、GoToでループの末尾に制御を移します。そのためイミディエイトウィンドウには奇数しか表示されません。
Sub sample()
Dim i As Integer
For i = 1 To 10
If i Mod 2 = 0 Then
GoTo Continue
End If
Debug.Print i
Continue:
Next i
End Sub
まとめ
ループ処理は頻繁に使います。適切なループ処理が選択できるようにそれぞれの特徴を押さえておくとよいでしょう。