K-fix Learning & Playing

応用編


実行処理を制御する

通常、1つのプロシージャを実行すると一番上のステートメントから処理が行われます。そこで、ある条件によって処理を分岐したり、同じ処理を繰返しするには制御構造を持つステートメントを使用します。初めてVBAの学習をした方は、必ずそのステートメントを見たことがあると思います。では、基本的な制御構造を持つステートメントを挙げてみましょう。

条件が成立・不成立によって処理を分岐する

IF~Thenステートメント

If  条件式  Then

条件式が成立した場合の処理

End If

                        
        Sub 条件分岐1()
            If Range("A1").Value > 5 Then
                Range("A2").Value = "5より大きい数字です。"
            End If
        End Sub
                        
                    

セルA1の値が5よりも大きければ、セルA2に「5より大きい数字です。」と入力されるプロシージャです。


If~Then~Elseステートメント

If  条件式  Then

条件式が成立した場合の処理

Else

条件式が成立しなかった場合の処理

End If

                        
        Sub 条件分岐2()
            If Range("A1").Value > 5 Then
                Range("A2").Value = "5より大きい数字です。"
            Else
                Range("A3").Value = "5以下の数字です。"
            End If
        End Sub
                        
                    

セルA1の値が5よりも大きければ、セルA2に「5より大きい数字です。」と入力され、もし違っていればセルA3に「5以下の数字です。」と入力されるプロシージャです。


If~Then~ElseIfステートメント

If  条件式1  Then

条件式1が成立した場合の処理

ElseIf  条件式2  Then

条件式2が成立した場合の処理

Else

いずれの条件も成立しなかった場合の処理

End If

                        
        Sub 条件分岐3()
            If Range("A1").Value > 5 Then
                Range("A2").Value = "5より大きい数字です。"
            ElseIf Range("A1").Value <= 0 Then
                Range("A3").Value = "0以下の数字です。"
            Else
                Range("A4").Value = "1から5までの数字です。"
            End If
        End Sub
                        
                    

セルA1の値が5よりも大きければ、セルA2に「5より大きい数字です。」と入力され、もしセルA1の値が0以下ならばセルA3に「0以下の数字です。」と入力されます。どの条件にも合わない場合は、セルA4に「1から5までの数字です。」と入力されるプロシージャです。

条件式やその値によって処理を分岐する

Select Caseステートメント

Select Case  条件式

Case  A

  条件式の値がAを満たしている場合の処理

Case  B

  条件式の値がBを満たしている場合の処理

  

  

Case Else

  どの条件も満たさなかった場合の処理

End Select

                        
        Sub 条件分岐4()
            Dim t As Integer
            t = Range("B2").Value
            Select Case t
                Case Is >= 100
                    MsgBox "10ポイントが追加されます。"
                Case Is >= 50
                    MsgBox "5ポイントが追加されます。"
                Case Is >= 20
                    MsgBox "2ポイントが追加されます。"
                Case Else
                    MsgBox "ポイントなしです。"
            End Select
        End Sub
                        
                    

Select CaseステートメントはIf~Then~ElseIfステートメントと同等な処理を行いますが、記述の簡潔さやメンテナンスなどを考えるとSelect Caseステートメントの方が扱いやすいメリットがあります。
上の例では、セルB2に100以上、50以上、20以上の場合はそれぞれのポイントが追加されるメッセージを表示させ、該当しない場合は「ポイントなし」のメッセージを表示させるプロシージャです。
Select Caseステートメントでは条件を比較演算子で表すことが多いです。比較演算子で条件を記述する場合は、上の例のようにCase Isとなります。Isを省略して記述しても、自動的にIsが挿入されます。

指定した数だけ処理を繰り返す

For~Nextステートメント

For  カウンタ変数=初期値  To  最終値  [Step増減値]

繰り返す処理

Next  カウンタ変数

                        
        Sub 繰り返し()
            Dim i As Integer
            For i = 1 To 5
                Worksheets("Sheet1").Cells(i, 1) = "繰返し"
            Next i
        End Sub
                        
                    

For~Nextステートメントでは処理を繰り返すためにカウンタ変数を使います。よって、まずカウンタ変数の宣言をしておきます。上の例では、カウンタ変数に1から5までの値を順次入れ、Sheet1のシートのセルA1からA5に「繰返し」という文字列を入れる処理になっています。

条件式を満たす間は処理を繰り返す

Do While~Loopステートメント

Do While  条件式

繰り返す処理

Loop

