VBA講義室 > コードの構造化 > 繰り返し処理
繰り返し処理
繰り返し処理もコード構造化の基本中の基本である。
Do と Loop の間に書かれたステートメントを繰り返し実行する。
実行条件が満たされている間、もしくは終了条件が満たされるまで実行を繰り返す。
Do の直後に条件を評価するので、条件によってはDo と Loop の間に書かれたステートメントが実行されない場合もある。
Do [{
While |
Until}
condition]
[
statements]
[
Exit Do]
[
statements]
Loop
Loop に達してから条件を評価するので、Do と Loop の間に書かれたステートメントは最低一回は実行される。
Do
[
statements]
[
Exit Do]
[
statements]
Loop [{
While |
Until}
condition]
- Do / Loop
- 必ず指定。この2つのステートメントの間に書かれた内容が繰り返し実行される。
- {While | Until} condition
- Exit Do
- 省略可能。このステートメントが実行されると繰り返し処理を終了し、Loopステートメントの次に書かれるステートメントへ処理を進める。
- statements
- 省略可能。繰り返したい実行ステートメントを記述する。
- While condition
- 条件式condition がTrueの間、処理を繰り返す。条件式condition が True であれば、Do Loop間のステートメントを実行し、FalseになればLoopステートメントの次のステートメントへ処理を進める。
- Until condition
- 条件式condition がTrueになるまで、処理を繰り返す。条件式condition が False であれば、Do Loop間のステートメントを実行し、TrueになればLoopステートメントの次のステートメントへ処理を進める。
- 条件式condition の値が Null 値の場合、条件式condition はFalseであるとみなされる。
- 条件式condition 以外に繰り返し処理を終了する必要がある場合に、Exit Do ステートメントを指定して繰り返し処理を終了する。通常、IfステートメントやSelect Caseステートメントと組み合わせて終了条件を評価した上で使用する。
- Do Loop ステートメントは、Do Loop ステートメントの内部に別の Do Loop ステートメントを入れ、ネスト (入れ子) 構造にすることができる。
{While | Until} condition や Exit Do は省略できるが、全て省略してしまうとオーバーフローなどのエラーになって実行が中断するか、或いは無限ループに陥る。終了させる条件を最低ひとつは用意しておく必要がある。
While...Wend ステートメント
指定した条件が真 (True) である間、一連のステートメントの実行を繰り返すフロー制御ステートメント。
Do Loopと類似。条件を判断して処理を繰り返す目的で使用する。
While condition
[
statements]
Wend
- condition
- 必ず指定。条件式。
TrueまたはFalseを返す数式か文字列式を指定。
- statements
- 省略可能。繰り返し実行する 1 つまたは複数のステートメントを指定。
条件式 condition がTrue であれば、While〜Wend 間に指定された statements を が実行。Wend に達したときに、処理が While へ戻り、再度条件式 condition を評価。評価した結果が True の場合は、この繰り返しとなり、また、False の場合は、Wend ステートメントの次のステートメントへ実行が移る。
While Wendステートメントと、Do Loopステートメントは条件によって処理を繰り返すと言うことにおいて、良く似た処理をする。根本的に違うのは、Do Loopステートメントでの Exit Doステートメントにあたる処理の途中でループから抜け出す手法がWhile Wendステートメントには用意されていないこと。
したがって、「構造化」と言う意味においてはDo Loopステートメントのほうが柔軟な処理が可能であるし、処理そのものについてもDo Loopステートメントで代用が出来るので、VBAコードを書くにあたってWhile Wendステートメントは必須ではないように思える。
ステートメントを指定回数分繰り返す。
For counter =
start To end [
Step step]
[
statements]
[
Exit For]
[
statements]
Next [
counter]
- counter
- 必ず指定。数値型の変数のみ指定可能(ここで変数の概念の理解が必ず必要になる)。配列変数およびブール型 (Boolean) 変数は指定できない。
- start
- end
- step
- 省略可能。ループをごとの引数 counter への加算値を指定。正の数または負の数を指定可能。
省略した場合、引数 counter へのループごとの加算値は 1 が設定される。
- statements
- 省略可能。実際に繰り返し実行する一連のステートメントを指定する。必ずFor と Next の間に記述。
引数start , end , step により決定される回数だけ実行。
なお、start , end , step の各引数には数値型の変数を使用することも可能。
- 引数 counter に引数 start の値を代入
- 引数 counter と引数 end の値を引数 step の値を加味して評価。終了条件が満たされていれば終了。
- 終了条件が満たされていなければループ内のステートメント実行。
- 実行後、Nextステートメントで 引数 step の値を引数 counter に加算。
- 2.へ処理が戻り、終了条件評価。
1.の処理は一回だけ行なわれ、以後2. 〜 5.の処理が終了条件を満たすまで繰り返される。
引数 step で指定した値によりループの実行は次のように制御される。
- 引数 step が正の数(または 0 )のとき
- 引数 counter が引数 end 以下であれば実行。
- 引数 counter が引数 end を超えればループ終了。
- 引数 step が負の数のとき
- 引数 counter が引数 end 以上であれば実効
- 引数 counter が引数 end 未満であればループ終了。
【例】
・For i = 1 to 0
・引数 step は省略されているので Step 1 (加算値は正の数)が省略されているとみなされる。
・引数 counter として使用される変数 i の初期値は 1 。
・だが、その時点で最終値を超えているので実行ステートメントを実行せずにループは終了。
・For i = 1 to 0 Step -1
・引数 counter として使用される変数 i の初期値は 1 。
・Step -1 (加算値負の数)で最終値以上であるので、一回は実行ステートメントが実行される。
・For i = 1 to 1 Step 0
・引数 counter として使用される変数 i の初期値は 1 。
・Step 0 (加算値0)のため変数 i は何回ループしても最終値以上にならない(無限ループ)。
・ループを抜け出す処理が必要になるが、引数 counter をアテにしないループなら通常はDo Loopステートメントを使用する。
ループから強制的に抜け出す方法として、Exit For ステートメントが用意されている。
ループ内に任意の数を指定することができる。
If Then ステートメント、Select Caseステートメントなど条件を評価できるステートメントで条件を評価した上でExit For ステートメントによりループから抜け出す。
抜け出した後は キーワード Next の次のステートメントへ実行が移る。
- For Next ループはネスト (入れ子) 構造にして、For Next ループの内部に別の For Next ループを入れることができる。
- ネスト (入れ子) 時には、それぞれの引数 counter に別の変数名を指定しなければならない。
- Next ステートメントの引数 counter は省略できるが、対応する For ステートメントを明確にするために省略するべきでない。
【例】
For i = 1 To 10
For j = 1 To 10
...
Next j
Next i
- ループ内で引数 counter の値は変更することもできるが、わかりにくい制御構造となり、デバッグが困難になるので変更してはいけない。
配列やコレクションの各要素に対して、一連のステートメントを繰り返し実行。
For Each element In group
[
statements]
[
Exit For]
[
statements]
Next [
element]
- element
- 必ず指定。処理を行ないたい要素のメンバを格納するための変数を指定。
- コレクションの場合、次の変数が指定できる。
- バリアント型
- 総称オブジェクト型
- 任意の固有オブジェクト型
- 配列の場合は、バリアント型のみ指定できる。
- group
- 必ず指定。
- 処理対象となるオブジェクト コレクション名または配列名 (ユーザー定義型の配列を除く) を指定。
- statements
- 省略可能。引数 group の各メンバに対して実行するステートメントを指定。
- 引数 group に要素がある場合処理開始
- 引数 group の要素のインデックスの小さいメンバより引数 element に格納(または参照を格納)
- 引数 element に格納(または参照を格納)したメンバに対して、ループ内のステートメントを実行。
- 実行後、引数 group の要素の次のインデックスのものがあれば、2.へ処理が戻る。
引数 group の中に要素がある限り、2.〜4.を繰り返す。引数 group の中にもう要素がなくなれば、ループを終了し、Next ステートメントの次のステートメントに実行が移る。
ループから強制的に抜け出す方法として、Exit For ステートメントが用意されている。
ループ内に任意の数を指定することができる。
If Then ステートメント、Select Caseステートメントなど条件を評価できるステートメントで条件を評価した上でExit For ステートメントによりループから抜け出す。
抜け出した後は キーワード Next の次のステートメントへ実行が移る。
- For Each Next ループはネスト (入れ子) 構造にして、For Each Next ループの内部に別の For Each Next ループを入れることができる。
- ネスト (入れ子) 時には、それぞれの引数 element に別の変数名を指定しなければならない。
- Next ステートメントの引数 element は省略できるが、対応する For ステートメントを明確にするために省略するべきでない。
【例】
For Each Sh In Worksheets
For C In Sh.Cells
...
Next C
Next Sh
- For Each Nextステートメントをユーザー定義型の配列に使用することはできない。
前(条件分岐) 目次 次(分岐処理)