こんにちは! Excel講師の榊裕次郎です。
この記事では、Excel VBAのDo ~ Loopステートメントについて、絶対に理解できるよう解説します。
Excel VBAの講座でも、For ~ Nextステートメントは処理の流れがわかりやすいのですが、このステートメントは4パターン存在するため、初見だとハードルの高いステートメントです。
1パターンずつイメージしながらマスターしていきましょう!
はじめに
Do ~ Loop ステートメントは「Until」「While」の付く位置が前後するため、4パターンあります。
- Do Until 〜 Loop
- Do 〜 Loop Until
- Do While 〜 Loop
- Do 〜 Loop While
まず用語の確認です。
「Until」は、条件を満たす「まで」ループします。
「While」は、条件を満たす「あいだ」ループします。
ニュアンス的にはどちらも同じような結果になりそうですね。
Untilの場合は、コップの水がいっぱいになるまで水を入れ続ける! という処理のイメージです。コップに水がいっぱいになったら、蛇口の栓を閉じて処理は終了します。
Whileの場合は、コップに水が注がれているあいだは処理を続ける! というイメージです。コップの水が1滴でもこぼれたら、作業している処理は終了です。
つまり……。
Untilを使うときは、お風呂で10まで数えたら出る! というような、到達点があるプログラムに使います。
Whileを使うときは、砂時計が落ちているあいだは筋トレを続ける! というような、処理時間の制約を設けるプログラムに使います。
ステートメントの勉強の前に、日常の風景を思い描いて、UntilとWhileの事例を作ってみてイメージしてみてください!
まずは、Untilから解説していきましょう。
1. Do Until 〜 Loop ステートメント
セルA1からA10まで連番を振るプロシージャは、以下のようになります。
Sub example1()
Dim i As Long
i = 0
Do Until i = 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
最初に、カウンタ変数 i を「0」に初期化します。
For ~ Next ステートメントでは初期化は不要と記載しましたが、Do ~ Loop ステートメントはすべてカウンタ変数の初期化が必要です。
このステートメントでは、繰り返し処理に入る前に、カウンタ変数 i が「10」かどうか? という審査があります。
カウンタ変数は「0」なので、ループ処理の中に入ることができます。
Loop で Do に戻り、i = 10 のチェックを行います。カウンタ変数「i」が「10」になって条件が満たされたら、処理は Loop の下に飛んでループを抜けます。
Sub example1()
Dim i As Long
i = 0
Do Until i = 10 ← ★① i が10になった!
i = i + 1
Cells(i, 1).Value = i
Loop
★② ループを抜ける。
End Sub
では、次の場合はどうでしょう?
' このコードはフリーズする恐れがあります。
Sub example2()
Dim i As Long
i = 11
Do Until i = 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
このプロシージャは、カウンタ変数 i が永遠に「10」を満たさなくなるので、Excelはフリーズしてしまいます(一応1,048,576行までいって終了しますが、マシンによってはExcel動かなくなるので、コピペして試す場合はご注意ください)。
お風呂のカウントだったら永遠に湯船から出られないので、茹で上がっちゃいますよね。
安全に記載するとしたら、
Sub example3()
Dim i As Long
i = 0
Do Until i >= 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
カウンタ変数 i は10まで、それ以上になってももちろん終了、といった書き方のほうが安心です。
Untilは到達点を目指して! というイメージですが、到達点以上という書き方にしたほうが、Excelに安心・安全な命令を出すことができます。
なので、10までという条件を付けるのであれば、10以上と記載するようにしてください。
2. Do ~ Loop Until ステートメント
この「Until」をおしりに移動すると、最初の審査がない状態でループ処理に入り込みます。
まず、Untilが先にある場合、以下の処理だとセルには何もデータが入力されません。
' カウンタ変数が既に10以上なので、繰り返し処理に入れない
Sub example4()
Dim i As Long
i = 10
Do Until i >= 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
' カウンタ変数が既に10以上だけど、繰り返し処理に入る。そしてUntilの条件に到達後、抜ける
Sub example5()
Dim i As Long
i = 10
Do
i = i + 1
Cells(i, 1).Value = i
Loop Until i >= 10
End Sub
カウンタ変数が「10」でも、初回のループ処理は実行されます。
前と後ろは、この違いがあるんですね。
3. Do While ~ Loop ステートメント
続いて「While」です。以下のプロシージャをご覧ください。
Sub example6()
Dim i As Long
i = 0
Do While i = 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
Whileは、この間は処理を続ける、という書き方となります。
つまり、上記のように等号(=)を使ってしまうと、i=10のあいだのみ、ということは、10のときのみ、となりますので、カウンタ変数が10のとき以外は処理されない、ということになります。
カウンタ変数 i は「0」なので、処理はされません。
それでは、~のあいだという表現はどのような符号をつければいいでしょうか?
それは、このようにします。
Sub example7()
Dim i As Long
i = 0
Do While i < 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
カウンタ変数「i」は10より小さいあいだは処理をする、という意味になります。
これで処理の幅を設けることができました。
さて、Untilのプロシージャと比べてみてください。
【Until】
Sub example3()
Dim i As Long
i = 0
Do Until i >= 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
【While】
Sub example7()
Dim i As Long
i = 0
Do While i < 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
Untilのときに10になるまで、で >= を使ったのに対し、Whileはその反対方向の < のみとなります。なので、どっちでも同じ結果を出すことができるんですね。
セルA1からA10まで連番を格納するこの処理、結果は同じになりますが、
- 【Until】セルのデータが10になるまで、ループ処理を行う
- 【While】セルのデータが10になるあいだ、ループ処理を続ける
プログラムの処理が、到達点を目指す処理なのか? それとも処理時間の幅を設けた処理なのか? どっちのイメージの処理になるかで、UntilとWhileを使い分けてくださいね!
Do ~ Loop While ステートメント
最後です。
Sub example8()
Dim i As Long
i = 10
Do While i < 10
i = i + 1
Cells(i, 1).Value = i
Loop
End Sub
Until同様、ループ処理に入る前の審査があります。この場合、条件を満たさないのでループ内には入れません。
Sub example9()
Dim i As Long
i = 10
Do
i = i + 1
Cells(i, 1).Value = i
Loop While i < 10
End Sub
ループ処理の中に条件なしで入れます。なので、セルA11に「11」の入力がなされて、ループ処理を抜けて完了となります。
ループに入る審査をするかしないか? これはUntilと同様の意味となります。
まとめ
以上、Do Loop ステートメント4種類でした!
For ~ Next ステートメントに続いて、Do ~ Loop ステートメント、Excel VBA の講座では、ここの箇所を教えるとおおかたの受講生は混乱します。
この場合、どっちを使えばいいの? と悩むことでしょう。
ぶっちゃけ、Until でも Whileでも、符号をしっかりつければどっちも結果は一緒です。また、For ~ Next ステートメントでも同じことが書けるため、もしかしたら使う機会がないかもしれません。
ただ、きちんとプログラムを書いてExcelに伝える! ということが何よりも重要なので、いまの処理は単なる繰り返し(For Next)なのか、目標地点に向かうためのループ処理(Until)なのか、それとも制限時間内に行うループ処理(While)なのか、実際にコードを書いたら日本語訳をして、腑に落ちる説明となるか確認してみてくださいね。
以上、Do Loop ステートメントでした!