【Excel VBA】WhileやForステートメントで処理を繰り返す

同様な処理を繰り返し実行するためにプログラミング言語にはループ処理の機構が用意されています。ここでは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 DoDo…Loopステートメントから抜ける
Exit ForFor…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 SubSubプロシージャを終了する
Exit FunctionFunctionプロシージャを終了する
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

まとめ

ループ処理は頻繁に使います。適切なループ処理が選択できるようにそれぞれの特徴を押さえておくとよいでしょう。

よかったらシェアしてね!
  • URLをコピーしました!
目次