テーマ
第14回目となる本稿では、For Next という繰り返し構文を学習します。
For Next は、特定の繰り返し処理に特化した構文です。よって For Next で記述可能な繰り返し処理は、前回学習した Do Loop を用いても表現可能です。しかし、For Next を用いることによってその意図をより明確に示すことが出来、可読性が高まるケースがあります。そのようなケースで For Next を使用出来るようになることが本稿の学習テーマとなります。
構文
For Next の構文を確認する前に、その特徴について簡単に触れておきたいと思います。
これが VBA における For Next の特徴です。この特徴から言えることは、For Next による繰り返し処理はあくまで回数指定がなされた繰り返し処理であるという点です。その回数に変数を用いることによって、実行時に回数を変化させることは可能ですが、スマートに無限ループを表現することは出来ません(これは他言語の for とは異なる特徴なので注意が必要です)。このような特徴から、For Next の適用範囲は限定されます。現時点では、この特徴がもたらす影響を完全に理解する必要はありませんが、For Next は回数指定された繰り返しであるという点を頭の片隅に入れておいてください。
それでは早速、その構文を見ていきます。
For カウンター = 最初の値 To 最後の値 Step 整数
繰り返す処理
Next カウンター
For Next はカウンターを用いた繰り返し処理となります。カウンターとは、簡単に言えば整数型の変数であり、数を数えていく変数です。Byte 型、Integer 型、または Long 型の変数を用います。これら整数型の変数に Step で指定した整数を加算することで、繰り返し回数を数えていく変数のことです。
Single 型や Double 型などの実数型の変数はカウンターとしては使用できません(基礎コースにおいて詳細を学習します)し、文字列型も同様にカウンターとして使用することは出来ません。「カウンター変数は整数のみ」と覚えておきましょう。(カウンターに Double などの実数型を指定してもコンパイルエラーとしてくれず、コンパイルされてしまいます。よって論理的に使用不可である型を構文上使用できてしまいますので注意が必要です)。
具体的な処理の流れを確認するために、以下のマクロを Sheet1 シートモジュールに記述してください。
Public Sub Chapter14_For_Next()
Dim counter As Long
Dim message As String
For counter = 0 To 9 Step 1
message = message & CStr(counter) & Strings.Space$(1)
Next counter
Debug.Print message
End Sub
コードの記述を終えたら F5 キーを押して実行してみましょう。イミディエイトウインドウに表示される実行結果は以下の通りです。
0 1 2 3 4 5 6 7 8 9
Dim counter As Long
Dim message As String
Long 型変数で counter を宣言しています。message は String 型変数です。
For counter = 0 To 9 Step 1
message = message & CStr(counter) & Strings.Space$(1)
Next counter
5 行目の For counter = 0 to 9 Step 1 と、
7 行目の Next counter が For Next 構文であり、その中にある 6 行目が実際に繰り返される処理です。 また、今回初めて使用するメソッドもありますので、そちらを先に説明しておきましょう。
Strings.Space$(1)
という記述があります。これは Strings クラスの Space$ メソッドを使用しています。このメソッドのシグネチャ―は以下の通りです。
Space$(ByVal number As Long) As String
つまり、整数型の値を一つ引数に取り、文字列を取得します。このとき取得する文字列は、引数で渡した整数個分半角スペースを繋げた文字列となります。したがって、Strings.Space$(1) という記述によって取得できる文字列は、半角スペース一つの文字列となります。
以上を踏まえ、この For Next の処理過程を見ていきましょう。
For counter = 0 To 9 Step 1 ↑ counter 変数に 0 を代入する。 message = message & CStr(counter) & Strings.Space$(1) ↑ message 変数に "0 " を代入する。 Next counter ↑ counter 変数に 1 を加算( Step 1 の意味)し、counter の値は 1 となる。 message = message & CStr(counter) & Strings.Space$(1) ↑ message 変数に "0 1 " を代入する。 Next counter ↑ counter 変数に 1 を加算し、counter の値は 2 となる。 message = message & CStr(counter) & Strings.Space$(1) ↑ message 変数に "0 1 2 " を代入する。 Next counter ↑ counter 変数に 1 を加算し、counter の値は 3 となる。 counter の値が 9 になるまで上記を繰り返し・・・ message = message & Cstr(counter) & Strings.Space$(1) ↑ message 変数に "0 1 2 3 4 5 6 7 8 9 " を代入する。 Next counter ↑ counter 変数に 1 を加算し、counter の値は 10 となる。 counter 変数の値が 10 となり、counter = 0 To 9 の範囲を超えたので Next の次行である 8 行目に処理が移る。
Debug.Print message
End Sub
8 行目によって現在の message 変数が保持する値がイミディエイトウインドウに表示されます。
如何でしょうか?既に Do Loop による繰り返しを学習済みなので、こちらもそれほど難しくはないと思います。Next counter によって加算される値は、Step 1 で指定した 1 であることを理解し、counter 変数の値が counter = 0 To 9 で指定した counter 変数が取りうる値の範囲内であるときは、Next counter の次に実行されるのは For の次行であること、counter 変数が取りうる値の範囲外であるときは、処理が Next counter の次行へ移るという点が理解出来れば十分です。
この For Next の例では、counter の値は 0 から 9 まで、Next counter を通るたびに 1 ずつ加算され、その間、 For Next の間にある行が実行されます。つまり、10回の繰り返し処理が行われます。
ここで学習内容をまとめておきます。
カウンターの範囲や加算値に変数を用いた場合
それでは、カウンターがとる値の範囲や Step で指定する加算値をコンパイル時には決定せず、実行時に動的に決定する場合の記述の仕方をご紹介しましょう。この例では動的に変化させる値をユーザーから入力してもらう形にします。
以下のコードを Sheet1 シートモジュールへ記述し、実行してみましょう。
Public Sub Chapter14_DynamicForNext()
Dim first As Long
Do
first = Application.InputBox("0 から 9 までの整数を入力してください。", "最初の値", Type:=1)
Loop While (first < 0 Or 9 < first)
Dim last As Long
Do
last = Application.InputBox("0 から 9 までの整数を入力してください。", "最後の値", Type:=1)
Loop While (last < 0 Or 9 < last)
Dim number As Long
Do
Dim condition As Boolean
If first <= last Then
number = Application.InputBox("1 から 3 までの整数を入力してください。", "増分", Type:=1)
condition = (number < 1 Or 3 < number)
Else
number = Application.InputBox("-3 から -1 までの整数を入力してください。", "増分", Type:=1)
condition = (number < -3 Or -1 < number)
End If
Loop While condition
Dim counter As Long
Dim message As String
For counter = first To last Step number
message = message & CStr(counter) & Strings.Space$(1)
Next counter
Debug.Print message
End Sub
実行すると、整数の入力を求められます。入力用ダイアログのタイトルに入力すべき内容が表示されますので、以下の構文を見ながら入力してください。
For カウンター = 最初の値 To 最後の値 Step 増分(整数)
繰り返す処理
Next カウンター
まず「最初の値」の入力を求められます。ここでは例えば 9 を入力します。次に「最後の値」の入力を求められますので、0 を入力してみます。最後に「増分」の入力を求められたら -3 を入力してみましょう。するとイミディエイトウインドウには以下のように表示されます。
9 6 3 0
この入力例では、各変数 first、last、number にそれぞれ入力した値が保持され、それを For 文で利用するため、以下の For 文と同じ機能になります。
For counter = 9 To 0 Step -3
message = message & Cstr(counter) & Strings.Space$(1)
Next counter
そのため、繰り返される文である
message = message & Cstr(counter) & Strings.Space(1)
は、counter の値が 9 であるとき、6 であるとき、3 であるとき、0 であるときに実行され、上記実行結果が得られるのです。増分の値に -3 という負の整数が指定されているので counter の値は Next counter で counter = counter + (-3) という演算が行われているということです。
何度かこのマクロを実行し、好きな値を入力して、想定している実行結果が得られるか試してみましょう。想定していた結果が得られないときは、F8 キーによるステップ実行を行い、どのように処理が進んでいくか、ある時点での変数の値はどのような値になっているか、などを確認しながらその原因を特定してください。コードの入力ミスであるか、For 文の理解不足であるか、ダイアログの入力ミスであるか、そのいずれかが原因です。
省略記法
For Next で最もよく使う形は Step 1 を指定してカウンターを 1 ずつ加算していく形です。そのため、カウンターの加算数が 1 の場合には Step 1 という記述そのものを省略出来ることになっています。
Dim counter As Long
Dim summary As Long
For counter = 0 To 9
summary = summary + 1
Next counter
この例では Step の指定がありません。これは Step 1 を省略しているとみなされ Next counter で counter 変数に 1 が加算されることになります。このように Step が省略されている For Next は大変よく見かけます。実際、カウンターを 1 ずつ加算するループ処理は使用頻度が高いのでこの記述方法にも慣れておいてください。
省略記法にはもう一つあり、それは Next カウンター変数 を単に Next と記述可能であることです。この省略記法も使用する人が多いので慣れておく必要があります。また、本稿の説明ではカウンター変数の変数名として counter を用いてきましたが、カウンター変数には好きな名前をつけることが出来ます。ループで用いるカウンター変数の名前は慣習として i が用いられることが多いです。
Dim i As Long
For i = 0 To 9
Debug.Print i
Next
この例ではカウンター変数として i を使用し、Step 1 や Next i を省略記法で記述しています。
まとめ
本稿では、反復構造である For Next を学習しました。数種類存在する繰り返し構造の中でも For Next は最も使用頻度の高い構文です。今すぐにこれを覚える必要はありませんが、プログラミングをする上では何度も遭遇する記述なので、忘れてしまったときは本稿に戻って復習してください。
まとめておきます。