Chapter 13 反復構造 Do Loop

イントロダクション コース

テーマ

 第13回目となる本稿のテーマは、「繰り返し構文の一つである Do Loop を理解する」です。

 Do Loop は繰り返しを行う構文の一つです。柔軟性が高いためどの様な繰り返し処理も表現することが出来ます。また、繰り返し構文の共通点として「条件分岐」を必ず伴うことが挙げられます。条件分岐を行わないと無限ループとなってしまうからです。

 繰り返し処理の基本的構文である Do Loop を学習することでコードの可読性や効率性が向上します。

前判定 Do Loop

    Do While True
        Debug.Print "ずっとにこれを繰り返す"
    Loop

 この形は Do While Loop の基本形です。1 行目から解説していきます。

Do While True

 While の後ろに条件式を記述し、その条件式が True と評価されている間はずっと Do While と Loop の間にある行を実行します。この例では条件式として True と記述されているため、条件式は常に True と評価されます。条件式が True と評価されたので Do While と Loop の間にある Debug.Print “ずっとこれを繰り返す” を繰り返し続ける無限ループとなります。

もう少しコードの流れを詳しく述べるとこのコードは以下の順序で実行されていきます。

Do While True
はじめにこの行の条件式が評価されます。
【評価された値が False のとき】
Do は無視され、 Loop の次行へジャンプします。
【評価された値が True のとき】
Do が働き次行を実行します。
この例では、条件式は True ですから次行へ移ります。

Debug.Print "ずっとこれを繰り返す"
この行が実行され、イミディエイトウインドウに
ずっとこれを繰り返す
と表示され、次行へ移ります。

Loop
Loop は Do へジャンプします。そのため、この行が実行されると
Do While True
この行へ処理が移ります。以下繰り返し。

While のあとに続く条件式に何を記述するかが重要です。記述する条件式によってこの構文の動作が決まるからです。

 それでは以下のマクロを Sheet1 シートモジュールへ記述して実際に動作させてみましょう。

Public Sub Chapter13_DoLoop()
    
    Dim counter As Long
    Dim message As String
    Do While counter < 6
        message = message & CStr(counter) & Strings.Space$(1)
        counter = counter + 1
    Loop
    Debug.Print message
    
End Sub

 このマクロを実行すると、イミディエイトウインドウに以下の様に表示されます。

0 1 2 3 4 5 

 このコードの流れを説明します。

Dim counter As Long

ループカウンター用の変数 counter を宣言しています。
Do Loop 構文では「繰り返し」の回数を制御するために、このようなループカウンターを用いることがあります。

Dim message As String

処理の結果を保持するための変数 message を宣言しています。

Do While (counter < 6) 

ここから Do While Loop の開始です。前判定を行う Do Loop の特徴は、最初に条件式による判定を行う点にあります。繰り返し構造である Do Loop の冒頭に Do While ( 条件式 ) と記述され、その条件式が True である間は繰り返し処理が継続されます。

この例では、条件式が counter < 6 となっていますので、変数 counter が保持している値が 6 未満である間、ループを続けることを意味しています。つまり、Do While は条件分岐として機能するわけです。

ところで変数 counter は初期値として 0 を保持しています。そのため Do While( counter < 6 ) は、True と評価され、処理は次行へと移ります。

        message = message & CStr(counter) & Strings.Space$(1)

CStr(counter) は数値である counter の値をテキストに変換します。よってこの式はテキスト “0” と評価されます。

Strings.Space$(1) は、Strings クラスのメソッドです。引数として渡した数値の個数だけ半角スペースを返してきます。今回は 1 を指定していますので半角スペース一つが返却されます。つまり、

message = message & CStr(counter) & Strings.Space(1)

message = “” & “1” & ” “

と評価され、変数 message には “1 ” が代入されることになります。

        counter = counter + 1

この行は counter = 0 + 1 と評価され、変数 counter には 1 が代入されます。

    Loop

Loop は 処理を ループ構造の冒頭へ飛ばしますから、再び Do While (counter < 6) へと処理が移ります。

変数 counter は 1 を保持しています。そのため条件式は True と評価され、再度繰り返し処理に移ります。このように 条件式 が満たされている間( True と評価されている間 ) は、Do While (条件式) と Loop の間に記述されている処理が繰り返し実行される仕組みとなっています。

この例での場合、繰り返し処理の中で counter が 1 ずつ増えていきますので、繰り返し処理が 6 回実行されたところで counter < 6 が False と評価され、処理は Loop の次行へと移ることになります。

Do Loop の構文を確認しておきましょう。

Do While 条件式

繰り返したい処理

条件式の評価を変化させる処理(ループカウンターの増加など)

Loop

この構文を用いることによって、条件式が True と評価されている間は Do の次行から Loop の前行までの処理を繰り返すことが可能となります。

条件式が繰り返し処理の前に配置されていることから、前置判定ループまたは前判定ループと呼ばれることがあります。

後判定 Do Loop

 もう一つの構文を紹介します。

Do

繰り返したい処理

条件式の評価を変化させる処理(ループカウンターの増加など)