条件が合う間は処理を繰り返す方法です。上の例では、まずセルA1を選択し、そのセルが空白でなければ塗りつぶしの色を水色にします。そして、そのセルの1つ下のセルを選択してから同じ処理を繰り返すプロシージャです。
セルA1からA5までは値が記述されているので塗りつぶしの色が設定されますが、セルA6は空白セルなのでそこで処理が終わっています。


Do~Loop Whileステートメント

Do

繰り返す処理

Loop While  条件式

これも条件が合うまでの処理ですが、Do~While Loopステートメントと違うのが、処理を必ず1回実行してから条件を参照します。上の例では、セルA1が空白であっても塗りつぶしの色を設定した後に、セルの値が空白であることを見ていくので、実際はセルA2から条件が参照されることになります。Do~While Loopステートメントならば、セルA1が選択された状態で処理を終えてしまいます。

条件を満たすまで処理を繰り返す

Do Until~Loopステートメント

Do Until  条件式

繰り返す処理

Loop

条件が満たされるまで処理を行います。上の例は、セルA1を選択した後に、選択されたセルが空白になるまで処理されるプロシージャです。セル内のデータのフォント色を緑に設定して、下のセルを選択してから処理を繰り返えしています。セルA6が空白であるので、そこで条件を満たすことになるので処理を終えています。


Do~Loop Untilステートメント

Do

繰り返す処理

Loop Until  条件式

これも条件が満たされるまで処理を繰り返します。ただし、必ず1回処理を行ってから条件を参照して繰り返します。上の例は、セルA1は空白ですので最初から条件は満たされています。Do Until~Loopステートメントならば何も処理を行わずプロシージャは終了します。この場合は、セルA1のセル内容は確認せずフォント色を設定し、1つ下のセルがアクティブされてから条件を参照して、その後に繰返しの処理が実行されます。


これらの制御構造を持つステートメントは、プロシージャを記述する上ではよく利用されます。コレクション内のすべてのオブジェクトを順番にオブジェクト変数に代入して処理ができる制御ステートメントを紹介します。For Each~Nextステートメントは、コレクション内のすべてのオブジェクトに対して処理を繰り返してくれます。

For Each~Nextステートメント

For Each  オブジェクト変数  In  コレクション

オブジェクトに対する処理

Next  オブジェクト変数

上の例を説明すると、まずRange型のオブジェクト変数Mycellを宣言しています。次に、セルB2からC4のすべてのセルに対してIf文内の処理を繰り返しています。For Each~Nextステートメントを使うと、各オブジェクトへの参照を順番に代入するので、Setステートメントを使う必要はありません。また、処理される順番は選択されている範囲内で右方向へ処理されてから、下の行の左端から右の方向へ移ります。最後は、コレクション内(指定されているセル範囲)の右下端のセルで処理が終了されます。

サブルーチンの利用

あるプロシージャから他のプロシージャを呼び出して利用することができます。呼ぶ出されるプロシージャのことをサブルーチンと呼びます。また、呼び出すプロシージャを親プロシージャと呼びます。
親プロシージャからサブルーチンを呼び出すには、サブルーチン名を親プロシージャ内に記述します。サブルーチンを呼び出して使うメリットは、同じようなコードを書く手間が省けたり、特定の機能ごとに処理をまとめておくことができ、さまざまなプロシージャで共有することが可能となります。さらに、処理のメンテナンスも機能ごとに分けてあるのでやり易く、処理の流れも把握しやすい点があります。

サブルーチンは標準モジュール内に記述し、すべてのモジュールのすべてのプロシージャで呼び出して使えます。

親プロシージャで処理した値や文字列などの値をサブルーチンに引渡し、サブルーチンでその値に応じた処理を実行させます。ただ、親プロシージャからサブルーチンに値を渡すためには、値を受け取るための変数がサブルーチン側で必要となります。その変数を引数といいます。つまり引数付きのサブルーチンでは、引数の名前やデータ型をサブルーチン名の後ろにある()内で指定します。では、例題でその使い方を理解してください。

親プロシージャ内にサブルーチン名を記述して呼び出しています。その際、サブルーチン側に引数(変数)のデータ型をカッコ内に記述しています。サブルーチンのプロシージャの内容は、70以上であれば水色にセルを塗りつぶし、40より多ければ白、どれにも条件が入らなければ赤に塗りつぶす設定です。
親プロシージャでは、まずセルB2を選択し、セル内が空白でなければ処理を繰り返すDo While Loopステートメントが記述されています。引数にアクティブセルの値を指定して、サブルーチン「サブ_点数判定」を呼び出します。その後、アクティブセルを1行下のセルを選択しています。
塗りつぶす色や判定する点数の変更は、サブルーチンのプロシージャで書き換えることになるので、変更しやすい点があります。それに、このサブルーチンを他のプロシージャでも利用することができます。