多重ループからの脱出

たまに、多重ループから抜けたいとき、「どうだっけ?」と迷うことがある。
f:id:Infoment:20200620223751p:plain

例えば、こんなとき。

Sub Test()
    Dim i As Variant
    Dim j As Variant
        For Each i In Array(1, 2, 3)
            For Each j In Array("一", "二", "三")
                If j = "三" Then
                    Exit For
                Else
                    Debug.Print i & j
                End If
            Next
        Next
End Sub

j が「三」ならループを抜けるわけだが、果たして外側のループまで抜けてしまうのか。結果は以下のとおり、抜けるのはあくまで内側のループだけ。
f:id:Infoment:20200620224819p:plain

もし外側まで抜けていたなら、このような結果になる。
f:id:Infoment:20200620224952p:plain


 
ちなみに、一気に外側まで抜ける方法は、私の知る限り三つ。

1.ラベル行まで一気に抜ける

以下の例では、多重ループの外にラベル行(Continue:)へ処理を移動。

Sub Test()
    Dim i As Variant
    Dim j As Variant
        For Each i In Array(1, 2, 3)
            For Each j In Array("一", "二", "三")
                If j = "三" Then
                    GoTo Continue:
                Else
                    Debug.Print i & j
                End If
            Next
        Next
        
Continue:
End Sub

たまにお見掛けするが、個人的には殆ど使用したことが無い(好みの問題)。

2.フラグを使用

内側のループを抜ける際にフラグを立て、更にフラグが立って(=True)いれば、外側のループを抜ける。

Sub Test()
    Dim i As Variant
    Dim j As Variant
    Dim Flag As Boolean
        For Each i In Array(1, 2, 3)
            For Each j In Array("一", "二", "三")
                If j = "三" Then
                    Flag = True
                    Exit For
                Else
                    Debug.Print i & j
                End If
            Next
            If Flag Then Exit For
        Next
End Sub

どちらかと言えば、先の例よりこちらを使う場合が多い。ただし、変数が一つ増えるのが難点。

3.プロシージャ自体を終了

その場で処理を終えて良い場合のみ使用可能なため、用法としては限定的。

Sub Test()
    Dim i As Variant
    Dim j As Variant
        For Each i In Array(1, 2, 3)
            For Each j In Array("一", "二", "三")
                If j = "三" Then
                    Exit Sub
                Else
                    Debug.Print i & j
                End If
            Next
        Next
End Sub

終わりに

個人的に常用するのは、二重ループまでかな。内側のループをユーザー定義関数化するなどして、三重ループ以上は極力避けたいところ。

なぜなら、そうでないと、私の頭では理解が追い付かなくなるので。

参考まで。