Loop While 条件式

 上記の構文は先に紹介した構文と異なり While 条件式 が Do の直後から Loop の直後へと移動しています。

 このように繰り返し処理の後に条件式を配置して判定を行うループを後置判定ループまたは後判定ループと呼びます。後判定ループの特徴は、繰り返し処理の実行が一度は保証されるという点です。前掲の前判定ループとともに使い勝手の良い書き方ですので練習して覚えてしまいましょう。

 先ほどのマクロを以下へ修正してください。

Public Sub Chapter13_DoLoop()
    
    Dim counter As Long
    Dim message As String
    Do
        message = message & CStr(counter) & Strings.Space(1)
        counter = counter + 1
    Loop While counter < 6
    Debug.Print message
    
End Sub

 このコードは後判定ループです。F5 キーを押して実行してみましょう。

0 1 2 3 4 5 

 上記例では前判定ループと結果は同じですが、仮に Do の手前で counter の値が 7 になっても

message = message & CStr(counter) & Strings.Space(1)

が一度は実行される点で前判定ループとは動作が異なります。

任意の位置で判定する Do Loop

 次に紹介するのは任意の位置で条件分岐を行う Do Loop 構文です。

Do

繰り返す処理

If 条件式 Then Exit Do

繰り返す処理

Loop

前判定ループでは Do の直後に While 条件式があり、後判定ループでは Loop の直後に While 条件式が記述されていました。任意の位置で条件分岐を行う時は、While 条件式 は不要となります。その代わりループ処理の任意の位置で If 文を用いて条件分岐を行い、Exit Do によって Do Loop から脱出する必要があります。

このような記述もときどき使われることがありますので、まずはこのような方法もあるということを頭の片隅に入れておいてください。

 Sheet1 シートモジュールに以下のマクロを作成し、実行してみましょう。

Public Sub Chapter13_ExitDo()

    Do
        Dim number As Long
        number = Application.InputBox("1 から 9 までの数値を入力してください。0 を入力すると終了します。", "Exit Do の練習", Type:=1)
        If number = 0 Then Exit Do
        Debug.Print number
    Loop
    
End Sub

 このマクロを実行すると、入力用ダイアログが表示され、数値を入力できます。入力した値はイミディエイトウインドウに表示されます。

0 を入力したときに Do Loop から処理が抜けるのでマクロが終了します。それ以外の文字を入力すると再び入力用ダイアログが表示されます。

もう一つの条件分岐

 今までは Do Loop で用いる条件分岐として While 条件式 と If 文を用いてきました。可読性の高さと使用頻度の多さからその二つを紹介しましたが、もう一つ条件分岐を行える構文があります。

 Sheet1 シートモジュールに以下のマクロを作成して実行してみてください。

Public Sub Chapter13_Until()

    Dim counter As Long
    Dim message As String
    Do Until counter = 6
        message = message & CStr(counter) & Strings.Space(1)
        counter = counter + 1
    Loop
    Debug.Print message
    
End Sub

 実行結果は以下の通りです。

0 1 2 3 4 5 

 この例では While + 条件式 の代わりに Until + 条件式 を用いています。どちらも同じことを実現出来ますが、While の後に続く条件式と Until の後に続く条件式は異なってきます。

While + 条件式 は、条件式が True と評価されている間ループを行いますが、Until + 条件式 は条件式が True になるとループ処理を終了します。

 Until を用いたループも時々見かけることはありますが、可読性が高いとは言えないのであまり使われることはありません。こんな書き方もあるという程度に抑えていれば十分かと思います。

 当サイトでもサンプルコードには While を用い、Until は非推奨構文とさせていただきます。

さらにもう一つの書き方

Sheet1 シートモジュールに以下のコードを追加し、実行してみましょう。

Public Sub Chapter13_WhileWend()
    
    Dim counter As Long
    Dim message As String
    While counter < 6
        message = message & CStr(counter) & Strings.Space$(1)
        counter = counter + 1
    Wend
    Debug.Print message
    
End Sub

 実行結果は以下の通りです。

0 1 2 3 4 5 

 この While Wend を用いた繰り返しは、Do While Loop (前判定)と同じ機能です。そのため、どちらの記述を採用するかは自由です。可読性は Do While Loop の方が若干優れているとは思いますが、大した差はないのでこちらを使っても構わないと思います。

 本コースを学習中でプログラミングそのものが初めての方は、一度にたくさんのことを覚えるのは大変だと思いますので、現時点ではこの記述方法は無視しても構いません。余裕を感じた時に、再度確認してみてください。

まとめ

 本稿では繰り返し処理を伴う条件分岐構文である Do Loop を学習しました。

前判定、後判定など非常に柔軟な記述が可能な繰り返し構文である Do Loop は使用頻度も高いです。特に、テキストファイルの入出力やデータベースから取得したデータの処理など、ループ回数を動的に把握出来ない繰り返し処理を主に担当します。

 それでは本稿はこれで終了します。お疲れさまでした、また次回お会いしましょう。

タイトルとURLをコピーしました