まずVBAではDo〜Loopで無限ループが実装できます。それに終了条件を追加するのがWhileキーワードです。
VBAで純粋な無限ループとして実装することはほとんど無いですが、2重のForを抜けたりするときなど、限られた場面では使用機会があります。悪名高いGoTo文を使用せずDo〜Loopをテクニカルに使用するイメージです。
目次
- VBAのDo〜Loopを使いこなす
- 1.サンプルコードを書く
- 2.Exit Forステートメント
- Sub sumple() Dim i As Integer Dim j As Integer For i = 1 To 9 For j = 1 To 9 If i > 5 And j > 5 Then Exit For End If Cells(i, j) = i * j Next j Next i End Sub
- Sub sumple() Dim i As Integer Dim j As Integer Dim frg As Boolean For i = 1 To 9 For j = 1 To 9 If i > 5 And j > 5 Then frg = True Exit For End If Cells(i, j) = i * j Next j If frg = True Then Exit For End If Next i End Sub
- 3.Do〜Loopをラベルに
VBAのDo〜Loopを使いこなす
Do〜Loopを単体で使用することは無限ループを実装することになります。「止まらない」マクロになりますので実装する時は必ず「終了条件」をどこかに追加してください。VBAのマクロが止まらなくなった時は「Esc」キーを連打することでVBAを強制停止できます。
1.サンプルコードを書く
今回のサンプルは九九のコードを下敷きにします。なんのことかわからない方は<こちら[25_Forへのリンク]> をどうぞ。
Sub sumple()
Dim i As Integer
Dim j As Integer
For i = 1 To 9
For j = 1 To 9
Cells(i, j) = i * j
Next j
Next i
End Sub
For j = 1 To 9
Cells(i, j) = i * j
Next j
Next i
End Sub
2.Exit Forステートメント
Forの処理を途中で辞めたくなった時はExit Forステートメントを使用します。
Sub sumple()
Dim i As Integer
Dim j As Integer
For i = 1 To 9
For j = 1 To 9
If i > 5 And j > 5 Then
Exit For
End If
Cells(i, j) = i * j
Next j
Next i
End Sub
For j = 1 To 9
If i > 5 And j > 5 Then
Exit For
End If
Cells(i, j) = i * j
Next j
Next i
End Sub
iとjが両方とも5より大きくなったら「Exit For」します。しかし「直近のFor」を抜けることになるので「2個めのFor」を抜けるものとVBAは解釈します。
iとjが5より大きくなった瞬間、九九の表示すべてを取りやめることはExit Forだけの場合、とても冗長なコードを書かなければいけません。
Sub sumple()
Dim i As Integer
Dim j As Integer
Dim frg As Boolean
For i = 1 To 9
For j = 1 To 9
If i > 5 And j > 5 Then
frg = True
Exit For
End If
Cells(i, j) = i * j
Next j
If frg = True Then
Exit For
End If
Next i
End Sub
For j = 1 To 9
If i > 5 And j > 5 Then
frg = True
Exit For
End If
Cells(i, j) = i * j
Next j
Exit For
End If
Next i
End Sub
2回目のForの内部での判定を、外側のForでも引き継いでExitしています。フラグ変数が必要ですし条件判断が増えすぎて冗長です。
問題はForが2重になっていて、Exit Forが「どちらの」Forを抜ければいいか判断できないことです。
3.Do〜Loopをラベルに
前章のようなことが発生した場合GoToメソッドを使うのが簡潔ですが、スパゲッティコードになってしまうことがあります。そのためGoToメソッドを絶対に使わないと決めている人も多いと思います。
そんな時Do〜Loopをラベルとして使うことで、コードの可読性を損なわずGoToメソッドのような柔軟性を実現できます。
Sub sumple()
Dim i As Integer
Dim j As Integer
Do
For i = 1 To 9
For j = 1 To 9
If i > 5 And j > 5 Then
Exit Do
End If
Cells(i, j) = i * j
Next j
Next i
Loop
End Sub
For i = 1 To 9
For j = 1 To 9
If i > 5 And j > 5 Then
Exit Do
End If
Cells(i, j) = i * j
Next j
Next i
Loop
End Sub
今回はExitする対象がDoになったので、1重目のForも一緒に抜けることになります。実行結果はこうなります。
VBAのGoToメソッドは「便利すぎて」濫用することになりかねないため、嫌われているメソッドです。
しかしGoToを使わないと2重目でフラグ変数を用意しなければいけないなど冗長性が増す。という状況の折衷案がこのDo〜Loopです。
これまでVBAでGoToを使っていた人は今度からこちらを使ってください。