■ 繰り返し処理(ループ処理)
いろいろな繰り返し処理
プログラミングで最も多用し、最もその恩恵に与ることができるのが繰り返し処理(ループ処理)です。
CPUは単純な繰り返し処理を正確に行うことが得意です。人間は単純な繰り返し処理ほど苦手なものはなく、またその結果は不正確です。
繰り返し処理には、さまざまな構文がありますが、このときは"これ"を使わなければならないといった規則はありません。
ただ、この場合はこの構文を使用したほうが適している。といったものは存在しますので、やはり様々な繰り返し構文をマスターしておいたほうがよいでしょう。
では早速、繰り返し構文についてみていきましょう。
For〜Nextステートメント
For〜Nextステートメントは自らの中にカウンタを持ちます。カウンタの初期値、終了値、増分値は開発者が任意に指定することが可能です。
例:
For i = 1 To 10 Step 1
Debug.Print "Counter Value:" & i
Next i
最も単純なFor〜Nextステートメントです。カウンタiの初期値は1、終了値は10、増分値は1です。
この例では、Stepの増分値を10以上にした場合、一回だけForブロック内の処理を実行して終了します。初期値に10を超える値を指定した場合は、一度もForブロック内の処理を行うことなく終了します。
Step以降の記述を省略した場合は、増分値は既定値の1になります。
Next i の"i"は記述してもしなくても構いませんが、Forループをネストした場合、どのForループの終了を示すのかわかりづらくなるので、できるだけ記述したほうがよいでしょう。
例:
For i = 1 To 2
Debug.Print "Counter i Value:" & i
For j = 1 To 2
Debug.Print "Counter j Value:" & j
Next j
Next i
For i = 1 To 2
Debug.Print "Counter i Value:" & i
For j = 1 To 2
Debug.Print "Counter j Value:" & j
Next
Next
For i = 1 To 2
Debug.Print "Counter i Value:" & i
For j = 1 To 2
Debug.Print "Counter j Value:" & j
Next j, i
上記の3つのループは、どれも同じ処理を行います。
Do〜Loopステートメント
カウンタを持ちません。その代り、ループの終了条件を記述します。記述法は4種類あり、それぞれ違った意味を持ちます。
Do While 条件式
構文
Loop
Do Until 条件式
構文
Loop
前判断ループです。Whileは条件式が真の間、Untilは条件式が真になるまで繰返しを行います。
前判断ループで、Whileは条件が偽の場合、Untilは条件が真の場合、一度もDoブロック内の構文は実行されません。
Do
構文
Loop While 条件式
Do
構文
Loop Until 条件式
後判断ループです。Whileは条件式が真の間、Untilは条件式が真になるまで繰返しを行います。
後判断ループは、条件の真偽にかかわらず、一度は必ずDoブロック内の構文を実行します。
また条件式は、論理演算子を使用して複数の条件を指定することもできます。
※ While〜Wendステートメントは、Do〜Loopステートメントの前判断、While条件と同じ意味になります。
古いプログラムなどで使用されている場合、できるだけDo〜Loopステートメントに置き換えておくことをお勧めします。
※ Exit For 、Exit Do ステートメントを使用すると、無条件にループから抜けます。ループから抜けたときは、抜けたループの次のステートメントから処理を継続します。
再起処理(再帰呼び出し)による繰り返し処理
再起処理(再帰呼び出し)は、プロシージャが自プロシージャを再帰的に呼び出すことで繰り返し処理を行います。終了条件をきちんと記述しないと無限ループに陥りますので、注意が必要です。
例:
Sub test()
Call FuncSaikiTest(3)
End Sub
Function FuncSaikiTest(ByVal i As Long) As Long
If i > 0 Then
Debug.Print "Counter Value:" & i
FuncSaikiTest = FuncSaikiTest(i - 1)
End If
End Function
この例では、FuncSaikiTest内で再帰呼び出しが行われています。testプロシージャを実行すると、繰り返し処理により下記の値が出力されます。
Counter Value:3
Counter Value:2
Counter Value:1
For〜Eachステートメント
書式:
For Each 変数 In グループ
For Eachステートメントは、グループに指定された、配列、コレクション(オブジェクトの集合)の各要素に対して繰り返し処理を行います。変数は、要素を示すバリアントまたはオブジェクトの型を指定します。
例:
Dim v As Variant
For Each v In Array(1, 2, 3, 4, 5)
Debug.Print v
Next v
Dim v As Variant
Dim a() As Variant
a() = Array(1, 2, 3, 4, 5)
For Each v In a
Debug.Print v
Next v
上の二つの構文は、同じ処理を行います。配列から1〜5の各要素値を全て出力します。
例:
Dim r As Range
For Each r In Range("A1:B5")
Debug.Print r
Next r
Dim r As Range
Dim a As Range
Set a = Range("A1:B5")
For Each r In a
Debug.Print r
Next r
上の二つの構文は、同じ処理を行います。アクティブシートのA1〜B5セルの値を全て出力します。
For〜Eachステートメントを利用するためには、コレクションについて理解している必要があります。
For〜Eachの使用例について、もう少し紹介しましょう。
Dim c As Variant
For Each c In Me.Controls
Debug.Print c.Name
Next c
この例では、フォーム上にあるコントロールの名前を全て出力します。
Dim r As Range
For Each r In ActiveSheet.UsedRange
Debug.Print r
Next r
この例では、アクティブなシート上で使用されているセル範囲の値を全て出力します。
Dim s As Worksheet
For Each s In ActiveWorkbook.Worksheets
Debug.Print s.Name
Next s
この例では、アクティブなブック上にあるワークシートの名前を全て出力します。
この他にもFor〜Eachステートメントは、様々なコレクションに対して繰り返し処理を行うことができます。
※ グループから取り出される要素の順番を制御することはできません。要素の順番を制御する必要がある場合は、他の繰り返し処理を応用してください。
※ ユーザー定義型の配列をグループに使用することはできません。
以上、繰り返し処理について解説しました。繰り返し処理はプログラムの至る所で使用されます。
前回解説した条件分岐処理と今回解説した繰り返し処理で、プログラムを構成するコードの大部分を占めるといっても過言ではないでしょう。
繰り返し処理は必ずマスターする必要のある処理です。
プログラムを構造化するということは、同じ処理を2度書かないということです。繰り返し処理をマスターすれば、コードの大部分を構造化することが可能です。
ぜひ、マスターしてください。
|