Excel VBA 入門 その6-4-3 : For文の動きをコントロールしてみましょう

StockSnap / Pixabay


皆さまこんにちは!

このサイトの管理者のHide(ヒデ)と申します。

前回と、前々回のブログでExcel-VBAで利用するFor文とは何か、また利用用途としてどのようなものがあるかについて見てきました。

前回のブログはこちら
前々回ブログはこちら

今回は、For文の一般的な使い方である、ループ変数の初期値から終了値までの間、処理を繰り返すだけでなく、処理を途中で中止したり、スキップしたりする方法についてお伝えします。

また、For文について、実際の開発現場での書き方についても合わせてお伝えします。

では始めましょう。

スポンサーリンク
Simplicityのレクタングル広告(大)

1. 実践的なFor文の記述方法

まず初めに、For文を使った簡単なプログラムを書いてみましたのでご覧ください。下記のプログラムは1~100までの整数の和の合計を計算するプログラムです。プログラムの名前はCalcSum2としました。

Sub CalcSum2()

'変数の宣言
Dim Sum As Long
Dim i As Long

'明示的な変数の初期化
Sum=0

'整数の和の計算
For i=1 To 100
    Sum=Sum+i
Next i

'整数の和の結果を表示
Debug.Print "整数の和=" & Sum

End Sub

上記のプログラムについて少し解説します。整数の和の結果を格納するために変数Sumを用意し、For文で必要なループ変数として変数iをそれぞれLong型で用意しました。

変数の型について解説しているブログはこちら

For文においてループ変数iの初期値は「1」,終了値は「100」と指定しています。このように初期値や終了値を直接数字で指定すると見た目は分かりやすいのですが、例えばこの初期値や終了値を変更することになった場合、しかも1つのプログラムではなく、たくさんのプログラムの中で同じ値の初期値や終了値が使われていたら、個々のプログラムを修正することになり、非常に大変です。

そこで、実際の開発現場では、For文の初期値や終了値について、直接数字を指定するのではなく、定数(定数名)を指定するのが一般的です。定数とは固定された値のことを意味します。また、Debug.Printの行に記述されている「整数の和=」という文字の部分も同様の事が言えます。

定数は変数と同様に宣言して利用します。定数は一般的に個々のプログラムで個別に宣言するのではなく、定数宣言用のモジュールを作成してそこにまとめて記述してしまいます。個々のプログラムの中で個別に定数を宣言した場合、修正時にその定数が記述されたプログラムを探して修正する手間がありますが、個々のプログラムが利用する定数を1つのモジュールにまとめて宣言してしまえば、その手間がなくなり、とても便利です。

下記が定数の宣言例になりますので、ご覧ください。

Public Const StartNum As Long = 1
Public Const EndNum As Long = 100
Public Const MsgStr As String = "整数の和="

定数の宣言ですが、下記のような文法になっています。

Public Const 定数名 As 定数のデータ型 = 「設定したい数値や文字」

このように定数を宣言しますが、少し解説しますね。

まず、先頭にPublicとありますが、Publicと書くことでプログラムを記述しているモジュールとは別のモジュールで定数を宣言(記述)してもそのプログラムから定数を利用できるようになります。

次に定数名の部分がありますが、上記の例ではStartNum,EndNum,MsgStrが定数名に当たります。定数名には予約語が利用できない,先頭を数字にできない等、若干制限はありますが、自由に決めることができます。この点は変数と同じとお考えください。

定数名についての補足:StartNum,EndNumはそれぞれStartNumber,EndNumberを短くしたイメージで、MsgStrはMessageStringを短くしたものをイメージして名前を付けました。プログラミングでは文字列のことをString(ストリング)と言うことが多いのでこのように付けてみました。

その後に「As 定数のデータ型」とありますが、これは変数と同じで、データの型を指定するのですが、その定数がどのデータ型に該当するのかということを踏まえてデータ型を設定します。整数のデータ型には、IntegerやLongなどがありますが、Integer型で格納できる範囲を超える数を定数として指定する場合はLong型を指定する必要があります。

