DO 〜 Loop文は、繰り返し集計処理をするためのVBA基本コードです。そして、Do ~ Loop文は、繰り返し集計処理を抜けるための条件設定がいくつかあります。本記事では、それらの条件設定について、基本の4パターンとExit Doを使ったパターンについてご紹介します。
Tips
「繰り返し構文」の「For ~ Next」構文
「繰り返し構文」の「For Each ~ Next」構文
目次
VBA繰り返し構文① Do ~ Loop Until ~
最初は「Do ~ Loop Until ~」からです。このパターンは、Until以降に繰り返し処理を抜ける条件を設定します。
Do ~ Loop Until ~ タイプのサンプルコード
では早速ですが、サンプルファイルからSampleSheet01を準備(「SampleSheet02」と「SampleSheet03」は削除してください)したあとに、下図にあるVBAコードを真似て書いてみてくださいね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | Option Explicit 'お店にあるすべての商品の総在庫数をしらべる Sub Sample013() Dim r As Integer '行(Row)方向の繰り返し処理用変数 Dim lngSum As Long '在庫数の合計値を入れる変数 lngSum = 0 '変数を初期化(0にリセット) r = 2 '先頭レコードの行番号 '全レコードに対し繰り返し集計処理 Do lngSum = lngSum + Cells(r, 3) '各レコード3列目の「在庫数」を加算する r = r + 1 '次のレコードを処理するため変数rに1を加える Loop Until r = 17 '行番号17になるまで繰り繰り返し集計処理を実行 MsgBox lngSum End Sub |
次にVBAを実行してみましょう。
いつものようにカーソル位置に注意して、▶ボタンか「F5」キーを押してみてください。下図のように、総在庫数が正しく集計されましたでしょうか。
正解の総在庫数は上図のとおり438ですが、念のためサンプルシートの合計も確認してみてくださいね。
VBAサンプルコード解説
続きまして、VBAコードの詳しい話に移りましょう。
このVBAコードの目的は、商品すべての在庫数の合計を集計することです。ですので、シート上15種類ある果物のそれぞれ3列目の「在庫数」の数字を全部足し合わせれば、合計が出ますよね。
シート上では、オートSUMとか3列目をドラックして簡単に合計を求められますが、コードではどうやっているのでしょうか。ではそのVBAコードを詳しく見ていきましょう。
8行目:Dim lngSum As Long
総在庫数を入れるための変数「lngSum」を宣言しています。このあとにお話しする繰り返し処理によって、各商品の在庫数を1つ1つこの変数に加算してます。
10行目:lngSum = 0
11行目:r = 2
VBAコード10行目は、総在庫数用の変数「lngSum」を0に、VBAコード11行目は、繰り返し処理の最初の処理対象になる先頭レコードの行番号(サンプルワークシートの2行目)をセットしています。
14~20行目:Do ~ Loop Until r =17
この区間で繰り返し集計処理が行われます。今回の場合、変数rの値が最終レコードのあるワークシート行番号16の次の値17に等しくなるまで繰り返し集計処理を行います。
16行目:lngSum = lngSum + Cells(r,3)
18行目:r = r + 1
これらは、Do~Loopで挟まれていますので、繰り返し集計処理される部分になります。今回の場合、繰り返し回数はレコード数分の15回になります。
Do ~ Loop Until ~ 繰り返し集計処理のアルゴリズム
ここからは、Do ~ Lopp処理のアルゴリズムについて、次の図を使って説明しますね。

