VBAにはループの先頭に戻る命令が無い
VBAのループ処理で、途中でループを抜けるExit命令があります。これは他のプログラミング言語にも実装されてある一般的なプログラミング言語の機能です。そして、ループを抜ける機能と対になるのが、ループの先頭に戻る命令です。
ところがなぜかVBAには、ループの先頭に戻る、という命令が言語として実装されていません。
C言語やJava言語を知っている方からすると、「なんでVBAはbreakがあるのにcontinueが無いの?」と当たり前のように不思議に感じると思います。私もそうでした。PythonやJavaScriptもcontinueがありますし、Perlの場合はlastに対するnextですね。
私もループの先頭に戻る命令があればなあ、と本当によく思います。しかし実装されていないものは仕方ないので別の解決方法を考えるしかありません。
ループの先頭に戻る方法は2つ
疑似的にループの先頭に戻る方法は2つの方法があります。
1つはGoToでループの最後に処理を移す方法で、もう1つはループの先頭にIf文を用意する方法です。
1. GoTo文でループの最後のラベルに処理を移す方法(おすすめします)
次ループの条件に一致するかどうかを判定するIf文と、それに対応するラベルを用意します。
こちらでの実装をお勧めします。
一般的なcontinue構文と同様に、continueしたい個所が複数ある場合でも対応できます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub continueTest() Dim i For i = 0 To 5 If i = 1 Then '// CONTINUEラベルに処理を移す GoTo CONTINUE ElseIf i = 3 Then '// CONTINUEラベルに処理を移す GoTo CONTINUE End If '// GoToしない場合はループカウンタが出力される Debug.Print i CONTINUE: '// 次ループ処理を行うためにループの一番最後にラベルを用意する Next End Sub |
2. ループの先頭のIf文で条件判定する方法(おすすめしません)
次ループの条件に一致するかどうかのIf文をループの先頭に配置します。
1 2 3 4 5 6 7 8 9 10 |
Sub continueTest2() Dim i For i = 0 To 5 If i <> 1 Then Debug.Print i End If Next End Sub |
ラベルへのGoToと大きなIf文のどちらがよいか
上の例ではCONTINUEラベルを付けた方がコードが長くなっていますが、他の言語を知っている方だとこちらの方がなじみやすいのではないかと思います。
大きなIf文はどうしてもネスト(インデントによる階層)が深くなってしまいます。
リーダブルコードなどの本にも書いてありますが、一般的には処理を途中で抜けられる場合はその場で抜けた方がよいとされているため、大きなIf文よりもCONTINUEラベルを用意した方がよいと思われます。
たまに、「GoTo=スパゲッティコード」というイメージが強いのかGoToを嫌悪する方がいらっしゃいますが、それはおかしなGoToの使い方をするからおかしくなる話であって、GoToが悪いわけではありませんし、そもそもC言語などのbreakやcontinueもやっていることはルール化されたGoToです。
うまく利用すればいいだけのことだと思います。
“VBAでループのcontinueを疑似的に行う方法” への1件のフィードバック