それぞれのデータ型がどのような範囲まで格納できるかについては、下記のブログも参考にしてください。

変数の型について解説しているブログはこちら

定数の宣言では、最後に「=」を書いて、その右隣りに設定したい数値や文字を記述します。文字の場合は、文字の前後を「"(ダブルクォーテーション)」で囲む必要があります。

変数と定数は、何となく似ている感じもしますが、決定的な違いは、プログラムの中で、定数には他の数値や文字を代入できないということです。また、変数はプログラムの中で色々な値に更新しながら使う可変のものですが、定数は一旦決めたら(方針が変わらない限り)変えない不変のものに使用します。最も代表的な定数の使用例は消費税の税率などです。定数を変更する場合は、プログラムの実行前に定数の宣言のところで値を書き換えておく必要があります。

定数についてどのようなものかご理解頂けましたでしょうか。例えば、先ほどのように定数を宣言することで、プログラムの中で今まで初期値や終了値を数字で書いていた部分をStartNumやEndNumという定数名で記述できるようになります。

それでは、ここで学んだ定数を別のモジュールで宣言してみましょう。今回、VBEの画面で下図のように新しいモジュールを追加して、赤枠部(1番)のように名前を「Mo00_Public」としました。また、モジュールを追加した際に赤枠部(2番)のようにコード画面の先頭に「Option Explicit」という文字が挿入されていることを確認してください。

モジュールの作成方法や名前の変更方法については、下記のブログをご覧ください。

モジュールの作成方法について解説したブログはこちら
モジュール名の変更方法について解説したブログはこちら

これで、定数記述用のモジュールができました。この中に先ほどご紹介した定数の宣言を記述してみましょう。下図の赤枠部ように先ほどの宣言をそのまま入力すればOKです。分かりやすくするため「'定数の宣言」というコメントも入れています。

それでは、この定数を使って先ほど作成したCalcSum2のプログラムを書き直してみましょう。For文の初期値と終了値,Debug.Print文の表示メッセージの部分を定数名で置き換えたものが下記のプログラムになります。

Sub CalcSum2()

'変数の宣言
Dim Sum As Long
Dim i As Long

'明示的な変数の初期化
Sum=0

'整数の和の計算
For i=StartNum To EndNum
    Sum=Sum+i
Next i

'整数の和の結果を表示
Debug.Print MsgStr & Sum

End Sub

このように記述することでStartNumは「1」に,EndNumは「100」に,MsgStrは「整数の和=」にそれぞれ置き換わってプログラムが実行されます。

もし、1~100までの整数の和ではなく、201~300までの整数の和に変更したいという場合は、上記のプログラムそのものではなく、Mo00_Publicモジュールの中の定数に設定された数値を書き換えればよいわけですね。

このように定数を使って修正しやすいプログラムを作成しましょう。今回ご紹介した定数という概念ですが、例えば、簡単なテストプログラムを作成する時や将来的にプログラムを修正する可能性が低いような箇所においては、定数(名)を使わずに直接数字や文字を記述してもかまいません。この点については、プログラムを作成する人の好みや判断となります。

2. For文の処理を途中で中止する方法

これまでのブログでは、For文がループ変数を初期値から終了値まで動かす一般的な使い方についてお伝えしてきました。実は、For文はループ変数が終了値になる前に途中で処理を中止し、次のプログラムのステップに進めることが可能です。この方法についてお伝えします。これには2つの方法があります。

2-1. Exit For 文を使って中止する

まず、「Exit For」という文を使ってFor文の処理を途中で中止することができます。といってもイメージがつきにくいと思いますので、まずは、簡単なプログラムを考えてみましたのでご覧ください。

Sub CalcSum3()

'変数の宣言
Dim Sum As Long
Dim i As Long

'明示的な変数の初期化
Sum=0

'整数の和の計算
For i=StartNum To EndNum
    If i=StartNum+3 Then
        Exit For
    End If

    Sum=Sum+i
