仕事がら、他の人が作成したVBAコードをよく見ます。ひと目で「むむ!この人はできるな」と察するコードもありますが、逆のイメージを感じることも少なくありません。ある程度のスキルに達すると、あとはセンスの問題なのかもしれませんが、そうではなく"知らないために損をしている"ケースもあります。ループ(繰り返し処理)から強制的に脱出するテクニックもそのひとつですね。
たとえば次のコードは、セル範囲A1:A1000の中から「合計」と入力されているセルを探しています。「合計」のセルが見つかったら、そのセルを変数Targetに格納して、その後何らかの処理を行うとします。
Sub Sample() Dim i As Long, Target As Range For i = 1 To 1000 If Cells(i, 1) = "合計" Then Set Target = Cells(i, 1) Next i ''この後Targetに対する処理… End Sub
「合計」セルが一つしか存在しないのなら、このコードは正常に動作します。しかし、美しくありません。調べる対象はセル範囲A1:A1000です。もし「合計」セルがセルA2にあったらどうでしょう。変数TargetにはセルA2が格納されますので問題ありませんが、すでに「合計」セルが見つかっているにもかかわらず、セルA3:A1000は無駄に調べられることになります。この場合、「合計」セルが見つかった段階でFor Nextステートメントによるループを終了させるべきでしょう。
For NextステートメントやDo Loopステートメントなどによるループから強制的に抜け出るには、Exitステートメントを使います。
Sub Sample2() Dim i As Long, Target As Range For i = 1 To 1000 If Cells(i, 1) = "合計" Then Set Target = Cells(i, 1) Exit For End If Next i ''この後Targetに対する処理… End Sub
Exitステートメントでループを抜けるには「Exit For」または「Exit Do」と記述します。「Exit For」はFor NextステートメントまたはFor Eachステートメントによるループから脱出し、「Exit Do」はDo Loopステートメントによるループを終了させます。いずれも、それぞれ対応するループ内でしか使用することはできず、実行するとExitステートメントが記述されているループの外側に抜け出ます。
また、Exitステートメントは「Exit Sub」「Exit Function」と書くことで、SubプロシージャやFunctionプロシージャを強制的に終了することもできます。これも覚えておきたいテクニックのひとつです。
Sub Sample2() Dim buf As Long buf = ActiveCell.Value Call myProc(buf) End Sub Sub myProc(buf As Long) If buf < 1 Then MsgBox "1以上の数値を指定してください", vbExclamation Exit Sub End If MsgBox buf * 100 End Sub
上記のサンプルは、Sub Sample2内で変数bufにアクティブセルのデータ(数値と仮定)を格納し、その数値をSub myProcに渡します。Sub myProcでは、受け取った数値を評価して、もし1より小さかったらメッセージを表示して、ただちにプロシージャを終了させます。