Excel VBAをつかって実務を効率的にすすめるマクロを作りたい。その上で欠かせないのが、繰り返し処理です。繰り返し処理は、データを大量にあつかう処理や、何百回、何千回、何万回と同じ作業をする場面においてなどに真価を発揮します。
繰り返しが必要な作業は身の回りにたくさんあります。
例えば、毎月●日に会議がある予定をカレンダーに書きこむことや、継続しているサービスや商品販売における請求書を発行することなど、職場によってはこれらの作業を事務スタッフとして働く人が期限に追われながら処理している可能性もあります。
しかし、こういったある程度の型が決まった作業は、一度マクロを作ってしまえば劇的に負担を減らすことができます。ただし、繰り返し処理をするマクロ作るには、VBAでFor Nextや、Do Loopなどの繰り返し文の使いかたを理解することが重要です。
本記事では、VBAの繰り返し処理について基礎から解説し、実際のコード例を交えながらマクロのつくりかたをわかりやすく紹介します。
なお、繰り返し処理の内、以前の文字入力を制限する方法として紹介した記事でも触れたDo While文やDo Until文については重なる部分はありますが、以前の記事では、使用用途を限定した紹介であったため、こちらでは繰り返し処理文の基本的な書き方を用いて紹介しています。
【結論】繰り返し処理はFor Next文またはDo Loop文をつかう
エクセルVBAで繰り返し処理をするマクロを作るために必要なステートメントは4つあります。
それぞれの特徴は以下のとおりです。
For Nextステートメント
For Nextの特徴
指定した回数だけ処理を繰り返すことができる。
指定した変数に対して、指定した増量分で値を更新しながら繰り返し処理を行うことができる。
ループ変数を外部から参照することができないため、処理の安全性が高い。
ネスト(入れ子)されたFor Nextステートメントを使用することで、複雑な処理を実行することができる。
VBAで繰り返しと言えば、ForNextステートメントと言えるくらいよく使われる。
For Eachステートメント
For Eachの特徴
指定したオブジェクトの全ての要素に対して処理を繰り返すことができる。
オブジェクト内の要素をループ変数に自動的に代入するため、要素の数を数える必要がない。
配列やコレクション、セル範囲などのデータ構造に対して簡単にループ処理を実行することができる。
ループ変数を外部から参照することができないため、処理の安全性が高い。
シートなどのオブジェクトに対する繰り返し処理に使いやすい。
Do Whileステートメント
Do Whileの特徴
指定した条件がTrueの場合に処理を繰り返すことができる。
条件式を最初に評価するため、条件式がFalseの場合は一度も処理を実行しない。
ループ内でループ変数を自動的に更新することができないため、手動で値を更新する必要がある。
Exit Doステートメントを使用することで、ループ処理を途中で終了することができる。
条件が満たされている間は繰り返すといった状況で使う。
Do Untilステートメント
Do Untilの特徴
指定した条件がFalseの場合に処理を繰り返すことができる。
条件式を最初に評価するため、条件式がTrueの場合は一度も処理を実行しない。
ループ内でループ変数を自動的に更新することができないため、手動で値を更新する必要がある。
Exit Doステートメントを使用することで、ループ処理を途中で終了することができる。
条件が満たされない間は繰り返すといった状況で使う。
次項より、VBAの繰り返し文の基本的な説明とそれぞれの書きかたについて詳しくみていきます。
オンラインスクールで現役エンジニアのサポートがあるテックアカデミーがおすすめ。
スキマ時間に学べて仕事も保証。必ず副業、始められます。まずは無料でプログラミング体験
エクセルVBAにおけるFor Next文やDo Loop文の繰り返し処理マクロ
本記事の概要
この記事では、エクセルVBAで繰り返し処理を実行するマクロのつくりかたを紹介します。
VBAには、For Nextステートメント、For Eachステートメント、Do Whileステートメント、Do Untilステートメントなど、複数の繰り返し処理の書きかたが用意されています。
それぞれのステートメントの特徴や使い方を詳しく解説し、実際のコード例を交えて具体的な使い方を紹介します。
また、繰り返し処理のネストや、ループ内での条件分岐など、より複雑な処理の実現方法についても触れます。この記事を読むことで、VBAで繰り返し処理を実行する方法を理解し、効率的なプログラミングを行うことができます。
※ここでは、コンピュータープログラムの繰り返し処理を構成するための手続きや命令における文やブロックを、ステートメントと表現していますが、これはプログラミングという分野の学習を進める上で必ず出会う単語であり、恐らく本ブログを訪れた人は、他のウェブサイトを閲覧する機会があることを想定した表現としています。横文字表現が苦手な人も、表現を難しくとらえずに単なる作法(書きかた)と理解してもらえれば幸いです。
VBAにおける繰り返し(ループ)処理についての基礎知識
繰り返し処理とは、同じ操作や条件にしたがった操作を何度も繰り返して実行することです。
Excel VBAでは、ループ処理を使って繰り返し処理を実装できます。
ループ処理をするマクロを書く方法としては、大きく分けて以下の2つとなります。
Forの繰り返しは『回数指定』、Doでの繰り返しは『条件指定』とおぼえてね。
For Nextステートメントの構文とサンプルコード
For Nextステートメントは、指定した回数だけ同じ処理を繰り返します。For Nextステートメントは、次のような構文を持ちます。
For Nextステートメントの構文
For 変数 = 初期値 To 終了値 Step 増分
処理
Next 変数
ForからNextの間に繰り返し実行する処理を書くよ。
For Nextステートメントのサンプルマクロ
以下のサンプルコードでは、イミディエイトウィンドウに1から10の数値を表示します。
サンプルマクロ
Option Explicit
Sub sample()
Dim i As Long
For i = 1 To 10
Debug.Print i'イミディエイトウィンドウに1~10を表示する
Next i
End Sub
以下のサンプルコードでは、シート1の(A1)セルから(I9)セルの範囲に九九の表を作成します。
サンプルマクロ2
Option Explicit
Sub 繰り返しで九九を計算する()
Dim i As Long, j As Long '繰り返し用の変数を宣言する
For i = 1 To 9 'For Next文で変数 i が1~9まで繰り返す
For j = 1 To 9 'For Next文で変数 j が1~9まで繰り返す
ThisWorkbook.Sheets(1).Cells(i, j) = i * j 'i * jで掛け算の結果をセルに入力する
Next j
Next i
End Sub
上記のサンプルマクロでは、For Next文の内側にFor Next文を書いてネスト(入れ子)しています。
これによって、外側のFor文で使用している変数 i が1の間に変数 j は1~9と変わっていき、最も内側に書かれたセルに値を書きこむ処理が繰り返されます。
また、変数 i と変数 j は値を書きこむセルの位置の役割もしているため、具体的には以下のように処理が進みます。
- 外側のFor Next文で変数iに1が代入されているときの処理
- 変数jの1巡目では、jは1となるため、セル1行目・1列目に1×1の値を書きこむ。
- 変数jの2巡目では、jは2となるため、セル1行目・2列目に1×2の値を書きこむ。
- 変数jの3巡目では、jは3となるため、セル1行目・3列目に1×3の値を書きこむ。
- 変数jの4巡目では、jは4となるため、セル1行目・4列目に1×4の値を書きこむ。
- 変数jの5巡目では、jは5となるため、セル1行目・5列目に1×5の値を書きこむ。
- 変数jの6巡目では、jは6となるため、セル1行目・6列目に1×6の値を書きこむ。
- 変数jの7巡目では、jは7となるため、セル1行目・7列目に1×7の値を書きこむ。
- 変数jの8巡目では、jは8となるため、セル1行目・8列目に1×8の値を書きこむ。
- 変数jの9巡目では、jは9となるため、セル1行目・9列目に1×9の値を書きこむ。
- 変数iの2巡目が開始され、変数iに2が代入されているときの処理
- 変数jの1巡目では、jは1となるため、セル2行目・1列目に2×1の値を書きこむ。
…変数 i が9のときまでつづく
9行・9(I)列のセル範囲に九九の表を作成したよ。
話題のChatGPTでもプログラミングができることを知っていますか。
メッセージを入力するだけで、プログラミングコードを返してくれるから、VBAを学ぶツールとしても活用できます。ChatGPTをつかってマクロの作成を検証した記事は以下から読むことができます。
For Eachステートメントの構文とサンプルコード
VBAのFor Eachステートメントは、配列やコレクションなどの要素を反復処理するために使用されます。For Eachステートメントは、次のような構文を持ちます。
For Eachステートメントの構文
For Each 要素 In コレクション
処理
Next 要素
コレクションがオブジェクトなら要素はオブジェクト型の変数で宣言、配列であればバリアント型の変数で宣言することに注意が必要です。
サンプルマクロ
Option Explicit
Sub sample()
Dim arr() As Variant'バリアント型で宣言する
arr = Array(1, 2, 3, 4, 5)'Array関数で配列を作成し、arrに代入する
Dim num As Variant
For Each num In arr'配列の要素数分繰り返す
MsgBox num'メッセージボックスで1~5を表示する
Next num
End Sub
For Eachステートメントは、かたまりや集合体のすべてに対して一つずつ取り出して処理をします。サンプルマクロでは、Array関数を使って変数 arr に対して[1・2・3・4・5]が代入されています。
Array関数は、Variant型で宣言された変数にカンマ区切りで複数の値を代入することができる関数です。
つまり、変数 arr は[1・2・3・4・5]の数値の要素を持ったかたまり・集合体となっています。
そして本題のFor Eachステートメントを使って、変数 arr の要素を変数 num に一つずつ取り出し、すべての要素に対して処理を実行します。
サンプルマクロでは、For Eachステートメント内の処理はメッセージボックスに変数 num に代入された数値を表示します。
メッセージボックスに1~5の数字が表示できたね。
Do Whileステートメントの構文とサンプルコード
Do Whileステートメントは、条件がTrueの間だけ同じ処理を繰り返します。以下のように書きます。
Do Whileステートメントの構文
Do While 条件式
処理
Loop
サンプルマクロ
Option Explicit
Sub sample()
Dim i As Long
i = 1
Do While i <= 5
Debug.Print i'イミディエイトウィンドウに1~5を表示する
i = i + 1
Loop
End Sub
Do LoopステートメントはFor Nextステートメントと異なり、回数を指定するのではなく条件を指定します。For Nextステートメントで、変数 i が1~5の時に処理を繰り返すマクロと同等にする場合は、Do Loopステートメントでは以下のように書くことができます。
Do While i <= 5
なお、Do Loopステートメントには、WhileとUntilがあるので、それぞれに合わせて条件を指定します。
Whileは条件判定がTrueであれば繰り返しを継続するため、変数 i が5以下の間であれば処理を繰り返します。
Do Loopステートメントを使うときの注意点としては、変数の値である数値を更新することです。
サンプルマクロの場合「 i = i + 1」がそれに当たりますが、これを書き忘れると変数 i は1のままとなり、無限ループが発生します。
Do Untilステートメントの構文とサンプルコード
Do Untilステートメントは、条件がFalseの間だけ同じ処理を繰り返します。以下のように書きます。
Do Untilステートメントの構文
Do Until 条件式
処理
Loop
サンプルマクロ
Option Explicit
Sub sample()
Dim i As Long
i = 1
Do Until i > 5
Debug.Print i'イミディエイトウィンドウに1~5を表示する
i = i + 1
Loop
End Sub
Do LoopステートメントはFor Nextと異なり、回数を指定するのではなく条件を指定します。
For Nextステートメントで、変数 i が1~5の時に処理を繰り返すマクロと同等にする場合は、Do Loopステートメントでは以下のように書くことができます。
Do Until i > 5
なお、Do Loopステートメントには、WhileとUntilがあるので、それぞれに合わせて条件を指定します。
Untilは条件判定がFalseであれば、繰り返しを継続するため、変数 i が5以下の間であれば処理を繰り返します。
Do Loopステートメントを使うときの注意点としては、変数の値である数値を更新することです。
サンプルマクロの場合「 i = i + 1」がそれに当たりますが、これを書き忘れると変数 i は1のままとなり、無限ループが発生します。
繰り返し構文の書きかたとサンプルマクロのまとめ
For Next、For Each、Do Loopなどの特性を理解して、適切なステートメント使うことで正確な分量の処理が実行できるようになります。
例えば、エクセルシートの表に対して、何かの処理をするマクロを作成するにあたり、処理回数は”最終行まで繰り返す”のか、または”空白行になるまで繰り返す”のかでも、For文をつかう人もいれば、Do Loop文で書く人もいます。
どちらが正しいということはないですが、関連書籍やインターネット上の記事・YouTubeの動画を参考にすると、それぞれの特徴から最終行まで繰り返す場合はFor文が多い。一方、空白行になるまでの場合はDo Loop文を使っているものを多く見かけます。
いずれにしても、For文で条件判定をしたいのであれば、If文などの条件判定と組み合わせをすること。Do Loop文で回数の指定をしたいのであれば、不等号のつけかたや変数の更新を書きわすれないことなどの注意点をおさえておくことが大切です。
ExcelVBAで繰り返し処理を行うことの重要性
Excel VBAで繰り返し処理を行うことは、プログラムの効率性を高めるために非常に重要です。
例えば、同じような処理を何度も行う場合、繰り返し処理を使えばコードを簡潔にまとめることができます。また、大量のデータを扱う場合には、繰り返し処理を使用することで、手動で1つずつ処理を行うよりも効率的にデータを処理できます。
さらに、繰り返し処理を使えば、複雑な処理も実現できます。Excel VBAでは、繰り返し処理の中で条件分岐ができます。これにより、複雑な条件に応じて、処理の流れの制御ができます。
繰り返し処理を使うことで、プログラムの作成時間やメモリ使用量を削減できます。より効率的なコードを書くことができれば、プログラムの実行速度も向上し、大規模な処理でも高速に処理ができます。
繰り返しと条件分岐が使えると、ほとんどの処理はプログラムでできるよ。
ExcelVBAにおける繰り返し処理の種類とそれぞれの使いどころ
繰り返し(ループ)処理の種類について
既に紹介していますが、繰り返し(ループ)処理の書き方については、以下の4種類があります。
それぞれの特徴については、本記事の冒頭で紹介しましたのでこちらでは最低限のみで記載します。
ステートメントの種類 | 特徴(概要) |
---|---|
For Nextステートメント | 繰り返す回数を指定することができる |
For Eachステートメント | オブジェクトや配列を網羅的に処理することができる |
Do Whileステートメント | 条件判定でTrueの間は繰り返すことができる |
Do Untilステートメント | 条件判定でFalseの間は繰り返すことができる |
For Nextステートメントのつかいどころ
For Nextステートメントは、処理を繰り返す回数が事前に分かっている場合に有効です。例えば5回繰り返したい、10行分だけ繰り返したいなど具体的な回数を指定する場合に使います。
また、エクセルワークシート上の表の処理では、行数分や、列数分を繰りかえすといったコードをよく使います。これらをうまく使うためには、表の最終行や、最終列を数値で取得し、For Next文の指定回数として利用します。
ワークシート上に書かれた表の最終行や、最終列の取得方法については、別の記事で紹介しているため、ここでは詳しく紹介しませんが、詳しく知りたい人は以下の記事をご覧ください。
For Eachステートメントのつかいどころ
For Eachステートメントは、配列やオブジェクトなどに対して全ての要素に対して繰り返し処理するときに便利です。例えばエクセルを新規作成時、ワークシートの数は1つだけですが、複数のワークシート分の処理が必要な場合や、特定のワークシートのセル範囲を網羅的に処理したい場合につかえます。
コレクション(複数の集合体)から、1つずつ取り出して順番に処理を繰り返していくようなイメージをすると分かりやすいかもしれません。
かたまりや集合体から一つずつ取り出すイメージだね。
Do Whileステートメントのつかいどころ
Do Whileステートメントは条件式を指定して、この式に一致している間は処理を繰り返します。
使いどころとして、繰り返し(ループ)の実行回数が不明な場合に使います。
具体的に言えば、ユーザーに入力ボックスを表示して、許容されない文字が入力されている間は処理を繰り返す。他にも、表の各行に対して処理を繰り返すマクロでは、セルに入力されている値が空欄でない間は繰り返す。など、実行するタイミングや、状況で条件を判定しながら繰り返す回数に対応した処理が可能です。
Do Untilステートメントのつかいどころ
Do Untilステートメントは条件式を指定して、この式に一致するまでの間は処理を繰り返します。
UntilとWhileは逆説の条件ですが、こちらもWhileと同じく繰り返し(ループ)の実行回数が不明な場合に使います。
例えば、ある変数の値が10になるまで処理を繰り返す。他にも、表の各行に対して処理を繰り返すマクロでは、セルに入力されている値が空欄になるまで繰り返す。など、実行するタイミングや、状況で条件を判定しながら繰り返す回数に対応した処理が可能です。
なぜ、膨大な事務作業でも定時で退社できるのか。
実務をプロから学べる「ユースフル」の動画は永年見放題。Q&A機能で分からないを放置しないから安心。
詳しくは以下のリンクをクリック
ExcelVBAでそれぞれの繰り返し文による実装方法
ExcelVBAで繰り返し処理を実装方法について
ここでは、それぞれの繰り返し文の実装方法を紹介していきます。
サンプルコードでは、内容を理解しやすくするために、For Nextステートメント、For Eachステートメント、Do Whileステートメント、Do Untilステートメントの4種類で同じ実行結果(イミディエイトウィンドウに1から10の数値の出力)となるコードを書いています。
実行結果は同じなので、先に実行結果をお見せした上で、それぞれのステートメントをつかったコードを紹介していきます。
1
2
3
4
5
6
7
8
9
10
イミディエイトウィンドウに数字の1から10までを表示するマクロだよ。
それでは、このマクロをそれぞれの繰り返し文で書き比べてみていきます。
For Nextステートメントの実装方法
For Nextをつかったくり返し処理のサンプルマクロ
Option Explicit
Sub ForNextステートメント()
'カウンタ変数を宣言する
Dim count As Integer
'For Nextステートメントで変数countは1から10まで繰り返す
For count = 1 To 10
Debug.Print (count) '繰り返す処理を記述する
Next count
End Sub
変数[count]が1のときから10まで繰り返す。数値で回数を指定しているところがポイントです。
For Eachステートメントの実装方法
For Eachをつかったくり返し処理のサンプルマクロ
Option Explicit
Sub ForEachステートメント()
'配列の宣言と初期化
Dim myArray As Variant
'配列にArray関数つかって1から10の数値を代入する
myArray = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
'要素を代入する変数itemを宣言する(バリアント型)
Dim item As Variant
'For Eachステートメントをつかって配列内の要素数分の処理を繰り返す
For Each item In myArray
Debug.Print item '繰り返す処理を記述する
Next item
End Sub
配列[myArray]の要素数の数だけ繰り返すところがポイントです。
Do Whileステートメントの実装方法
Do Whileをつかったくり返し処理のサンプルマクロ
Option Explicit
Sub DoWhileステートメント()
'カウンタ変数を宣言し、1を代入する
Dim count As Integer: count = 1
'Do Whileステートメントをつかってcountが10になるまでの間繰り返す
Do While count <= 10
Debug.Print (count) '繰り返す処理を記述する
count = count + 1 '変数countに1を足す(※書かないと無限ループします)
Loop
End Sub
条件式で、変数[count]が10以下の条件である間は繰り返すといった指定方法がポイントです。
Do Untilステートメントの実装方法
Do Untilをつかったくり返し処理のサンプルマクロ
Option Explicit
Sub DoUntilステートメント()
'カウンタ変数を宣言し、1を代入する
Dim count As Integer: count = 1
'Do Untilステートメントをつかってcountが10になるまで繰り返す
Do Until count > 10
Debug.Print (count) '繰り返す処理を記述する
count = count + 1 '変数countに1を足す(※書かないと無限ループします)
Loop
End Sub
条件式で、変数[count]が10よりも大きくなるまでは繰り返すといった指定方法がポイントです。
繰り返し(ループ)処理のコードの制御構文の比較
ここでは、前項で紹介した繰り返し処理のステートメントの制御構文を比較していきます。
For Nexrステートメントを使ったマクロのコード
Option Explicit
Sub ForNextステートメント()
'カウンタ変数を宣言する
Dim count As Integer
'For Nextステートメントで変数countは1から10まで繰り返す
For count = 1 To 10
Debug.Print (count) '繰り返す処理を記述する
Next count
End Sub
For Eachステートメントを使ったマクロのコード
Option Explicit Sub ForEachステートメント() '配列の宣言と初期化 Dim myArray As Variant '配列にArray関数つかって1から10の数値を代入する myArray = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) '要素を代入する変数itemを宣言する(バリアント型) Dim item As Variant 'For Eachステートメントをつかって配列内の要素分の回数繰り返す For Each item In myArray Debug.Print item '繰り返す処理を記述する Next item End Sub
For NextとFor Eachステートメントの比較で注目しておきたい点は、宣言する変数のデータ型です。
※変数のデータ型については、こちらの記事で紹介しています。
For Nextは繰り返す回数を指定できるステートメントなので、宣言した変数 count は整数型に指定し、数値の1~10が処理の度に1ずつカウントしていきます。
なお、この場合は別途 count = 1 の変数に値を代入するコードは不要です。かわりにFor count = 1 To 10 のコードが変数 count に1~10を代入しています。
もっと言えば、For Nextよりも前に変数 count に値の代入をしていても、繰り返し処理の中では、変数 count は1~10の値に書き変わってしまう点はおぼえておきましょう。
For Nextステートメントの末尾にある Next count の部分で変数 count に代入された数値に1が加算されます。For Nextでは、ループごとにステップする数の指定もできます。Stepを指定した場合は、加算される指定した数値に応じて加算されます。
一方、For Eachステートメントでは、繰り返す回数を指定するのではなく、集合体となる配列やオブジェクトの要素の数だけ繰り返します。
ここでは、バリアント型の変数 myArrayを配列として宣言し、Array関数で1~10の数値を代入しています。これにより、10コの要素(数値)の集合体となった myArray に対する繰り返す回数は10回になります。
そして、For eachステートメントでは、取り出した要素を代入するための変数をつかいます。サンプルコードでは、itemという名前の変数を宣言していますが、要素を代入する変数はバリアント(Variant)型でなければエラーが生じる点には注意が必要です。
※集合体がオブジェクトなら、object型でも実行が可能です。例えば、セル範囲を集合体として、一つのセルを要素として全セル分繰り返し処理をするのであれば、宣言する変数は、object(Range)型でも実行が可能です。
集合体や、要素のデータ型について分かっているのであればそれに合わせた型を利用できますが、データ型についての理解が不安であれば、バリアント型を利用しましょう。
For Eachはブドウを一粒ずつ取って何かを処理するといった感じだね。
Do Whileステートメントを使ったマクロのコード
Option Explicit
Sub DoWhileステートメント()
'カウンタ変数を宣言し、1を代入する
Dim count As Integer: count = 1
'Do Whileステートメントをつかってcountが10になるまでの間繰り返す
Do While count <= 10
Debug.Print (count) '繰り返す処理を記述する
count = count + 1 '変数countに1を足す(※書かないと無限ループします)
Loop
End Sub
Do Untilステートメントを使ったマクロのコード
Option Explicit
Sub DoWhileステートメント()
'カウンタ変数を宣言し、1を代入する
Dim count As Integer: count = 1
'Do Whileステートメントをつかってcountが10になるまでの間繰り返す
Do While count <= 10
Debug.Print (count) '繰り返す処理を記述する
count = count + 1 '変数countに1を足す(※書かないと無限ループします)
Loop
End Sub
Do WhileとDo Untilステートメントでは、Forステートメントのように回数や集合体の要素数分を繰り返すのではなく、条件を指定します。
Whileは、条件判定の結果がTrueの間は処理を継続し、判定結果がFalseになった時点で終了します。一方でUntilでは、条件判定がFalseの間は処理を継続。Tureになったら終了します。
サンプルコードのコメントでも分かるとおり、Do WhileやUntilステートメントでは、Forステートメントのように末尾にNextがないので、無限ループを回避するための対策として、繰り返しのたびに変数 count に+1の処理を実行しています。
繰り返し(ループ)変数の使い方や変数のスコープについて
ここまでで、VBAで繰り返し処理を行う場合、For NextステートメントやDo Loopステートメントを使用することが一般的であることは理解できたかと思います。
これらのステートメントでは、繰り返し(ループ)変数を使用する手段が多くつかわれます。繰り返し(ループ)変数とは、繰り返しの処理内で変化する変数ですが、ここでは繰り返し(ループ)変数のつかいかたのポイントと変数のスコープについて説明します。
繰り返し(ループ)変数のつかいかたのポイント
繰り返し(ループ)変数の初期値を設定する
繰り返し(ループ)変数を使用する場合、最初に変数の初期値を設定する必要があります。初期値を設定しない場合、繰り返しが正しく動作しない可能性があります。
繰り返し(ループ)変数の値を更新する
繰り返し(ループ)内で、繰り返し(ループ)変数の値を更新することが必要です。更新しない場合、繰り返し(ループ)が正しく動作しない可能性があります。For Nextステートメントでは、繰り返し文の中で更新されていきますが、Do Loopステートメントでは、繰り返し用に利用する変数を更新する処理を忘れないようにしましょう。
繰り返し(ループ)変数の値を使用する
繰り返し(ループ)内で、繰り返し(ループ)変数の値を使用することができます。例えば、繰り返し(ループ)変数の値に応じて処理を分岐したり、処理をするセルのアドレスを指定するときに使うなどの様々な用途があります。
変数のスコープ(適用範囲)について
変数のスコープとは、変数の適用範囲のことです。
ここではVBAにおける変数の適用範囲(スコープ)について紹介します。スコープについて詳しく説明するためには、VBAにおけるモジュールやプロシージャなどの単位・範囲の事前説明が必要だと考えているため、以下の記事で詳しい内容を解説していますので、以下のリンクより記事をご覧ください。
\変数のスコープについての記事は以下をクリック/
モジュールレベルの変数[Public/Private]
モジュールの宣言セクションに記入ができます。
モジュールレベルの変数において、Publicで宣言したものは、他のモジュールからも使用ができます。
例えば、Module1で宣言した変数をModule2をつかって値の代入ができます。これはグローバル変数と呼ばれたりもしますが、広い範囲で変数を利用できるメリットの反面、処理があちらこちらに飛んでいくのでプログラム全体の可読性が悪くなるデメリットを発生させることを理解しておきましょう。
一方、Privateで宣言したモジュールのスコープは、同じモジュール内で使用ができます。同じモジュール内の他プロシージャからでも使用ができます。
プロシージャレベルの変数
プロシージャレベルの変数は、変数を宣言したプロシージャ内でのみ使用ができます。プロシージャレベルの変数は、プロシージャの先頭でDimステートメントを使用して宣言できます。こちらはローカル変数と呼ばれ、プロシージャ実行中のみの有効期間となる変数です。
この記事内で書いているコードであれば、プロシージャレベルの変数で大丈夫だよ。
それでは、以下のサンプルマクロで見ていきましょう。
モジュール1に入力したサンプルマクロ
Option Explicit '-----ここが宣言セクション----- Dim A As String 'Privateと同じあつかいになる Private B As String 'プライベート(このモジュールの範囲で利用できる) Public C As String 'パブリック(モジュールの範囲外からでも利用できる) '--------------------------- Sub 変数のスコープサンプル1() Dim D As String A = "これは宣言セクションで宣言された変数Aです。" B = "これは宣言セクションで宣言されたプライベート変数Bです。" C = "これは宣言セクションで宣言されたパブリック変数Cです。" D = "これはプロシージャ内で宣言された変数Dです。" Debug.Print A Debug.Print B Debug.Print C Debug.Print D End Sub Sub 変数のスコープサンプル2() A = "これは宣言セクションで宣言された変数Aです。" B = "これは宣言セクションで宣言されたプライベート変数Bです。" C = "これは宣言セクションで宣言されたパブリック変数Cです。" D = "これはプロシージャ内で宣言された変数Dです。" Debug.Print A Debug.Print B Debug.Print C Debug.Print D End Sub
モジュール2に入力したサンプルマクロ
Option Explicit Sub 変数のスコープサンプル3() A = "これはモジュール1の宣言セクションで宣言された変数Aです。" B = "これはこれはモジュール1の宣言セクションで宣言されたプライベート変数Bです。" C = "これはこれはモジュール1の宣言セクションで宣言されたパブリック変数Cです。" D = "これはこれはモジュール1のプロシージャ内で宣言された変数Dです。" Debug.Print A Debug.Print B Debug.Print C Debug.Print D End Sub
上記のマクロは2つの標準モジュール(モジュール1とモジュール2)があります。モジュール1では、宣言セクションで宣言方法のちがう変数 A B Cを宣言し、モジュール1に属するプロシージャ(変数のスコープサンプル1)で変数 D を宣言しています。
つまり、変数は全部で4つ(A・B・C・D)がある状態ですが、宣言している場所や宣言方法を表にすると以下のようになっています。
モジュール名 | 変数名 | 宣言方法 |
---|---|---|
モジュール1 | A | 宣言セクションでDimをつかって宣言 |
B | 宣言セクションでPrivateをつかって宣言 | |
C | 宣言セクションでPublicをつかって宣言 | |
D | プロシージャ(変数のスコープサンプル1)でDimをつかって宣言 |
それぞれのプロシージャから4つの変数に値を代入できるか、変数に代入した値が出力できるかの結果をみていきます。
変数のスコープサンプル1()プロシージャを実行したとき
まずは、モジュール1の”変数のスコープサンプル1()”プロシージャを実行した場合ですが、これはすべての変数に文字列を代入することも、代入した値を出力もできます。当然ですが、変数 A・B・C がモジュール1で宣言されたものであり、変数 D もプロシージャ内で宣言しているので、同じプロシージャ内の変数、同じモジュール内の変数であるためです。
変数のスコープサンプル2()プロシージャを実行したとき
次に、モジュール1の”変数のスコープサンプル2()”プロシージャを実行するとエラーが発生します。変数 A・B・Cについては、サンプル1プロシージャと同様に値の代入や出力が可能ですが、変数 D についてはこちらのプロシージャで宣言されていないためエラーが発生します。
変数のスコープサンプル3()プロシージャを実行したとき
さいごに、モジュール2の”変数のスコープサンプル3()”プロシージャを実行した場合ですが、こちらもエラーが発生します。変数 D があつかえない理由については、スコープがプロシージャの範囲のため、”変数のスコープサンプル2()”プロシージャと同じ理由です。
また、他の変数 A・B・C は、モジュール1の宣言セクションで宣言したものですので、異なるモジュールで宣言されています。3つの変数の中でこのプロシージャであつかえる変数は、Publicをつかって宣言した変数 C のみです。
なお、宣言セクションで宣言した変数 A ですが、Dimを使って宣言している場合、Privateと同様のあつかいになることは覚えておいてください。
宣言セクションで宣言した変数AとBは同じスコープになるんだね。
モジュールとプロシージャのイメージ図
プロシージャ別の実行結果とエラーの理由
プロシージャ名 | 実行結果 | エラー原因 |
---|---|---|
変数のスコープサンプル1 | 変数への値の代入・出力が可能 | ― |
変数のスコープサンプル2 | エラーが発生する | 変数Dと異なるプロシージャであるため |
変数のスコープサンプル3 | エラーが発生する | 変数 A・B・D と異なるモジュール・プロシージャであるため |
パブリックやプライベート変数をあつかったコードで可読性が悪くなるケース
前項で変数のスコープ(適用範囲)についてざっくりと紹介しましたが、宣言セクションで宣言した変数についてパブリックで宣言したものなら、他モジュールからの利用ができること、プライベートで宣言したものでも同じモジュールの他プロシージャから利用できます。
ただし、他のプロシージャやモジュールから利用できることはメリットだけを生むわけではないことを知っておいてください。
デメリットを生むケースとして、例えば以下のような場合があります。
繰り返し変数を他のプロシージャで変更するケース
次のサンプルマクロでは、For Nextステートメントで繰り返しの処理に利用する変数 kurikaeshi を宣言して、繰り返し回数を数えることに利用しています。
そして、繰り返しの処理の中で変数 kurikaeshi に代入された値をデバッグプリントでイミディエイトウィンドウに出力するだけのシンプルなマクロです。
くり返し変数を他のプロシージャで変更するサンプルマクロ
Option Explicit '繰り返し処理で利用するモジュール変数をプライベートで宣言する Private kurikaeshi As Long Sub 繰り返し変数をプロシージャの外で書きかえる() '繰り返し変数が1~10の間繰り返す For kurikaeshi = 1 To 3 '変数に代入された値をイミディエイトウィンドウに出力する Debug.Print kurikaeshi '変数を書き換えるという名前のプロシージャを呼び出す Call 変数を書き換える(kurikaeshi) '変数に代入された値をイミディエイトウィンドウに出力する Debug.Print kurikaeshi Next kurikaeshi End Sub Function 変数を書き換える(kurikaeshi As Long) As Long '変数に代入された値から1をひく kurikaeshi = kurikaeshi - 1 'Functionプロシージャの戻り値として返す 変数を書き換える = kurikaeshi End Function
上記のマクロを実行すると、イミディエイトウィンドウには以下のとおり表示されます。
1
0
1
0
1
0
…
変数 kurikaeshi に1~3の数字が入っている間は処理を繰り返します。ですが、実行結果では1と0を繰り返し出力してしまっています。つまり、こちらのマクロではくり返しが終了する3を超えることがなく無限ループが発生してしまっています。
無限ループが発生する原因は、For Nextの中のCallステートメントで、別のFunctionプロシージャ(変数を書きかえる)を呼び出すときに、引数として変数 kurikaeshi を引き継いでおり、呼び出されたFunctionプロシージャで変数 kurikaesh に代入された値から1をひく処理をしているためです。
これは、まさに変数のスコープ(適用範囲)を広くしたことによって発生してしまうデメリットと言えるでしょう。この規模のマクロであれば、原因や修正に手がかかりませんが、変数をたくさんあつかうような大規模なマクロでは、もっと複雑になるためサンプルのような変数の変更は控えたほうが無難であると言えるでしょう。
このように、一見するとスコープ(適用範囲)が広くなることで、少ない変数で効率的にマクロを作成することができるように考えてしまいがちですが、その変数にもたせる役割に応じたスコープ(適用範囲)で利用し、できる限りその範囲は小さいものにしておくことは、外部からの書きかえによる不正な動作を予防しているとも言えます。
ExcelVBAの繰り返し処理を使ったコード例
For Nextステートメントで行または列に対する計算
(1)合計列の緑色のセルに入力されている点数を合計する
(2)6行目(小林みどりさん)の青色のセルを合計する
上の画像のように、これまで紹介したサンプルマクロと異なる点として、行の処理と列の処理に間隔がある場合を想定したものにしています。こういった場合はStepを指定します。
次からは、実際にStepを指定したマクロを紹介します。
合計列の緑色のセルに入力されている点数を合計するサンプルマクロ
サンプルマクロ
Option Explicit
Sub For_Next_sample1()
Dim i As Long
Dim value As Long
For i = 2 To 11 Step 3
value = value + ThisWorkbook.Worksheets("Sheet5").Range("K" & i).value
Next i
MsgBox ("K列の緑色のセルの合計は" & value)
End Sub
ポイントは、Step 3の部分です。増量の指定により、変数 i の値の変化は以下のとおり。.Range(“K” & i) でK列の行数を変数 i に指定しているため、K列の2行目・5行目(2+3)・8行目(5+3)・11行目(8+3)に記入された値を変数 value に加算していきます。
状態 | 変数[i]の値 | 増量(Step) |
---|---|---|
くり返し処理開始時 | 2 | |
2回目のくり返し処理開始時 | 5 | +3 |
3回目のくり返し処理開始時 | 8 | +3 |
4回目のくり返し処理開始時 | 11 | +3 |
緑色に着色したセルの合計を算出することができました。
6行目(小林みどりさん)の青色のセルを合計するサンプルマクロ
サンプルマクロ
Option Explicit
Sub For_Next_sample2()
Dim i As Long
Dim value As Long
For i = 6 To 12 Step 2
value = value + ThisWorkbook.Worksheets("Sheet5").Cells(6, i).value
Next i
MsgBox ("6行目の青色のセルの合計は" & value)
End Sub
こちらのプログラムでは、変数 i の値は6~12となり、増量は Step 2で指定しています。今度は行を固定して、該当する列に入力された値の加算を繰り返しています。
実務では、平均列を合計するようなことは稀だと思いますが、ここでは”Step”の使い方がこういったものだと伝われば嬉しいです。
状態 | 変数[i]の値 | 増量(Step) |
---|---|---|
くり返し処理開始時 | 6 | |
2回目のくり返し処理開始時 | 8 | +2 |
3回目のくり返し処理開始時 | 10 | +2 |
4回目のくり返し処理開始時 | 12 | +2 |
青色に着色したセルの合計を算出することができました。
For Nextステートメントで条件に合わせたセルの操作
こちらのサンプルマクロでは、条件判定で使うIf文との組み合わせで判定の結果によって処理を実行する・しないを分岐します。処理をする条件には、5教科の点数が入力されているF列~J列の中で、30点以下かどうかを指定しています。
点数の条件判定との繰り返しを組み合わせたサンプルマクロ
サンプルマクロ
Option Explicit
Sub For_Next_sample3()
Dim i As Long, j As Long
For i = 2 To 11
For j = 6 To 10
If ThisWorkbook.Worksheets("Sheet5").Cells(i, j).value <= 30 Then
ThisWorkbook.Worksheets("Sheet5").Cells(i, j).Interior.Color = RGB(255, 0, 0)
End If
Next j
Next i
MsgBox ("30点以下を赤色にしました。")
End Sub
For Nextステートメントで繰り返し処理を入れ子(ネスト)して、行の繰り返しと、列の繰り返しを実現しています。処理部分はIfステートメントで、条件判定により30点以下のセルを赤色に着色します。
変数 i が2の間に、内側のループで変数 j が6~10と更新されていき、変数 j が10まで到達すると、外側のループが一回りし、変数 i は3に更新されます。これを繰り返し変数 i が11、変数 j が10になるまで処理を継続します。
変数 i と j は、セルの座標として利用しているため、繰り返し処理の最初は、Cells(2,6)です。
つまり、2行目のF列が30点以下か判定し、31点のため処理は何もしない。
次にG列[Cells(2,7)]→H列[Cells(2,8)]→I列[Cells(2,9)]と進み、I列は16点なので、判定の結果がTrueでセルを赤色に変更します。2行目のJ列[Cells(2,10)]まで到達すると、次は3行目のF列[Cells(3,6)]といったながれで処理します。
For Eachステートメントで範囲内の全てのセルに数値を入力する
以下のセル範囲をオブジェクト型の変数(area)に代入し、繰り返し処理で全てのセルに1つずつ数値を入力するプログラムを作成します。
For Eachステートメントですべてのセルを対象に繰り返すサンプルマクロ
サンプルマクロ
Option Explicit
Sub ForEachステートメント_Image()
Dim ws As Worksheet 'Worksheet型の変数を宣言
Dim area As Range 'Range型の変数を宣言
Set ws = ThisWorkbook.Sheets("テストシート") '作業対象シートを代入
Set area = ws.Range("A1", "J5") '作業対象範囲を代入
Dim cell As Variant '繰り返し用の要素を代入する変数を宣言(オブジェクト)
Dim i As Integer: i = 1 '入力する数値を代入する変数を宣言する(オブジェクト)
'作業対象範囲から全てのセルに数値を入力する繰り返し処理
For Each cell In area
cell.value = i
i = i + 1
Next cell
End Sub
A1からJ5セルの範囲に1セルずつに数値を記入することができました。このサンプルコードでは、変数iの値を範囲内のセルに入力しますが、入力後に変数iに1が足されていくので、次のセルに入力される数値は i + 1です。
入力された数値に着目すると、For Eachステートメントで繰り返し処理を実行した場合、値を入力する順番がA1→B1→C1…J1と列を移動しながら処理を進め、最終列のJ列まで完了した後で、行を移動し、A2セルを処理しています。それを繰り返し、最後のJ5セルまで処理されたことが分かります。
For Eachステートメントでオブジェクトの色を変更する
For Eachステートメントでは、セルを対象にするだけでなく、ワークシートに挿入した図形(オブジェクト)の色を変えるプログラムも作成できます。
For Eachステートメントですべての図形に処理を繰り返すサンプルマクロ
サンプルマクロ
Option Explicit
Sub ChangeShapeLineColor()
Dim shp As Shape 'Shape型の変数を宣言する(objectでも良い)
'カラーという名前のシート上にある図形の数だけ繰り返す
For Each shp In Sheets("color").Shapes
'Select Caseステートメントで現在の色を判定して処理を実行
Select Case shp.Fill.ForeColor.RGB
Case RGB(255, 0, 0) '元の色が赤色なら緑色に変更
shp.Line.ForeColor.RGB = RGB(0, 255, 0)
shp.Fill.ForeColor.RGB = RGB(0, 255, 0)
shp.Fill.BackColor.RGB = RGB(0, 255, 0)
Case RGB(0, 255, 0) '元の色が緑色なら青色に変更
shp.Line.ForeColor.RGB = RGB(0, 0, 255)
shp.Fill.ForeColor.RGB = RGB(0, 0, 255)
shp.Fill.BackColor.RGB = RGB(0, 0, 255)
Case RGB(0, 0, 255) '元の色が青色なら赤色に変更
shp.Line.ForeColor.RGB = RGB(255, 0, 0)
shp.Fill.ForeColor.RGB = RGB(255, 0, 0)
shp.Fill.BackColor.RGB = RGB(255, 0, 0)
End Select
Next shp
End Sub
マクロを実行するたびにそれぞれの図形の色が変わります。
青色の図形は赤色へ、赤色の図形は緑色へ、緑色の図形は青色へと変わっていきます。
以下の画像は、サンプルマクロを実行した結果ものです。
左から実行前、1回目実行、2回目実行、3回目実行した結果で一番右側の画像では元の状態に戻ります。
In Sheets(“color”).Shapes の部分がシート内のすべての図形を対象にしているコードになります。Shape(図形)オブジェクトのコレクションなので、Shapesを指定しています。
また、条件判定をする方法として、Select Caseステートメントを使って、図形の処理前の色を判定していて、元の色に応じて他の色に塗りかえます。
Shape(図形)オブジェクトの集合体に対して繰り返すので、Shapesを指定するんだね。
Do Whileステートメントでデータのフィルタリング
Do Whileステートメントをつかって、配列から指定条件に該当する値をフィルタリング(抽出)するサンプルコードを書いてみます。
Do Whileステートメントで条件に一致する値をフィルタリングするサンプルマクロ
サンプルマクロ
Option Explicit
Sub Do_While_sample()
Dim Arr1 As Variant
Dim i As Integer, j As Integer
Dim Arr2() As String
' テストデータを設定
Arr1 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
' フィルタリングを実行
i = 0
Do While i <= UBound(Arr1)
If Arr1(i) Mod 3 = 0 Then
ReDim Preserve Arr2(j)
Arr2(UBound(Arr2)) = Arr1(i)
j = j + 1
End If
i = i + 1
Loop
' 結果を表示
Debug.Print "フィルタリングされた値は" & Join(Arr2, ",") & "です。"
End Sub
このサンプルマクロでは、1から10の数字が代入された配列 Arr1 のすべての要素に対して3で割ったときに、余りが0になる数値を別の配列 Arr2 に代入していきます。
変数の宣言
まずは、テストデータを代入する入れる変数 Arr1 を宣言します。その他に繰り返し用の変数 i と配列のインデックスとなる変数 j を宣言します。最後に該当した値を代入する配列 Arr2 を宣言します。
Array関数をつかって変数Arr1に配列を作成する
次に、変数 Arr1 にArray関数をつかって1~10の値で配列を作成します。これにより Arr1 は以下になります。
変数Arr1のインデックス | 値 |
---|---|
0 | 1 |
1 | 2 |
2 | 3 |
3 | 4 |
4 | 5 |
5 | 6 |
6 | 7 |
7 | 8 |
8 | 9 |
9 | 10 |
Arr1要素の数だけを繰り返す条件式とIfステートメントの条件判定による処理
Do Whileステートメントにて繰り返し処理ですが、配列 Arr1 の全ての要素すべてを繰り返したいため、Ubound関数で要素数を取得します(サンプルコードでは9となる)。変数 i が9以下の間は繰り返し処理を実行するため、結果として Arr1 の要素の分だけ繰り返します。
続いて処理の部分ですが、Ifステートメントにて Arr1 の要素の全ての値を3で割って余りが0かどうかを判定しています。判定の結果がTrueであれば、動的配列 Arr2 の要素数を変更して、該当した Arr1 の値を Arr2 に代入していきます。Arr1 の値は1から10の数値が入っているため、この内、3で割ったときに余りが0となる数値は、3、6、9となり、これらの値が、Arr2 の配列に代入されます。
Join関数をつかって結果を表示する
Debug.Print "フィルタリングされた値は" & Join(Arr2, ",") & "です。"
さいごに以下のコードで、配列 Arr2 の値を、Join関数でつなげてイミディエイトウィンドウに表示します。
フィルタリングされた値は3,6,9です。
Do Untilステートメントでデータのフィルタリング
Do Untilステートメントで、特定の範囲内のセルの内、指定の文字列が入力されているセルがいくつ該当したのか、また、どこのセルに該当文字が入力されているかを返すプログラムを作成します。
上記のリストから、”ABC“の文字列が該当するセルがいくつあるか。また、そのセルの座標(位置)を返します。
Do Untilステートメントで条件に一致する値をフィルタリングするサンプルマクロ
サンプルマクロ
Option Explicit
Sub Do_Until_sample()
Dim rng As Range'セルの範囲を参照(代入)するRange変数を宣言する
Dim cell As Range'セルの範囲の内、1つのセルを参照(代入)するRange変数を宣言する
Dim hit As Integer'検索結果数を代入する変数を宣言する
Dim address() As Variant'条件に一致したセルのアドレスを代入する変数を宣言する
' 対象の範囲を指定
Set rng = ThisWorkbook.Worksheets("Sheet6").Range("A1:A21")
' フィルタ条件
Dim filterValue As String'検索キーワードを代入する変数を宣言する
filterValue = "ABC"'ABCを変数に代入する
' フィルタ処理
Set cell = rng.Columns(1).Cells(1)
Do Until cell.Value = ""
If cell.Value = filterValue Then
ReDim Preserve address(hit)
address(hit) = cell.address
hit = hit + 1
End If
Set cell = cell.Offset(1, 0)
Loop
Debug.Print ("ABCがヒットした数:" & hit)
Debug.Print ("セル番地は以下のとおり" & vbCrLf & Join(address, vbCrLf))
End Sub
変数の宣言
作業対象範囲を代入するためのオブジェクト(Range)型変数として、変数 rng を準備します。また対象範囲の内の1つのセルを代入する変数 cell とヒット数を代入する目的で変数 hit・該当セルのアドレス格納するための配列としてaddress を宣言しています。
また、検索キーワードを代入するための変数は文字列(String)型にして filterValue という名称にしています。
変数に範囲や値を代入する
作業対象である.Range(“A1:A21”)を変数 rng に、検索キーワードとして文字列を変数 filterValue に”ABC“を代入します。さらに、変数 cell にはrng.Columns(1).Cells(1)を代入するコードがありますが、これはA1からA21セルの1列目のひとつめのセルという意味です。
変数 rng に代入されているセル範囲は、A1:A21であり1列しかありませんので、変数 cell の最初の参照先は、A1セルです。
セルの値が空白になるまで繰り返す
Do Untilステートメントで、変数 cell の値が空白になるまで繰り返す条件式です。
具体的には、A1から順番に処理を繰り返していくとA22セル以降は値が入っていないため、A21セルまで処理が繰り返されます。
そしてポイントとなるコードは「Set cell = cell.Offset(1, 0)」です。
これは、現在のセル座標を(0, 0)として、Offset(行数, 列数)と表記することで、行数や列数に記載した数値分シフトします。サンプルコードでは、1行下にシフトする処理をしています。これによって、A1→A2→A3…と処理を1セルずつシフトしていく仕組みを実装しています。
判定処理の内容
Ifステートメントをつかって条件判定をしています。変数 cell が参照したセルに記入された値が変数 filterValue に代入された”ABC”と同じであるかを判定し、Trueであれば配列 address に該当したセルのアドレスを代入していきます。また、変数 hit にも1を加算することで該当する件数を数えています。
Join関数をつかって結果を表示する
変数 hit によって、文字列”ABC”と同じ文字列が入力されたセルの個数を返すことができます。さらに配列 address 内の値を、結果として返すときに配列の要素を結合することができる、Join関数をつかってイミディエイトウィンドウに表示します。
ABCがヒットした数:3
セル番地は以下のとおり
$A$3
$A$12
$A$20
A1セルからA21までの範囲で、文字列”ABC”が入力されているものは3件見つかり、該当のセル番地はA3セル、A12セル、A20セルとなることが結果として返ってきました。
「For nextやDo Loopで繰り返し処理マクロをつくる」まとめ
今回は、VBAの繰り返し(ループ)処理について紹介しました。
こちらでは、これまで紹介した内容をまとめます。
VBAの繰り返し処理をするマクロを作成するためには、以下の方法がある
- For Nextステートメント
繰り返す回数を指定する書きかたで、繰り返す回数が明確である場合に利用する。 - For Eachステートメント
配列やオブジェクトなどの集合体のすべての要素に処理を繰り返す書きかた。 - Do Whileステートメント
条件を満たす間は処理を繰り返す書きかた。繰り返しをする回数が不明確な場合に利用する。 - Do Untilステートメント
条件を満たさない間は処理を繰り返す書きかた。繰り返しをする回数が不明確な場合に利用する。
繰り返し処理の重要性
それぞれのステートメントのつかいどころ
For Nextステートメント
繰り返す回数が明確な場合に有効なので、例えばワークシートなら行数や列数、配列なら要素数が分かっている、または事前に取得すれば回数を指定して利用できます。また、Do Loopステートメントよりコードが読みやすく使いやすいです。
For Eachステートメント
繰り返す対象がワークシートなどのオブジェクトや配列である場合に有効です。
指定したオブジェクトや、配列の要素すべてに対して繰り返すので、全体の数量が明確でなくても利用が可能です。
例えば、すべてのワークシートを繰り返す処理を実装する場合や、ユーザーフォーム内のコントロールや図形を対象にすると便利に使えます。
Do Whileステートメント
繰り返す回数を指定するのではなく、条件で繰り返す回数を指定する場合は有効です。
Do Whileステートメントは、条件判定がTrueの間は繰り返しを継続します。
例えば、ワークシートのセルが空白ではない間は処理を継続するなどで行数が明確に分からない状況でも使えます。ただし、無限ループのリスクがあるため、繰り返し回数を代入する変数をカウントする処理を書く必要があります。また、使用時の注意点として、Untilとは逆説の関係にあるので、書きかえる場合は不等号の指定方法に気をつけましょう。
Do Untilステートメント
繰り返す回数を指定するのではなく、条件で繰り返す回数を指定する場合は有効です。
Do Untilステートメントは、条件判定がFalseの間は繰り返しを継続します。
例えば、ワークシートのセルが空白になるまで間は処理を継続するなどで行数が明確に分からない状況でも使えます。ただし、無限ループのリスクがあるため、繰り返しの回数として利用する変数をカウントする処理を書く必要があります。また、使用時の注意点として、Whileとは逆説の関係にあるので、書きかえる場合は不等号の指定方法に気をつけましょう。
変数のスコープ(有効範囲)について
変数の適用範囲であるスコープは宣言方法によって異なります。
プロシージャ内で宣言すれば、プロシージャ変数になり、宣言セクションで宣言する場合、”Private”もしくは”Public”の指定によって適用範囲が変わります。スコープ(適用範囲)を広くした場合は他のモジュールから変数を参照したり、書き換えられますが、他モジュールからの処理の影響で、その変数に意図しない値が代入されてしまうことの注意や、処理があちらこちらに飛ぶことで可読性が低下することは理解しておきましょう。
ExcelVBAがすこし書けるようになった人が、さらに知識を深めていくならこちらの書籍がおすすめ。
オブジェクトや、ライブラリ・クラスなどネット検索だけで部分的な情報や知識を体系的に整理できます。条件分岐や配列などが扱えるようになった脱初心者向けの内容で、スキルアップを目指す人に最適です。
今回は、VBAの繰り返し(ループ)処理について紹介しました。繰り返し処理は、条件分岐と並んでプログラムにおける重要なポイントだと言えます。また、エクセル関数では実行できないものとなるので、VBAの真骨頂とも言える部分だと言えます。
繰り返し処理がつかえると、実務でもVBAを活用できる幅は多くなってきます。そのため、ぜひここで紹介した内容を文字通り”繰り返し”見ながら自身のスキルとして身につけていって頂けたら幸いです。
今回はここまで、さいごまでお読みいただきありがとうございます。
コダマのもりブログはにほんブログ村に登録しています。
今回の記事が役に立ったと感じて頂けたら、フォローお願いいたします。
コメント