Next i

'整数の和の結果を表示
Debug.Print MsgStr & Sum

End Sub

このプログラムは先ほどご紹介したCalcSum2というプログラムを一部改造したものです。違いは、CalcSum3のFor文の中に下記の文が追加されている点です。

If i=StartNum+3 Then
    Exit For
End If

このIf文の意味ですが、ループ変数iの値がStartNum+3(これは1+3を意味します)、つまり「4」になったらFor文の処理を終了して、次に実行されるプログラムの行に進みなさいという意味です。

では、For文の次に実行されるプログラムの行とはどこのことでしょうか?

それは「Debug.Print MsgStr & Sum」という、整数の和の結果を表示する命令の行です。

Exit Forという文には、一般的にFor文の中でIf文と組み合わせて、ある条件式に一致したらFor文の処理を中止するという機能があります。Exit For文の詳しい動きについては後述します。

では、実際にVBEのコード画面にこのプログラムを入力して動かしてみましょう。

前回のブログで下図のようにVBEの画面のMo04_Forというモジュールに「TimesTable」という名前のプログラムを作成しました。今回のブログではこのプログラムの上側にプログラムを入力していきたいと思います。ちょうど赤矢印の部分に入力しましょう。

プログラムを入力すると下図の赤枠部のようになりました。

プログラムは入力できましたでしょうか。それではプログラムを動かしてみましょう。通常、プログラムの動かす場合、動かしたいプログラムの中(このプログラムであれば、Sub CalcSum3() と End Sub の間)にカーソルを置いてF5キーを押します。

この方法でもよいのですが、今回はステップ実行というプログラムを1行ずつ動かせる便利な機能を使って動かしてみたいと思います。カーソルを上記のようにプログラムの中に置いた状態でキーボードのF8キーを1回押してみてください。すると下図のように、プログラムの先頭が黄色でハイライトされました。

では、F8キーを2回押してみましょう。すると下図のようにFor文の開始位置がハイライトされました。

ここからF8キーをさらに押して行きますが、今回は、VBE画面の右下に表示されている下図のローカルウィンドウも使いたいと思います。このローカルウィンドウには下図の赤枠部のようにプログラムで宣言した変数の現在の状態が表示されます。

では、ローカルウィンドウの変数iの値の変化を監視しながら、下図のように値が「4」になるまでF8キーを押してみてください。

すると、プログラムにおいては下図のようにIf文がハイライトされたところで止まりました。

ここでプログラムの中の変数iにマウスカーソルを近づけて変数iの内容を確認してみましょう。すると下図のようになりました。ここでも変数iが「4」になっていることが確認できますね。

ということは、このIf文の条件式である、左辺の変数iの内容「4」と右辺の内容(StartNum+3、これは1+3を意味します)が等しくなるので、この条件式は「True(真)」になっていることがわかります。このIf文はまだ実行されていないので、もう1回、F8キーを押してみましょう。

すると下図のようにExit Forの文がハイライトされました。つまり、この命令がこれから実行されるということですね。

ではもう1回、F8キーを押してみましょう。さて、この操作でどの行の命令に処理が移動するでしょうか。そうですね、先ほどお伝えしたように下図のようにDebug.Printの行にプログラムのステップが進みました。

Exit For 文の命令による「For文の中止と次に実行されるプログラムの行への移動」のイメージは下図の赤矢印のようになります。このようにExit For 文には現在実行中のFor~Nextのくくりから外へ(次のプログラムのステップへ)ジャンプする機能があります。またFor~Nextに囲まれた間でのみ利用できる点にご注意ください。

それでは後2回、F8キーを押してプログラムを終了しましょう。すると下図のようにイミディエイトウィンドウに整数の和の結果が表示されます。

今回のプログラムではFor文のループ変数iの初期値が「1」,終了値は「100」ですが、途中にIf文を入れ、ループ変数が「4」になった時点で整数の和を計算する前(Sum=Sum+iの命令を実行する前)に中止しています。その結果「1+2+3」という和までが計算され「6」という結果が表示されました。

