見出し画像

Excel VBA #3 二重ループを抜ける

二重ループとは、Forステートメントの中に、Forステートメントが入っている状態です。

For i = 1 To 3
    For j = 1 To 7

      '何かの処理
       
    Next j
Next i

この様に、iで回るループの中に、jで回るループが入っている処理で、この場合は,3x7で21回、何かの処理を行うことになります。

jのループの中で処理をしているとき、ある条件の時に「jのループだけを抜けたい」もしくは、「jのループもiのループも抜けたい」というケースがあったとします。
このようなとき、どうコーディングすればいいのかを解説します。

GoToやExit Subは使わない

ループを抜けるならGoToを使ったり、それ以降処理がないなら、Exit Subで処理を終わらせればいいという考え方はだめです。
VBAでGotoステートメントを使うのは、On Errorステートメントだけにし、ForやSelect Caseの中で、Exit Subを使うのも避けましょう。

誤作動を起こす可能性も捨てきれませんし、可読性が下がります。
なにより、コードが美しくありません。


下記の様なデータがあるとします。

図1

各セルの値を2倍する

まずは、二重ループの基本を押さえるために、図1の各セルの値を2倍する処理です。

Dim i As Integer
Dim j As Integer

For i = 1 To 3
    For j = 1 To 7
        Cells(i, j) = Cells(i, j) * 2
    Next j
Next i

外側の i のループが行、内側の j のループが列になっています。
まずはセルA1の値を2倍しセルA1に書込み、次ぎにB1のセルの値を…という順序で処理していきます。

図2

実行すると、図2の様に正しく処理されました。
分かり易いように、値が変化したセルには色付けをしています。

セルの値が25未満の場合にだけ、値を2倍する

次に、セルの値が25未満のときだけ、値を2倍するコードです。

Dim i As Integer
Dim j As Integer

'25未満だけ処理する
For i = 1 To 3
    For j = 1 To 7
        If Cells(i, j) < 25 Then
            Cells(i, j) = Cells(i, j) * 2
        End If
    Next j
Next i

「Cells(i, j) = Cells(i, j) * 2」の処理に、IF文が追加されました。
これを実行すると、図3の様に正しく処理出来ることが分ります。

図3

処理されなかったのは、2行目のC列、D列、3行目のA列~D列とG列です。

25以上の値が出てきたら、その行はそれ以降処理しない

今度は、25以上の値が出てきたら、その行のそれ以降の列は処理しない方法を考えてみましょう。

Dim i As Integer
Dim j As Integer

'25以上の値が出てきたら、その行はそれ以降処理しない
For i = 1 To 3
    For j = 1 To 7
        If Cells(i, j) >= 25 Then
            Exit For
        End If
        
        Cells(i, j) = Cells(i, j) * 2
    Next j
Next i

コードは上記の様になり、結果は図4の様になりました。

図4

1行目では、全ての列が処理され、2行目では、C列が25以上に該当するのでB列まで、3行目は、A列が該当するので、全ての列で処理をしないことが分ります。

コードを見ると、j のループの中にあるIF文で、セルの値が25以上だったら、Exit Forをしています。
Exit Forは、「一番内側のForループを抜ける」という意味なので、j のループを抜けます。
つまり、Next j の次の行に処理が移動します。
次の処理は、Next i なので、iを1つ増やし、3以下なら次の行を処理するということになります。

これが、二重ループの内側のループを抜ける方法です。

25以上の値が出てきたら、その以降全ての行で処理を行わない

最後は、各セルを処理していくなかで、25以上の値があったら、それ以降のセル、行ともに処理を行わない、つまり、全てのループを抜ける処理です。

図1を見ると、1行目は全て2倍の処理をし、2行目のB列まで処理をした後に処理が終わる(全てのループを抜ける)ことが分かります。

そのコードが次になります。

Dim i As Integer
Dim j As Integer
Dim flag As Boolean

'25以上の値が出てきたら、全てのループを抜ける
flag = False
For i = 1 To 3
    For j = 1 To 7
        If Cells(i, j) >= 25 Then
            flag = True
            Exit For
        End If
        
        Cells(i, j) = Cells(i, j) * 2
    Next j
    
    If flag Then
        Exit For
    End If
Next i

実行結果は図5です。

図5

新たにブール型の変数 flag を用意し、処理前に初期値はFalseにしています。

jのループでセルの値が25以上の時、flagにTrueを代入し、Exit Forをします。
jのループが終わるか抜けたら、Next i の前に、「flagの値がTrueだったら、Exit For(iのループを抜ける)」をするようになっています。

変数flagをIntegerにして、0と1で判断するでも構いません。

iのループの中で、jのループがどう終わったのかを判断させることが、このコードのミソです。
基本的なコーディング方法なので、是非覚えて下さい。


このような発想、コードのサンプルをたくさん用意して、初心者の方でも分かり易く解説しています。


いいなと思ったら応援しよう!