この記事では、VBAのWhileステートメントの概要と使い方を実際のVBAコードも含めて紹介します。
プログラミングの3大要素にも「反復(くり返し)」があるように、ある条件に基づいて処理を繰り返すのは、VBAでも頻出する動作のひとつです。
Whileステートメントは設定されたくり返しの条件を判定し、条件に該当する間は同じ処理をループさせることができます。
VBA(プログラミング)の中でも、くり返し処理の構文は習得必須の内容です。
早速、Whileステートメントの概要と実際のVBAコードを見ていきましょう。
この記事で紹介するWhileステートメントは設定した条件に該当する間、処理をくり返すという動きをしますが、主に2通りの動作があります。
それは「設定した条件」を判定するタイミングです。論点は処理を実行する中で、1度目(最初)の処理が実行されるかどうかです。
上記が前判定と後判定のイメージ図です。何となく分かっても、具体的なイメージはつきにくいかと思いますので、次の例を考えてみてください。
ある条件判定が「18歳以上か」という内容になっていた場合、「前判定」の場合には18歳以上という条件に該当しない限り処理が実行されることはありません。処理の前に必ず条件判定が存在するからです。
一方、「後判定」の場合には18歳以上という条件に該当しなくても1度目(最初)の処理は実行されてしまいます。このフローはくり返しを想定しているため、条件判定もくり返されるのですが、1度目(最初)に限っては、条件判定よりも前に処理が実行されるからです。
この記事で紹介するWhileステートメントは「前判定」と「後判定」の性質を、構文により使いわけることができます。
「前判定」の場合は、[Do While・・Loop]を使い、「後判定」の場合には、[Do・・・Loop While]を使います。要は条件判定を前に書くか、後に書くか、です。
まずは、使用頻度の高い「Do While・・・LOOP」のWhileステートメントから説明します。前章で説明した中で、「前判定」の動作をするWhileステートメントです。
Do While 条件
・・・
LOOP
この実例で紹介するサンプル処理です。
下記のように、ExcelのA列に値が入力されており、「値があれば文字色を赤色にする」という処理をWhileステートメントを使って記述します。処理は、セルが空白になるまでくり返すものとします。
[実例VBAコード(Do While・・Loop)]
Sub Sample()
Dim Count As Long
Count = 1
Do While Range("A" & Count) <> ""
Range("A" & Count).Font.ColorIndex = 3
Count = Count + 1
Loop
MsgBox Count - 1 & "行目まで処理を行いました"
End Sub
Do While・・Loopステートメントでは、処理の最初であるDo Whileステートメントを記述した直後に、処理をくり返す(実行する)条件を設定します。
上記の例では、6行目の「Do While Range(“A” & Count) <> “”」ですね。ここで、セルが空欄ではないという条件を設定しています。
セルが空欄でなければ、セルの文字色を赤色にするプロパティが実行されます。9行目のLoopの後、再度、6行目の条件判定を行い、条件に該当する間、この範囲の処理がくり返されます。
最後は、実際に何行目(何カウント)まで処理が行われたのか確認するため、MsgBox関数を使っています。
上記のVBAコードを実行するとExcelは下記のようになります。
メッセージボックスは「7行目まで」となっており、VBAコード内で8行目までカウントされたあとDo Whileに戻り、設定された条件に該当しなかったため、8度目の処理は行われずに処理が完了したことが分かります。
この章で説明した、Do While・・・Loopと同じ動きをする「While・・・Wend」という構文もあります。
Do WhileをWhileに、LoopをWendに置き換えるだけでどちらを使っても構いませんが、「While・・・Wend」にはループを抜ける処理がありませんので、使用するメリットもありません。(Exit Doが使えません)
参考程度にしてください。
[実例VBAコード(While・・Wend)]
Sub Sample()
Dim Count As Long
Count = 1
While Range("A" & Count) <> ""
Range("A" & Count).Font.ColorIndex = 3
Count = Count + 1
Wend
MsgBox Count - 1 & "行目まで処理を行いました"
End Sub
次に「Do・・・LOOP While」のWhileステートメントについて説明します。前章で説明した中で、「後判定」の動作をするWhileステートメントです。
構文的には、While 条件の記述箇所が異なるだけです。
Do
・・・
LOOP While 条件
この実例で紹介するサンプル処理です。
下記のように、「値があればセルの背景色を赤色にする」という処理をWhileステートメントを使って記述します。処理は、セルが空白になるまでくり返すものとします。
ただし、Do・・Loop Whileは1度目(最初)の処理は条件判定の前に実行されるという特徴を確認するため、実際には空欄のExcelシートを使います。
[実例VBAコード(Do・・Loop While)]
Sub Sample()
Dim Count As Long
Count = 1
Do
Range("A" & Count).Interior.ColorIndex = 3
Count = Count + 1
Loop While Range("A" & Count) <> ""
MsgBox Count - 1 & "行目まで処理を行いました"
End Sub
Do ・・Loop Whileステートメントでは、処理の最後であるLoop Whileステートメントの後に、処理をくり返す条件を設定します。
上記の例では、9行目の「Loop While Range(“A” & Count) <> “”」ですね。ここで、セルが空欄ではないという条件を設定しています。
そのため、1度目(1行目)の処理は条件判定はされずに必ず実行されます。
セルが空欄でなければ、セルの背景色を赤色にするプロパティが実行されます。条件に該当する間、この範囲の処理がくり返されます。
最後は、実際に何行目(何カウント)まで処理が行われたのか確認するため、MsgBox関数を使っています。
上記のVBAコードを実行するとExcelは下記のようになります。
ここまでで説明したように、Whileステートメントは設定した条件を満たす限り、何度でも処理をくり返しますが、処理回数が増えるとパソコンに負担をかけることもあります。
また、想定外のデータコンディションになっていた場合には、異常な処理回数に発展したり、無限ループに陥ることもリスクとして考えておかなければなりません。
そのため、Whileステートメントに上限回数やその他の条件を定めておき、ループを抜ける処理を組み入れておくことはとても有効です。
たとえばあるサンプルデータを取得する場合で、取得件数が「最大50件」と決まっているようなケースでも、ループを抜ける処理を使います。
Sub Sample()
Dim Count As Long
Count = 1
Do While Range("A" & Count) <> ""
Range("A" & Count).Font.ColorIndex = 3
Count = Count + 1
If Count = 4 Then
MsgBox "上限到達"
Exit Do
End If
Loop
MsgBox Count - 1 & "行目まで処理を行いました"
End Sub
上記のVBAコードは、当記事の「Do While・・Loopステートメントの章」で紹介したコードに、ループを抜ける処理を追加したものです。
上記の例では、10行目から13行目にかけてif文を使っており、カウントが4に到達した時点で、Exit Doが実行されWhileステートメントを抜けます。
Exit Doで抜けるのは、あくまでもWhileステートメントであり、上記の例では16行目以降は実行されます。