※For文を使った整数の和を計算する方法については、下記のブログをご覧ください。
For文を使った整数の和について取り上げたブログはこちら

次の例題のためにイミディエイトウィンドウの内容はクリアしておきましょう。

2-2. GoTo 文を使って中止する

次に実行中のFor文をGoTo文を使って中止する方法をお伝えしたいと思います。まず、プログラムからご覧ください。

Sub TimesTable2()
'変数の宣言
Dim i As Long
Dim j As Long

'九九の計算
For i=1 To 9
    For j=1 To 9
        Debug.Print i & “*” j & “=” i*j
        If (i=1) And (j=3) Then
            GoTo Label
        End If

    Next j
Next i

Label:
Debug.Print "プログラムの終了直前です。"

End Sub

このプログラムは前回のブログでお伝えした九九の計算のプログラムTimesTableを一部改造したもので、九九の掛け算を全て行うのではなく「1の段を3つまで計算したら終了する」プログラムにしてみました。

九九の計算の詳細については前回のブログも合わせてご覧ください。
前回ブログはこちら

前回の九九の計算のプログラムとの違いは、下記の2点が追加されているところです。それぞれについて解説しましたのでご覧ください。

【追加ポイントその1】
If (i = 1) And (j = 3) Then
    GoTo Label
End If

このIf文の意味ですが「 変数iが1と等しく なおかつ 変数jが3と等しい 」場合、Label と書かれた行へジャンプしなさいという意味になります。このIf文がまさに「1の段を3つまで計算したら終了する」処理になります。

If文についてのブログはこちら

今回、GoToとLabelという新しい用語が出てきました。これについて説明します。GoToはGoTo文と呼ばれるものでプログラムを任意の行にジャンプさせる機能があります。このGoTo文を使ってFor文の処理を抜けようというわけです。GoTo文は下記のような使い方をします。

GoTo ラベル名
...
...
ラベル名:

<解説>
GoTo文は、上記のようにGoToと記述した後に、半角スペースを空けた後、自分で決めた「ラベル名」という形式で記載します。また、GoTo文とは別の行(GoToの行からジャンプさせたい行)に「ラベル名:」と記述します。こちらは「ラベル名」の後に半角の「:(コロン)」が付きます。また「ラベル名:」の行はプログラムの命令ではないため、実際のジャンプ先はこの行の次の行以降に来る最初のプログラムの命令の行になることに注意してください。

ラベル名は自分で任意に決めることができますが(Excel-VBAの文法に利用される予約語は除きます)、LabelやLabel1,Label2などラベルとわかるような文字を使うのが一般的です。

今回のプログラムではLabelというラベル名が使われています。

GoTo文の特徴は、一般的にはラベル名をGoTo文より下方の行に配置し、プログラムの順方向(上から下)にジャンプしますが、ラベル名をGoTo文より上方の行に配置し、プログラムの逆方向(下から上)にもジャンプさせることができるということです。そのため自分の好きなようにあちこちにジャンプできるため、プログラムの流れがわかりにくくなるということで、GoTo文の多用は敬遠される傾向にあります。しかし、ケースによってはGoTo文の方がわかりやすかったり、使わざるを得ないこともありますのでケースバイケースといったところです。

GoTo文はFor文の中だけでなく色々な場所で処理をジャンプするために利用することが可能です。

【追加ポイントその2】
Label:
Debug.Print "プログラムの終了直前です。"

この部分は、先ほど解説したGoTo文のジャンプ先になります。「Label:」という行がGoTo文の行からのジャンプ先を表しています。但し、「Label:」の行はプログラムの命令ではないため、実際のジャンプ先はその次の行の命令である「Debug.Print」から始まる行になります。

では、実際にVBEのコード画面にこのプログラムを入力して動かしてみましょう。

先ほど、下図のようにVBEの画面のMo04_Forというモジュールに「CalcSum3」という名前のプログラムを作成しました。今回のブログではこのプログラムの上側にプログラムを入力していきたいと思います。ちょうど赤矢印の部分に入力しましょう。

