プログラミングには必須の処理である繰り返し。
繰り返しの処理の中で特定の条件に当てはまった時に繰り返し処理を抜けたいということはよくあります。
VBAにも繰り返し構文がいくつか用意されていますが、その中でFor文(For i = 1 to 10のような)の3つの抜け方について紹介したいと思います。
Exit Forステートメント
基本的な例
基本的にはこれを使えば解決します。
例を見てみましょう。
Sub ExitForSample1() Dim i As Long Debug.Print "Start ExitForSample" For i = 1 To 10 Debug.Print i If i = 3 Then Debug.Print "Exit Forを実行します。" Exit For End If Next i Debug.Print "End ExitForSample" End Sub
10回の繰り返しのうち、3回目で処理を抜ける例です。
For文の中でExit Forと書くことで強制的にFor文を抜けることができます。
For文がネストされている(複数のFor文の)場合
For文がネストされ、複数のFor文がある場合、Exit Forステートメントだと最も内側のFor文からしか抜けることはできません。
Sub ExitForSampleNest() Dim i As Long Dim j As Long Debug.Print "Start ExitForSampleNest" For i = 1 To 10 For j = 1 To 10 Debug.Print i If i = 1 Then Debug.Print "Exit Forを実行します。" Exit For End If Next j Debug.Print "1つ目のFor終わり" Next i Debug.Print "End ExitForSampleNest" End Sub
For文が複数になっていて、全部のForから抜けたいときは次に紹介するGoToステートメントを使うと良いでしょう。
GoToステートメント
悪魔のGoTo?
GoToステートメントは指定したラベルに一気に処理をスキップする命令です。
古いプログラミング言語では多様されていましたが、前後関係ガン無視で、脈絡なく処理が飛びまくることから悪魔のGoToと呼ばれているとかないとか・・・。バグやループの温床になることが多かったのです。
今時の言語では言語仕様上は実装されているものの、その悪魔の挙動のため、事実上は禁じ手となっていることがほとんどです。
しかし最小限、正しく使えばかなり便利なのは間違いありません。
VBAではエラー処理や今回のようなFor文で処理を抜けるときに使われることがあります。
Gotoを使ってFor文から抜ける例になります。
Sub GotoSample1() Dim i As Long Debug.Print "Start GotoSample1" For i = 1 To 10 Debug.Print i If i = 3 Then Debug.Print "Gotoを実行します。" GoTo EXIT_FOR_LABEL End If Next i EXIT_FOR_LABEL: Debug.Print "End GotoSample1" End Sub
実行すると、EXIT_FOR_LABELへ処理が一気に飛ぶことがわかります。
ネストされていても関係ない
先ほども書いた通り、前後関係をガン無視でラベルまで処理の流れが飛ぶため、いくらネストされていようが、お構いなしにFor文を抜けることができます。
Sub GotoSample2() Dim i As Long Dim j As Long Debug.Print "Start GotoSample2" For i = 1 To 10 For j = 1 To 10 Debug.Print i If i = 3 Then Debug.Print "Gotoを実行します。" GoTo EXIT_FOR_LABEL End If Next j Next i EXIT_FOR_LABEL: Debug.Print "End GotoSample2" End Sub
変数をいじる
これは実用性皆無なのですが、For文の仕様を逆手に取ったような方法になります。
For文は変数の値が指定された値より大きく(または小さく)なるまで繰り返し処理を行います。
変数の値が指定された値を超えると処理が終了するので、処理の途中で変数に大きな値を代入してやるとFor文の最初で変数が指定された値を超えたということで処理が終了します。
変数の値が増えていくパターン
Sub VariableSample1() Dim i As Long Debug.Print "Start VariableSample1" For i = 1 To 10 Debug.Print i If i = 3 Then Debug.Print "変数に最大値より大きい値を代入します" i = 11 End If Next i Debug.Print "End VariableSample1" End Sub
変数の値が減っていくパターン
Sub VariableSample2() Dim i As Long Debug.Print "Start VariableSample2" For i = 10 To 1 Step -1 Debug.Print i If i = 3 Then Debug.Print "変数に最小値より小さい値を代入します" i = 0 End If Next i Debug.Print "End VariableSample2" End Sub
注意点
下記のコードを実行してみてください。
変数 i に11が代入された時点では処理は終わらず、Ifの後の処理が実行されていることがわかります。
Sub VariableSample3() Dim i As Long Debug.Print "Start VariableSample3" For i = 1 To 10 Debug.Print i If i = 3 Then Debug.Print "変数に最大値より大きい値を代入します" i = 11 End If Debug.Print "Ifの後の処理" Next i Debug.Print "End VariableSample3" End Sub
つまり、変数 i の値が評価され、処理を終了するか継続するかは、1回の繰り返しが終わったタイミングで決まります。
そのため、繰り返しをせず、処理を中断したいときはこの手法は使えません。
というかそもそも使うことはないとは思いますが・・・。
終わりに
VBAにおけるFor文の抜け方について紹介しました。
VBAももう少しこのあたりの命令が強化されるといいですが、きっともう変わることは絶対にないのでしょうね。
配られたカードの中でできることをやるしかないですね!!
というわけで、ここまでお読みいただき、ありがとうございました。