VBA 回数不定のループ処理はDo LoopとFor Each

vbadoloopeyecatch

制御構文とステートメントのDo LoopとFor Each Next は、VBA コード組み立てで、回数を決められないループ処理を行いたい時などに利用します。

こんにちは、じゅんぱ店長(@junpa33)です。

以前の記事でも書いたように、エクセルを使った業務で、「ループの処理」コードは重要な実行処理部分です。

今回は、このもう一つの「ループの処理」である「実行回数が限定されないループ処理」を行うコードについて説明します。

VBA 回数不定のループ処理はDo LoopとFor Each

vbadoloopp011

ループ処理はコード組み立てで、最も重要な構造です。

文字通りループ処理は同じ計算を何回も行うということですが、

ループを終わる判断(命令)はどうなっているのでしょうか?

もし、その命令が間違っていれば、あの恐ろしい「無限地獄」に陥ってしまう事になります。

「For~Next」は以前に説明しましたが、このステートメントは「いつまで、何回まで」を明記しないと動かない仕組みでした。

今回の「Do Loop」は終了条件としては、「いつまで」ではなく「✖✖の条件に合った時」となります。

ですので、1回でループが終わるかもしれませんし、100回続くかもしれませんし、0回かもしれません。

「永遠に」は最悪ですが、条件の設定が肝になってきます。

Do Loop の使い方には4種類の構文があります。そして

For Each は、ループの回数指定の要らないFor Next 文になります。

サンプル設定

説明に進む前に、例題のベースとする内容(プロシージャー)を解説しておきます。

セルA1からJ10まで使います。この100個のセルに1から99までの数字がランダムに表示されます。

セルの抽出条件は「0より大きく70未満」の条件設定を行います。

VBA
Option Explicit

Sub ループテスト()
    Dim N, x, y As Integer
        For x = 1 To 10
            For y = 1 To 10
                N = Int(Rnd * 100)
                Cells(x, y).Value = N
            Next y
        Next x
End Sub
vbadoloop001

参考記事

  • Int関数についてはこの記事を参考にしてください。
vbaintfixeyecatch Int・Fix・Abs・Sign関数で数値の整数部分を完全分離
  • Rnd関数についてはこの記事を参考にしてください。
vbarndeyecatch Rnd関数で乱数を取得。デフォルトでは使えない戻り値の加工

条件を満たす間はループする。(While)Do Loop の使い方

While は「条件を満たしている間」という意味です。条件を満たさなくなったときにループを抜け出します。

参考記事

  • 「Activecell」の使い方については、関連記事のこちらを参考にしてください。
vbanameeyecatch 新規作成ブックとシート。アクティブ状態でやっておくこと
  • Offsetの使い方についてはこの記事を参考にしてください。
vbaoffseteyecatch Offsetプロパティは指定範囲を移動させる

Do While …Loop という構文を使う

この構文の場合は、ループ処理に入っていく前に条件の判断を行います。

セルの抽出条件は「0より大きく70未満」

A列のデータに対してループ処理を行います。

例題1.Do While …Loop

この例題のセルの抽出条件は「0より大きく70未満」となっています。

VBA
Sub DoWhile_Loop()
        Cells(1, 1).Select
        Do While ActiveCell.Value > 0 And ActiveCell.Value < 70
            ActiveCell.Interior.ColorIndex = 6
            ActiveCell.Offset(1).Select
        Loop
End Sub
vbadoloop002

結果を見るとセルA3で値が70より大きくなっていますので、ループから抜け出すことになりました。

Do …Loop Whileという構文を使う

この構文の場合は、ループ処理の後で条件の判断を行います。

セルの抽出条件は「0より大きく70未満」

同じくA列のデータに対してループ処理を行います。

例題2.Do …Loop While
VBA
Sub Do_WhileLoop()
        Cells(1, 1).Select
        Do
            ActiveCell.Interior.ColorIndex = 6
            ActiveCell.Offset(1).Select
        Loop While ActiveCell.Value > 0 And ActiveCell < 70
End Sub
vbadoloop003

この場合の結果は「Do While …Loop」 と 「Do …Loop While」では同じになりました。

違いはなに?

「もしA1の値が53でなく73だったら。」

セルA!の値がいきなり条件式に引っかかってきます。

例題1のパターン「Do While …Loop」の場合は、最初にもう条件を満たしていませんので、0回のループ処理で終了します。

vbadoloop004

例題2のパターン「Do …Loop While」の場合は、条件の判断は1回ループ処理してからですので、セルA!の値は無視されます。次の条件判断で終了します。

vbadoloop005

条件を満たされるまではループする。(Until)Do Loop の使い方

Until は「条件を満たされるまで」という意味です。条件が満たされるとループを抜け出します。

Do Until …Loop という構文を使う

この構文の場合は、ループ処理に入っていく前に条件の判断を行います。

セルの抽出条件は「0より大きく70未満」

A列のデータに対してループ処理を行います。

例題3.Do Until …Loop

この例題のセルの抽出条件は「0より大きく70未満」となっています。