プログラムを入力すると下図の赤枠部ようになりました。

プログラムは入力できましたでしょうか。それではプログラムを動かしてみましょう。通常、プログラムの動かす場合、動かしたいプログラムの中(このプログラムであれば、Sub TimesTable2() と End Sub の間)にカーソルを置いてF5キーを押します。

この方法でもよいのですが、今回はステップ実行というプログラムを1行ずつ動かせる便利な機能を使って動かしてみたいと思います。カーソルを上記のようにプログラムの中に置いた状態でキーボードのF8キーを1回押してみてください。すると下図のように、プログラムの先頭が黄色でハイライトされました。

では、ここでF8キーを1回押してみましょう。すると下図のようにFor文の開始位置がハイライトされました。

ここからF8キーをさらに押して行きますが、今回は、VBE画面の右下に表示されている下図のローカルウィンドウも使いたいと思います。このローカルウィンドウには下図の赤枠部のようにプログラムで宣言した変数の現在の状態が表示されます。

では、ローカルウィンドウの変数iと変数jの値の変化を監視しながら、下図のように変数iの値が「1」,変数jの値が「3」になるまでF8キーを押してみてください。

すると、プログラムにおいては下図のようにDebug.Printの行がハイライトされたところで止まりました。

ここでプログラムの中の変数iと変数jにマウスカーソルを近づけて変数iと変数jの内容を確認してみましょう。すると下図のようになりました。ここでも変数iが「1」,変数jが「3」になっていることが確認できますね。

まずここで1回、F8キーを押してみましょう。すると、下図のようにイミディエイトウィンドウには九九の1の段の3つまでの結果が表示されます。

また、下図のようにIf文の行が黄色でハイライトされました。先ほど、変数iが「1」,変数jが「3」になっているとお伝えしました。ということはこのIf文の条件式である「 変数iが1と等しく なおかつ 変数jが3と等しい 」という条件に一致することがわかります。このIf文はまだ実行されていないので、もう1回、F8キーを押してみましょう。

すると下図のようにGoTo文の行がハイライトされました。つまり、この命令がこれから実行されるということですね。

ではもう1回、F8キーを押してみましょう。さて、どこにプログラムの命令が移動するでしょうか。そうですね、先ほどお伝えしたように下図のようにDebug.Printの行にプログラムのステップが進みました。

GoTo 文の命令による「For文の中止と次に実行されるプログラムの行への移動」のイメージは下図の赤矢印のようになります。このようにGoTo 文には現在実行中のプログラムの行からラベル名で指定された行(実際には「ラベル名:」と書かれた行の次の行以降に来る最初のプログラムの命令の行へ)ジャンプする機能があります。

それでは後2回、F8キーを押してプログラムを終了しましょう。するとイミディエイトウィンドウには、下図の赤枠部のように「プログラムの終了直前です。」というメッセージが新たに表示されます。

ここまでで、GoTo 文を使ってFor文の処理を中止する方法について見てきました。次の例題のためにイミディエイトウィンドウの内容はクリアしておきましょう。

2-3. Exit For 文についての要注意事項

先ほど「九九の計算を1の段の3つまで計算したら終了する」プログラムの例を見て頂きました。このプログラムでFor文を中止するためにGoTo文を使いましたが、この部分を単純にExit For文に書き換えても同じように動くかというと実はそうではないんです。

九九の計算はFor文を入れ子にした2重ループという構造になっているのですが、Exit For 文は、あくまで現在実行中のFor文の1段外に出るという機能しかもっていないんですね。この点についてわかりにくいかもしれませんので下図のイメージ図をご覧ください。

上図は先ほどの九九の計算のプログラムのGoTo文をExit For文に書き換えて抜粋したものです。また見やすいようにプログラムについて空白行を追加しプログラムの行間隔を少し開けました。