まず、VBAコード11行目でr=2にセットすることで、ワークシート2行目にある先頭レコードから処理をはじめる指定をしました(図の赤枠)。
つづくVBAコード14~20行目は、繰り返し処理になります。繰り返す回数はレコード数分の15回です。ここで、その繰り返し内容を図のように①と②で分けて考えてみますね。
というのも、今回の例では繰り返し処理を抜ける条件が、最終レコードのあるワークシート行の16ではなく、17であることから少し説明が複雑になるからです。
改めて図を見て頂きますと、Do ~ Loopを囲った青い枠の中央に、細い青線で繰り返し処理を①と②で分けてありますよね。それと、 下にある表は、繰り返し処理(表の行単位)ごとに①と②の変化を表したものです。
この図表を見ながら先頭行から、途中飛ばして最終行までの処理を整理すると、以下のようになります。
r=2(繰り返し処理1回目、先頭レコード)のとき、
- ①で先頭レコードの在庫数が加算される
- ②でrに+1加算されるのでr=3になる
- Loop以降の条件式Until r=17は偽であるため、繰り返し集計処理続行
r=3(繰り返し処理2回目、2番目のレコード)のとき、
- ①で2番目のレコードの在庫数が加算される
- ②でrに+1加算されるのでr=4になる
- Loop以降の条件式Until r=17は偽であるため、繰り返し集計処理続行
とつづき、r=16(繰り返し処理15回目、最終レコード)のとき、
- ①で15番目のレコードの在庫数が加算される
- ②でrに+1加算されるのでr=17になる
- Loop以降の条件式Until r=17は真であるため、繰り返し集計処理を抜ける
以上より、少し複雑でしたが、r=17が繰り返し処理を抜ける条件になる説明でした。
22行目:MsgBox lngSum
Loopを抜けた後の処理になります。この時点で、変数「lngSum」には前の繰り返し集計処理の中で、すべての商品の在庫数の合計値が入っています。これにより、MsgBoxで表示された数字が総在庫数になるということです。
Tips
MsgBox関数の使い方
VBA繰り返し構文② Do ~ Loop While ~
Do ~ Loop While ~ を使って、前出のDo ~ Loop Until ~ と同じ処理をさせたのが次のサンプルコードになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Option Explicit 'Do Loop Whileタイプ Sub Do_LoopWhile() Dim r As Integer '行(Row)方向の繰り返し集計処理用変数 Dim lngSum As Long '在庫数の合計値を入れる変数 lngSum = 0 '変数を初期化(0にリセット) r = 2 '先頭レコードの行番号 '全レコードに対し繰り返し集計処理 Do lngSum = lngSum + Cells(r, 3) '各レコード3列目の「在庫数」を加算する r = r + 1 '次のレコードを処理するため変数rに1を加える Loop While r < 17 '行番号17よりrが小さい値の間は、繰り繰り返し集計処理を実行 MsgBox lngSum End Sub |
変えたのは、VBAコード20行目の「Loop While r<17」の箇所のみです。While以降は繰り返し処理を抜けるための条件判定式になり、「条件式が真を満たす間、処理を繰り返す」という意味になります。
この場合について、具体的に言いますと「rが17よりも小さい値である限り、繰り返し集計処理を実行し続ける」という解釈になります。では、Do ~ Loop Until~の時に用いた図を書き換えて説明しますね。

先ほども述べましたが、前出のDo ~ Loop Until ~のサンプルコードに対して、VBAコード20行目(赤字)を変えただけです。表で見ますと条件式「While r<17」は、最終レコード処理後までは、「真」になっているところも異なります。
そして最終レコード実行後の②では、r=17になりますので「While r<17」は偽になるため、ここで処理を抜けています。
VBA繰り返し構文③ Do Until ~ Loop
Do ~ Loop構文3つ目のパターンは、Do Until ~ Loopです。これは、1つ目でお話しした「Do ~ Loop Until」パターンに対して、条件判定を繰り返し処理の始めに行っているものになります。
コードの中身は、1つ目のパターンの時のサンプルコードに対して、VBAコード20行目にあった「Until r=17」をVBAコード14行目のDo以下に移動しただけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | Option Explicit 'Do Until~Loopタイプ Sub DoUntil_Loop() Dim r As Integer '行(Row)方向の繰り返し集計処理用変数 Dim lngSum As Long '在庫数の合計値を入れる変数 lngSum = 0 '変数を初期化(0にリセット) r = 2 '先頭レコードの行番号 '全レコードに対し繰り返し集計処理 Do Until r = 17 lngSum = lngSum + Cells(r, 3) '各レコード3列目の「在庫数」を加算する r = r + 1 '次のレコードを処理するため変数rに1を加える Loop MsgBox lngSum End Sub |
では、これまでの図を今回のパターン用に書き換えてみましたので、ご覧頂きながらお話をすすめたいと思います。