「Until」は「~するまで」ですので、セルの値が条件を外れるまでということになります。

VBA
Sub DoUntil_Loop()
        Cells(1, 1).Select
        Do Until ActiveCell.Value >= 70
            ActiveCell.Interior.ColorIndex = 6
            ActiveCell.Offset(1).Select
        Loop
End Sub
vbadoloop006

セルA3で条件を満たしましたのでループ処理を抜け出しました。

Do …Loop Until という構文を使う

この構文の場合は、ループ処理の後で条件の判断を行います。

セルの抽出条件は「0より大きく70未満」

A列のデータに対してループ処理を行います。

例題4.Do …Loop Until
VBA
Sub Do_LoopUntil()
        Cells(1, 1).Select
        Do
            ActiveCell.Interior.ColorIndex = 6
            ActiveCell.Offset(1).Select
        Loop Until ActiveCell.Value <= 0 Or ActiveCell >= 70
End Sub
vbadoloop007

この場合の結果は「Do Until …Loop」 と 「Do …Loop Until」では同じになりました。

違いはなに?

「もしA1の値が53でなく73だったら。」

前述の「While」の説明と同様ですが、

セルA!の値がいきなり条件式に引っかかってきます。

例題3のパターン「Do Until …Loop」の場合は、最初にもう条件を満たしていませんので、0回のループ処理で終了します。

vbadoloop004

例題4のパターン「Do …Loop Until」の場合は、条件の判断は1回ループ処理してからですので、セルA!の値は無視されます。次の条件判断で終了します。

vbadoloop005

入れ子のDo Loop の使い方

Do While …Loop を使った入れ子構造を作る

Whileを使った入れ子を作ります。

条件設定ミスで無限ループにならないように注意が必要です。

このケースは、空白セルにも条件設定を行うようにしましょう。

例題5.Do While …Loop入れ子
VBA
Sub DoWhile_Loop入れ子()
    Dim y As Integer
        y = 1
        Do While y < 11
            Cells(1, y).Select
            Do While ActiveCell.Value > 0 And ActiveCell.Value < 70
                ActiveCell.Interior.ColorIndex = 6
                ActiveCell.Offset(1).Select
            Loop
            y = y + 1
        Loop
End Sub
vbadoloop008

実行結果は、A列からJ列まで、1行目から順に 0<値<70 の範囲内でループ処理を行っていきます。

Do Until …Loop を使った入れ子構造を作る

Untilを使った入れ子を作ります。

例題6.Do Until …Loop入れ子
VBA
Sub DoUntil入れ子()
    Dim y As Integer
        y = 1
        Do While y < 11
            Cells(1, y).Select
            Do Until ActiveCell.Value <= 0 Or ActiveCell.Value >= 70
                ActiveCell.Interior.ColorIndex = 6
                ActiveCell.Offset(1).Select
            Loop
            y = y + 1
        Loop
End Sub
vbadoloop008

実行結果は、A列からJ列まで、1行目から順に 値<=0または値>=70 以外の範囲内でループ処理を行っていきます。

ループ回数指定の要らないFor Eachの使い方

回数を指定しないループ処理のステートメントで、Do Loop の他にも、

「For Each …Next 」のステートメントがあります。

「For Each …Next 」ステートメントは、

指定した範囲すべてについてループ処理を実行します。

指定条件を満たした場合のコード処理は、

Do …Loopとは逆に、ループ抜け出しコードを記述する必要があります。

例題として同様にセルの抽出条件は「0より大きく70未満」のセルを黄色に着色します。

例題7.For Each …Next
VBA
Sub ForEach()
    Dim MyRange As Range
        For Each MyRange In Range("A1:J10")
            If MyRange.Value > 0 And MyRange.Value < 70 Then
                MyRange.Interior.ColorIndex = 6
            End If
        Next MyRange
End Sub
vbadoloop010

実行結果として、For Each は範囲内のセル全てについて条件判断を行っていきます。

セルJ10までループ処理を行って終了します。

回数不定のループ処理 Do LoopとFor Eachまとめ

vbadoloopp012

Do Loop は、条件の判断で処理を終了します。

ですので、条件設定の不備があると無限ループというエラーに陥ってしまいます。細心の注意が必要ということです。

コード組み立ての中で、何かの条件に合うものが出てきたときに、

ループから抜け出せるので、その分次の処理に速く入れるということがあります。

処理データ量が多い時は特に有効だと思います。

For Each は、範囲内のすべてを処理をすれば終了します。

処理データ量が多い時は、全て処理完了しないとループを抜けませんので、もたついた処理の感覚になる時があるかもしれません。

自分的には、実際の使用においては、そこまでの大量のデータ量を扱うこともあまりないので、

「For Next」系のループでコード組を行う事が多いかと思います。

(もたつきも体感レベル程度ですので...)

エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。

vbastudyeyecatch2 エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です

今回の記事はここまでです。   最後までご覧いただき有難うございました。

エクセルVBA最速理解で必要な知識を集めよう!

エクセルVBA業務ツールで日常の業務改善を行いましょう。

<記事内容についての告知>VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。