赤矢印の部分がExit For文によってジャンプする先を表しています。本当は2重ループになっているFor文の処理を全て中止して、プログラムの終了する方向へ向かいたいところですが、このプログラムは、外側のNext i の行へプログラムが進んでしまいます。(赤矢印の先端が Next i の行ではなく、Next j と Next i の間に来ていますね。このプログラムでは Next j と Next i の間にプログラムの命令がないので赤矢印は Next i の行を示してもよいのですが、実際のプログラムでは Next j と Next i の間に命令が書かれることもあります。その場合、Next j の直後にある命令から実行されるため、Exit Forのジャンプ先は上図で示した赤矢印の先端の場所と思って差支えありません。)

その結果、九九の計算について、1の段を3つ計算した後、2の段から9の段まで計算して終了する動きになってしまいます。

このようにExit For文は現在のFor文の1つ外側にジャンプする動きしかしないので、今回のような2重ループでは、GoTo文を利用して2つのFor文の外側に一気にジャンプする方法が簡単です。

もしExit For文を使いたい場合は、内側のFor文の中のIf文でGoTo文の行をExit Forに変えた後、さらにNext jの文の直後にIf文を入れて条件判定を行う必要があります。またその際、GoTo文には必須であったジャンプ先のラベルの記述は不要となります。参考までにそのプログラムを下記に掲載しました。プログラムの名前はTimesTable3としました。

Sub TimesTable3()
'変数の宣言
Dim i As Long
Dim j As Long

'九九の計算
For i = 1 To 9
    For j = 1 To 9
        Debug.Print i & "*"; j & "="; i * j
        If (i = 1) And (j = 3) Then
            Exit For
        End If

    Next j
    If (i = 1) And (j = 3) Then
        Exit For
    End If

Next i

Debug.Print "プログラムの終了直前です。"

End Sub

いかがでしょうか。Exit For文を使うとIf文による条件判定が2回必要となりますので、先ほどのGoTo文を使ったプログラムの方がすっきりして見やすいかと思います。

ここまで、Exit For文の注意点についてお伝えしました。

3. For文内の処理をスキップしてFor文の処理を先に進める方法

先ほどまでは、For文を途中で中止してプログラムを終了する方向に向かうプログラムの記述方法をお伝えしましたが、ここでは、ForとNextの間にはさまれた「プログラムの命令」をスキップしてFor文のループ処理を早める方法をお伝えします。For文は命令を繰り返す文なのでループ処理という言い方もしますので覚えておいてください。

まずは、プログラムからご紹介しますね。下記のプログラムは1~100までの奇数の和を計算するプログラムです。プログラムの名前はCalcSum4としました。

Sub CalcSum4()

'変数の宣言
Dim Sum As Long
Dim i As Long

'明示的な変数の初期化
Sum=0

'奇数の和の計算
For i=1 To 100
    if (i Mod 2)=0 Then
        GoTo SkipLabel
    End If
    Sum=Sum+i
SkipLabel:
Next i

'奇数の和の結果を表示
Debug.Print "奇数の和=" & Sum

End Sub

上記のプログラムについて、説明のために各行の先頭に行番号を付けたものが下記になります。※便宜上、行番号を付けていますが、実際には記述しません。また今回は定数を使っていませんがあらかじめご了承ください。

奇数の計算は前回のブログのCalcSumというプログラムでもご紹介していますが、今回のプログラムは、以前のものと書き方が異なります。この点にも注目してください。

前回のブログはこちら

01. Sub CalcSum4()
02.
03. '変数の宣言
04. Dim Sum As Long
05. Dim i As Long
06.
07. '明示的な変数の初期化
08. Sum=0
09.
10. '奇数の和の計算
11. For i=1 To 100
12.     if (i Mod 2)=0 Then
13.         GoTo SkipLabel
14.     End If
15.     Sum=Sum+i
16. SkipLabel:
17. Next i
18.
19. '奇数の和の結果を表示
20. Debug.Print "奇数の和=" & Sum
21.
22. End Sub

