制御構文とステートメントのDo LoopとFor Each Next は、VBA コード組み立てで、回数を決められないループ処理を行いたい時などに利用します。
こんにちは、じゅんぱ店長(@junpa33)です。
以前の記事でも書いたように、エクセルを使った業務で、「ループの処理」コードは重要な実行処理部分です。
今回は、このもう一つの「ループの処理」である「実行回数が限定されないループ処理」を行うコードについて説明します。
コンテンツ
VBA 回数不定のループ処理はDo LoopとFor Each
ループ処理はコード組み立てで、最も重要な構造です。
文字通りループ処理は同じ計算を何回も行うということですが、
ループを終わる判断(命令)はどうなっているのでしょうか?
もし、その命令が間違っていれば、あの恐ろしい「無限地獄」に陥ってしまう事になります。
「For~Next」は以前に説明しましたが、このステートメントは「いつまで、何回まで」を明記しないと動かない仕組みでした。
今回の「Do Loop」は終了条件としては、「いつまで」ではなく「✖✖の条件に合った時」となります。
ですので、1回でループが終わるかもしれませんし、100回続くかもしれませんし、0回かもしれません。
「永遠に」は最悪ですが、条件の設定が肝になってきます。
Do Loop の使い方には4種類の構文があります。そして
For Each は、ループの回数指定の要らないFor Next 文になります。
説明に進む前に、例題のベースとする内容(プロシージャー)を解説しておきます。
セルA1からJ10まで使います。この100個のセルに1から99までの数字がランダムに表示されます。
セルの抽出条件は「0より大きく70未満」の条件設定を行います。
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
- Int関数についてはこの記事を参考にしてください。
- Rnd関数についてはこの記事を参考にしてください。
条件を満たす間はループする。(While)Do Loop の使い方
While は「条件を満たしている間」という意味です。条件を満たさなくなったときにループを抜け出します。
- 「Activecell」の使い方については、関連記事のこちらを参考にしてください。
- Offsetの使い方についてはこの記事を参考にしてください。
Do While …Loop という構文を使う
この構文の場合は、ループ処理に入っていく前に条件の判断を行います。
セルの抽出条件は「0より大きく70未満」
A列のデータに対してループ処理を行います。
この例題のセルの抽出条件は「0より大きく70未満」となっています。
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
結果を見るとセルA3で値が70より大きくなっていますので、ループから抜け出すことになりました。
Do …Loop Whileという構文を使う
この構文の場合は、ループ処理の後で条件の判断を行います。
セルの抽出条件は「0より大きく70未満」
同じくA列のデータに対してループ処理を行います。
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
この場合の結果は「Do While …Loop」 と 「Do …Loop While」では同じになりました。
違いはなに?
「もしA1の値が53でなく73だったら。」
セルA!の値がいきなり条件式に引っかかってきます。
例題1のパターン「Do While …Loop」の場合は、最初にもう条件を満たしていませんので、0回のループ処理で終了します。
例題2のパターン「Do …Loop While」の場合は、条件の判断は1回ループ処理してからですので、セルA!の値は無視されます。次の条件判断で終了します。
条件を満たされるまではループする。(Until)Do Loop の使い方
Until は「条件を満たされるまで」という意味です。条件が満たされるとループを抜け出します。
Do Until …Loop という構文を使う
この構文の場合は、ループ処理に入っていく前に条件の判断を行います。
セルの抽出条件は「0より大きく70未満」
A列のデータに対してループ処理を行います。
この例題のセルの抽出条件は「0より大きく70未満」となっています。
「Until」は「~するまで」ですので、セルの値が条件を外れるまでということになります。
Sub DoUntil_Loop()
Cells(1, 1).Select
Do Until ActiveCell.Value >= 70
ActiveCell.Interior.ColorIndex = 6
ActiveCell.Offset(1).Select
Loop
End Sub
セルA3で条件を満たしましたのでループ処理を抜け出しました。
Do …Loop Until という構文を使う
この構文の場合は、ループ処理の後で条件の判断を行います。
セルの抽出条件は「0より大きく70未満」
A列のデータに対してループ処理を行います。
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
この場合の結果は「Do Until …Loop」 と 「Do …Loop Until」では同じになりました。
違いはなに?
「もしA1の値が53でなく73だったら。」
前述の「While」の説明と同様ですが、
セルA!の値がいきなり条件式に引っかかってきます。
例題3のパターン「Do Until …Loop」の場合は、最初にもう条件を満たしていませんので、0回のループ処理で終了します。
例題4のパターン「Do …Loop Until」の場合は、条件の判断は1回ループ処理してからですので、セルA!の値は無視されます。次の条件判断で終了します。
入れ子のDo Loop の使い方
Do While …Loop を使った入れ子構造を作る
Whileを使った入れ子を作ります。
条件設定ミスで無限ループにならないように注意が必要です。
このケースは、空白セルにも条件設定を行うようにしましょう。
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
実行結果は、A列からJ列まで、1行目から順に 0<値<70 の範囲内でループ処理を行っていきます。
Do Until …Loop を使った入れ子構造を作る
Untilを使った入れ子を作ります。
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
実行結果は、A列からJ列まで、1行目から順に 値<=0または値>=70 以外の範囲内でループ処理を行っていきます。
ループ回数指定の要らないFor Eachの使い方
回数を指定しないループ処理のステートメントで、Do Loop の他にも、
「For Each …Next 」のステートメントがあります。
「For Each …Next 」ステートメントは、
指定した範囲すべてについてループ処理を実行します。
指定条件を満たした場合のコード処理は、
Do …Loopとは逆に、ループ抜け出しコードを記述する必要があります。
例題として同様にセルの抽出条件は「0より大きく70未満」のセルを黄色に着色します。
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
実行結果として、For Each は範囲内のセル全てについて条件判断を行っていきます。
セルJ10までループ処理を行って終了します。
回数不定のループ処理 Do LoopとFor Eachまとめ
Do Loop は、条件の判断で処理を終了します。
ですので、条件設定の不備があると無限ループというエラーに陥ってしまいます。細心の注意が必要ということです。
コード組み立ての中で、何かの条件に合うものが出てきたときに、
ループから抜け出せるので、その分次の処理に速く入れるということがあります。
処理データ量が多い時は特に有効だと思います。
For Each は、範囲内のすべてを処理をすれば終了します。
処理データ量が多い時は、全て処理完了しないとループを抜けませんので、もたついた処理の感覚になる時があるかもしれません。
自分的には、実際の使用においては、そこまでの大量のデータ量を扱うこともあまりないので、
「For Next」系のループでコード組を行う事が多いかと思います。
(もたつきも体感レベル程度ですので...)
エクセルVBAを独習するのに参考書は欠かせません。 参考書選びは自分に合った「相棒」にできるものを選んでいきたいです。
エクセルVBAの独習でおすすめ参考書を7冊選ぶ。良書との出会いは大切です今回の記事はここまでです。 最後までご覧いただき有難うございました。
<記事内容についての告知>
VBAコードの記述記事においては、その記述には細心の注意をしたつもりですが、掲載のVBAコードは動作を保証するものではりません。 あくまでVBAの情報の一例として掲載しています。 掲載のVBAコードのご使用は、自己責任でご判断ください。 万一データ破損等の損害が発生しても当方では責任は負いません。
アンケートでポイ活しよう!!
アンケートに答えれば答えるほど ”使える” ポイントがたまります。