繰り返し集計処理の始めVBAコード14行目「Do Until r=17」で処理続行か処理を抜けるかの判定をしています。これを踏まえて、先頭レコードからVBAコード上の処理の流れを書いてみます。
r=2(繰り返し処理1回目、先頭レコード)のとき、
- ①の14行目の判定条件は偽になるので、後につづく繰り返し集計処理を実行
- ①の16行目で変数「lngSum」に先頭レコードの在庫数が加算される
- ②でrに+1加算されるのでr=3になる
- Loopのところで、処理はDoがある14行目に戻される
r=3(繰り返し処理2回目、2番目のレコード)のとき、
- ①の14行目の判定条件は偽になるので、後につづく繰り返し集計処理を実行
- ①の16行目で変数「lngSum」に2番目のレコードの在庫数が加算される
- ②でrに+1加算されるのでr=4になる
- Loopのところで、処理はDoがある14行目に戻される
途中同様に繰り返されて、r=16(繰り返し回数15回目、最終レコード)のとき、
- ①の14行目の判定条件は偽になるので、後につづく繰り返し集計処理を実行
- ①の16行目で変数「lngSum」に最終レコードの在庫数が加算される
- ②でrに+1加算されるのでr=17になる
- Loopのところで、処理はDoがある14行目に戻される
この後、r=17になってDoに処理が戻された時には、判定式「Until r=17」は真になるので、ここで繰り返し処理を抜けることになります。そして、処理はVBAコード21行目以降へ移ります。
VBA繰り返し構文④ Do While ~ Loop
ではDo ~ Loop文の4つ目のパターン「Do While ~ Loop」について解説したいと思います。まずは、サンプルコードをご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | Option Explicit 'Do While~Loopタイプ Sub DoWhile_Loop() Dim r As Integer '行(Row)方向の繰り返し集計処理用変数 Dim lngSum As Long '在庫数の合計値を入れる変数 lngSum = 0 '変数を初期化(0にリセット) r = 2 '先頭レコードの行番号 '全レコードに対し繰り返し集計処理 Do While r < 17 lngSum = lngSum + Cells(r, 3) '各レコード3列目の「在庫数」を加算する r = r + 1 '次のレコードを処理するため変数rに1を加える Loop MsgBox lngSum End Sub |
2つ目の「Do ~ Loop While」パターンに対して、VBAコード20行目の「While r <17」をVBAコード14行目に移動しただけの変更になります。
では、ここでも4つ目のパターン用に図を用意しましたので、ご覧頂きながら説明をしたいと思います。

3つ目のパターン「Do Until ~ Loop」と同様、今回のパターンもr=17の後に戻った先のVBAコード14行目の判定式で、今度は条件式を満たさない(偽)ため、繰り返し処理を抜けています。
Exit Do を使って処理を抜ける
最後に、繰り返し処理を抜けるVBAコード「Exit Do」を使ったサンプルコードの説明をしたいとおもいます。では、本記事最後のサンプルコードです。ぜひ真似して書いてから実行してみてくださいね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Option Explicit 'お店にあるすべての商品の総在庫数をしらべる Sub Sample013() Dim r As Integer '行(Row)方向の繰り返し集計処理用変数 Dim lngSum As Long '在庫数の合計値を入れる変数 lngSum = 0 '変数を初期化(0にリセット) r = 2 '先頭レコードの行番号 '全レコードに対し繰り返し集計処理 Do If r <= 16 Then lngSum = lngSum + Cells(r, 3) '各レコード3列目の「在庫数」を加算する r = r + 1 '次のレコードを処理するため変数rに1を加える Else Exit Do '繰り返し処理「Do~Loop」を抜ける End If Loop MsgBox lngSum End Sub |
どうでしょう。実行結果は、前の4パターンとと同じになります。
ところで、今回のサンプルコードには、VBAコード14行目のDoにも、VBAコード24行目のLoopにも繰り返し処理を抜けるための条件設定がありませんよね。このことだけからすると、まさに無限ループのように思えてしまいます。
でもきちんと実行結果が出ていますので、どこかでループを抜けていることになります。
そうです、実はVBAコード21行目の「Exit Do」がこのサンプルコードの繰り返し処理を抜けるためのVBAコードになります。下の図に今回のDo~Loop内部の処理コードを書きだしてみました。

VBAコード16行目の「If r <= 16 Then」の条件判定では、ワークシート行番号が16行以下で「真」になりますので、その間はThen以降の処理を行います。そして、ここの判定式が「偽」の場合(rがワークシート17行目以上)、処理はElse以降となり、このとき「Exit Do」によって繰り返し処理を抜けます。
以上より、Exit Doを使う事でDo~Loop内で多様な処理をさせることができる上、今回のサンプルのように「Exit Do」を使い処理を抜けるることができます。
まとめ
VBAコードの繰り返し構文「Do ~ Loop」文についてご紹介しました。Do ~ Loop文は、4つの基本パターンによる条件判定式を使い、繰り返し処理を抜けます。また4つの基本パターン以外にも、Do~Loop処理内に「Exit Do」を使って処理を抜けることも可能です。
今回ご紹介したDo~Loop文ですが、ポイントとして大切なのは、処理を抜ける条件をしっかりと設定することです。きちんと処理を抜ける条件を設定したつもりでも、実際にはありえない条件の場合、無限ループになり処理が戻らず、最悪はExcelを強制終了させることになりますので気を付けましょう。
Tips:Do ~ Loop文以外のVBA基本構文
For ~ Next文(繰り返し)
For Each ~ Next文(繰り返し)
If文(繰り返し)
Select文(分岐)