<解説>
01,22行目について:
01行目はプログラムの先頭を表し、22行目はプログラムの末尾を表しています。

04,05行目について:
この部分はプログラムで利用する変数を宣言する部分になります。04行目の変数Sumは整数の和の計算結果を保持するためにLong型という整数を格納できるデータ型の変数として用意しました。05行目はFor文を利用するために必要なループ変数になります。ループ変数は通常は整数型として用意しますのでこちらもLong型としました。今回の整数の計算は数が小さいのでどちらともInteger型としてもよいですが、最近のパソコンはメモリーも大きくなっているので整数を扱う場合、全てLong型にしてもまず問題ありません。

変数の型について解説しているブログはこちら
変数の型について解説しているブログはこちら

03,07,10,19行目について:
各行をよく見ると先頭に「'(シングルクォーテーション)」が付いていますね。このような行のことをコメント行と言います。先頭に「'」記号を付けることで、それ以降に書かれた文字はプログラムの命令ではなくプログラムの説明と解釈されます。このような行は命令ではないため何も処理は実行されません。

02,06,09,18,21行目について:
この行は空白行といってプログラムを見やすくするための行となります。先ほどのコメント行と同じで、命令ではないため何も処理は実行されません。

08行目について:
この行には「Sum=0」と書かれています。

先ほど、変数Sumは整数の和の計算結果を格納する変数とお話しました。

「Sum=0」はFor文の処理に入る前に変数の内容を初期化するために記述しました。実は08行目の「Sum=0」は省略可能です。というのはExcel-VBAでは04行目で変数Sumを宣言した後、その変数に何も処理を行っていなければその内容は「0」だからです。ただ、変数の最初の値がどのようなものか、明確にするためにあえて08行目のように初期化することもあります。これを明示的な初期化といいます。他の方がプログラムを見たときに変数Sumは初めは「0」なんだなと分かりやすくなるメリットもあります。

11~17行目について:
この部分で奇数の和を計算しています。特に15行目の「Sum=Sum+i」の部分で和の計算をしていますが、この部分の動きの詳細については前回のブログをご覧ください。

前回のブログはこちら

12~14,16行目について:

この部分が今回のプログラムで最も重要なポイントになります。

12. if (i Mod 2)=0 Then
13.     GoTo SkipLabel
14. End If

まず12行目のIf文でModという新しい用語が出てきました。このModは割り算の余りを求めるもので下記のように記述することで、余りを求めることが可能です。

「割られる数」Mod「割る数」

12行目の意味は「変数iの中身を2で割ったときの余りが0だったら」という意味で、この条件に一致したら13行目のGoTo文を実行する動きになります。

補足になりますが、12行目は if i Mod 2 =0 Then と書くことができますが、私は式の部分が明確になるように式の部分を()で囲って記述しています。

13行目のGoTo文にはSkipLabelというラベル名が書かれていますので、もし12行目の条件に一致し、13行目のGoTo文の行の命令が実行された場合には、16行目の「SkipLabel:」と書かれた行(実際にはこの「SkipLabel:」の次の行以降に来る最初のプログラムの命令の行)にプログラムの処理がジャンプします。

「SkipLabel:」の次の行以降に来る命令は、今回のプログラムでは17行目の「Next i」の命令になりますね。つまり、GoTo文により15行目の和の計算は行われずにスキップして、計算に利用する変数iの内容を次の数に進めるということを行っているのです。

「Next i」 にはループ変数iを次の値(現在の変数iの値+増減値)に更新する役割がありましたね。今回のFor文にはStepの指定がありませんので増減値は「1」となります。

この一連の動きにより、ループ変数iが偶数の場合は和の計算を行わずにスキップして、最終的に奇数だけの和の計算が行われるという動きになるのです。このプログラムの仕組みについて何となくお分かり頂けましたでしょうか?

14行目のEnd If はIf文の終わりを表しています。

16行目は、先ほどもお伝えしましたが、GoTo文からジャンプして飛んでくる場所(ラベル)を表しています。

20行目について:
Debug.Printという命令で奇数の和の計算結果をイミディエイトウィンドウに表示しています。文字の部分は「"(ダブルクォーテーション)」で囲み、この文字と変数Sumの内容を連結するために「&」記号を用いています。

ここまでで、プログラムについて説明してきましたが、実際にVBEのコード画面にCalcSum4のプログラムを入力して動かしてみましょう。

先ほど、下図のようにVBEの画面のMo04_Forというモジュールに「TimesTable2」という名前のプログラムを作成しました。今回のブログではこのプログラムの上側にプログラムを入力していきたいと思います。ちょうど赤矢印の部分に入力しましょう。

プログラムを入力すると下図のようになりました。

プログラムは入力できましたでしょうか。それではプログラムを動かしてみましょう。通常、プログラムの動かす場合、動かしたいプログラムの中(このプログラムであれば、Sub CalcSum4() と End Sub の間)にカーソルを置いてF5キーを押します。

この方法でもよいのですが、今回はステップ実行というプログラムを1行ずつ動かせる便利な機能を使って動かしてみたいと思います。カーソルを上記のようにプログラムの中に置いた状態でキーボードのF8キーを1回押してみてください。すると下図のように、プログラムの先頭が黄色でハイライトされました。

今回は、プログラムのポイントとなる部分を見ていきたいと思います。それではF8キーを2回押してみましょう。すると下図のようにFor文の開始位置がハイライトされました。

ここからF8キーをさらに押して行きますが、今回は、VBE画面の右下に表示されている下図のローカルウィンドウも使いたいと思います。このローカルウィンドウには下図の赤枠部のようにプログラムで宣言した変数の現在の状態が表示されます。

では、ローカルウィンドウの変数iの状態を監視しながら、下図のように変数iの値が「2」になるまでF8キーを押してみてください。

すると、プログラムにおいては下図のようにIfの行がハイライトされたところで止まりました。

ここでプログラムの中の変数iにマウスカーソルを近づけて変数iの内容を確認してみましょう。すると下図のようになりました。ここでも変数iが「2」になっていることが確認できますね。「2」は偶数ですからこのIf文の条件式である「変数iを2で割った余りが0だったら」という条件に一致することがわかります。このIf文はまだ実行されていないので、もう1回、F8キーを押してみましょう。

すると下図のようにGoToの文がハイライトされました。つまり、この命令がこれから実行されるということですね。

ではもう1回、F8キーを押してみましょう。さて、どの行の命令にハイライトが移動するでしょうか。そうですね、先ほどお伝えしたように、GoTo文に記述されたラベル名は「SkipLabel」でそのジャンプ先である「SkipLabel:」の次の行以降に来る最初の命令の行ですから下図のように「Next i」の行にプログラムのステップが進みました。つまり「Sum=Sum+i」という和の計算の行の処理がスキップされたということですね。

「For文内の処理をスキップしてFor文の処理を先に進める方法」のイメージは下図の赤矢印のようになります。

このような流れで、これ以降もループ変数iが偶数の場合は和の計算をスキップする形で処理が続いていきます。

それでは、ここでF5キーを押してプログラムを終了しましょう。すると下図のようにイミディエイトウィンドウには「奇数の和=2500」というメッセージが表示されます。

ここまでで、「For文内の処理をスキップしてFor文の処理を先に進める方法」について見てきました。このようにExcel-VBAではGoTo文とラベル名のセットでこの処理を実現しますが、他のプログラミング言語ではラベル名などは不要でGoTo文の行の部分に「continue;」と書くだけで同じ処理を実現できるものもあります。

4. まとめ

長くなりましたが、今回はFor文の動きを色々コントロールする方法について見てきました。

おつかれまでした!

ブログの続きはこちら

Excel VBA 入門 目次ページ はこちら

本ブログの内容が電子書籍(Kindle)になりました。

スポンサーリンク
Simplicityのレクタングル広告(大)
Simplicityのレクタングル広告(大)

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

%d人のブロガーが「いいね」をつけました。