【超々初心者向き】エクセルVBAのFor~Nextって何?
VBAで「For~Nextループ」を使うと、同じことを繰り返す処理を簡潔に書くことができます。
エクセルVBAでは、同じことを繰り返す処理というのは頻繁に出てきます。
そのため、エクセルVBAを使いこなすためには、For~Nextループを確実に理解をしておかないといけません。
ところが、プログラミングを初めて学習する人にとってFor~Nextループを習得するのは非常に難しいようです。
一通りFor~Nextループの説明を読んでも
- ループという概念自体がわからない
- なぜ、ループ処理が必要なのかがわからない
- どういう場面で使えばいいかがわからない
という感想を持つ方も多いようです。
そこで、このページでは、多くのホームページ・ブログでの解説よりも「さらに一歩」初心者寄りに踏み込んで、For~Nextループの具体的なイメージを掴めるような説明をしていこうと思います。
この記事の目次
1. For~Nextってそもそも何?
For~Nextはプログラム中の同じ箇所を「繰り返し実行」するために使います。
この処理のことを別の言い方で「ループ処理」ともいいます。
2. For~Nextを使うメリットは?
「似たような処理を何回も繰り返したいときに命令文を1回書くだけで済む」
ということが一番のメリットです。
それでは、実際の例を見てみましょう。
- 例:C1~C10セルにA1~A10セルの内容を転記する
-
(For~Nextを使わない場合)
Sub Copy1() Cells(1, 3).Value = Cells(1, 1).Value 'C1セル←A1セル Cells(2, 3).Value = Cells(2, 1).Value 'C2セル←A2セル Cells(3, 3).Value = Cells(3, 1).Value 'C3セル←A3セル Cells(4, 3).Value = Cells(4, 1).Value 'C4セル←A4セル Cells(5, 3).Value = Cells(5, 1).Value 'C5セル←A5セル Cells(6, 3).Value = Cells(6, 1).Value 'C6セル←A6セル Cells(7, 3).Value = Cells(7, 1).Value 'C7セル←A7セル Cells(8, 3).Value = Cells(8, 1).Value 'C8セル←A8セル Cells(9, 3).Value = Cells(9, 1).Value 'C9セル←A9セル Cells(10, 3).Value = Cells(10, 1).Value 'C10セル←A10セル End Sub
↓
(For~Nextを使った場合)
Sub Copy2() Dim Row As Long For Row = 1 To 10 '1行目~10行目まで Cells(Row, 3).Value = Cells(Row, 1).Value '各行のC列←各行のA列 Next '繰り返す End Sub
↓この2つのマクロを実行したときの動画です。
For~Nextを使って処理を1行に集約する
For~Nextを使わない場合には、次のような似たような表現が10回出てきています。
それに対して、For~Nextを使うと、この10行分の処理が、次の1行に集約できます。
たったこれだけ?と思われるかもしれません。
でも、この「1行書くだけで済む」ということがとても重要なのです。
メリットその1:入力が楽
入力すべき文字数が少ないので、入力がとても楽です。
似たような命令文を大量に書くためのコピペをしないで済むので、精神的に良いです。
メリットその2:見やすい
プログラムの行数が少なくなっているので見やすくなっています。
メリットその3:修正が楽
元々のマクロは
《「C1~C10セル」に「A1~A10セル」の内容を転記する》
というものでした。
このマクロを、
《「D1~D10セル」に「A1~A10セル」の内容を転記する》
ように修正しようと思います。
そのとき、どのように修正をすればいいかを考えてみます。
- 1.単に羅列をしたとき
-
2行目~11行目まで全ての行について「3」→「4」に修正することになります。
修正箇所が多く、とても大変です。Cells(1, 34).Value = Cells(1, 1).Value 'C1セル←A1セル Cells(2, 34).Value = Cells(2, 1).Value 'C2セル←A2セル Cells(3, 34).Value = Cells(3, 1).Value 'C3セル←A3セル Cells(4, 34).Value = Cells(4, 1).Value 'C4セル←A4セル Cells(5, 34).Value = Cells(5, 1).Value 'C5セル←A5セル Cells(6, 34).Value = Cells(6, 1).Value 'C6セル←A6セル Cells(7, 34).Value = Cells(7, 1).Value 'C7セル←A7セル Cells(8, 34).Value = Cells(8, 1).Value 'C8セル←A8セル Cells(9, 34).Value = Cells(9, 1).Value 'C9セル←A9セル Cells(10, 34).Value = Cells(10, 1).Value 'C10セル←A10セル
- 2.For~Nextを使ったとき
-
次のようにたった1カ所「3」→「4」に修正するだけです。
Cells(Row, 34).Value = Cells(Row, 1).Value '各行のC列←各行のA列
このようにFor~Nextを使うことでプログラムの作成~メンテナンスまで、すべての段階で楽ができるのです。
3. For~Nextループの構文(基本編)
ここからは、実際にFor~Nextの説明をしていきます。
まずは、For~Nextループの一番の基本となる構文を説明します。
For {カウンタ変数} = {最初の値} To {最後の値}
'繰り返したい処理
Next
カウンタ変数 | For~Nextの「カウンタ」として使う変数 |
---|---|
最初の値 | 最初に「カウンタ変数」に設定する値 |
最後の値 | 最後の「ループ処理」時の「カウンタ変数」の値 |
実際の例
このページの冒頭で紹介した例を、再度見てみましょう。
Sub Copy2()
Dim Row As Long
For Row = 1 To 10 '1行目~10行目まで
Cells(Row, 3).Value = Cells(Row, 1).Value '各行のC列←各行のA列
Next '繰り返す
End Sub
3行目~5行目にFor~Nextが出てきています。
今回は、最初の値を「1」、最後の値を「10」に設定しているので、
- 変数Rowが1、2、3・・・、10というように変化しながら
- Cells(Row, 3).Value = Cells(Row, 1).Value
が実行されます
実際にデバッガを使って、プログラムを1行ずつ実行したときの様子を見てみると、変数Rowが変化している様子がわかると思います。
デバッガだとちょっとわかりにくいという方のために、模式図も準備しましたのあで、合わせてご覧ください。
上の動画や模式図を見ると、変数Rowの値は、最終的に「11」になっています。
繰り返し処理は変数Rowが「10」までしか行われないって言ったのに変数Rowが「11」になるなんておかしくない?と思われるかもしれません。
ただ、よく見ると、変数Rowが「11」のときには、内部の処理は実行されていないことがわかります。
内部の処理が実行されているのは、先ほど説明したとおり変数Rowが1、2、3・・・、10のときだけであることを確認してください。
4. For~Nextを使いこなす鍵は「カウンター変数」にあり
for~nextを使いこなすためには「カウンター変数」を理解することがとても大事です。
4-1. なぜ、カウンター変数を使うの?
そもそもの話として、なぜFor~Nextループでは「カウンター変数」が必要なのでしょうか?
そのことを理解するために、VBAから少し離れて考えてみたいと思います。
処理を繰り返すときに無意識にやっていること
突然ですが、「ピザ」って10回言ってみてください。
...
...
少し考えてほしいのですが。
「ピザ」「ピザ」・・・というときに、同時に何かをしていないでしょうか?
実は、ここに「カウンター変数」の秘密があります。
「カウンタ変数」を見れば、何回目かがわかる
「ピザ」と10回言うとき、ほとんどの人は同時に「1、2、3、・・・10」と頭の中で数を数えているはずです。
なぜなら、10回「ピザ」と言うためには、今が何回目なのかを把握しておく必要があるからです。
For~Nextループでも考え方はまったく同じで、何らかの手段で「回数を数える」必要があります。
その手段として「カウンタ変数」を使っているのです。
For~Nextを使うとカウンタ変数は「自動で」増える
カウンタ変数は、For~Next内の処理ごとに自動で1ずつ増えます。
そのため、カウンタ変数を1足す処理を、わざわざ書く必要はありません。
ここまでの話を踏まえて、もう一度For~Nextの実行の様子をデバッガで見てみましょう。
プログラム中に1を足す処理がないのに、勝手に1ずつ増えている様子がわかると思います。
4-2. カウンター変数の「もう1つ」の役割
カウンター変数には、もう1つ大事な役割があります。
それはFor~Nextで繰り返す処理の内容を少しずつ変えるという役割です。
ループ処理は「同じ処理」の繰り返しではない
ループ処理というと、なんとなく「同じ処理を何回も繰り返す」というイメージがないでしょうか?
でも、そのイメージは、多くの場合、正しくありません。
実際のループ処理では、
ほとんど同じだけれど微妙に違う処理をくり返す
ことがほとんどです。
たとえば、このページの一番最初に挙げた「For~Nextを使わない場合の例」をもう一度見てみましょう。
Cells(1, 3).Value = Cells(1, 1).Value 'C1セル←A1セル
Cells(2, 3).Value = Cells(2, 1).Value 'C2セル←A2セル
Cells(3, 3).Value = Cells(3, 1).Value 'C3セル←A3セル
Cells(4, 3).Value = Cells(4, 1).Value 'C4セル←A4セル
Cells(5, 3).Value = Cells(5, 1).Value 'C5セル←A5セル
Cells(6, 3).Value = Cells(6, 1).Value 'C6セル←A6セル
Cells(7, 3).Value = Cells(7, 1).Value 'C7セル←A7セル
Cells(8, 3).Value = Cells(8, 1).Value 'C8セル←A8セル
Cells(9, 3).Value = Cells(9, 1).Value 'C9セル←A9セル
Cells(10, 3).Value = Cells(10, 1).Value 'C10セル←A10セル
Cellsの中の数字を見ると「1、2、3、・・・10」と変わっていますよね?
要は、処理対象の行が
「1行目」→「2行目」→「3行目」→・・・→「10行目」
と変わっているわけです。
For~Nextを使う処理の多くは、
このようなまったく同じではないけれど、似た処理を繰り返す処理なのです。
カウンター変数を使って、処理を変える
このような
「ほとんど同じだけれど、微妙に違う処理」
を書くときに役に立つのが「カウンター変数」です。
元々、回数を数えるために「カウンター変数」は1ずつ変化しているのでした。
そこで、For~Nextの間に「カウンター変数」を使った処理を書きます。
そうすることで、For~Nextで繰り返される1回1回の処理内容を、自動的に変えることができるのです。
たとえば、このページの最初の「For~Nextを使った場合の例」を改めて見てみましょう。
For Row = 1 To 10 '1行目~10行目まで
Cells(Row, 3).Value = Cells(Row, 1).Value '各行のC列←各行のA列
Next '繰り返す
For~Nextの間で「カウンタ変数」を使うことで、処理対象の行が変わる様子をうまく表現していることがわかると思います。
5. どういう場面でFor~Nextを使えばいいの?
For~Nextを使うべき場面を、一言でいうと、
ほとんど同じ処理だけれど、処理で使う「数字」だけが規則的に変わる処理です。
極端な言い方をすると、For~Nextを使うために無理矢理、「数字だけが変化する」処理に置き換えるくらいの感覚がちょうど良いかもしれません。
For~Nextを使うときには、「日本語」「エクセル(VBA)の言葉」のどちらでもいいので、
- 処理の枠組みは同じ
- その中に出てくる数字だけが変化する
表現ができないかを考えることがポイントです。
いくつか例で考えてみましょう。
例1:単価×数量=金額
B列に単価、C列に数量が入っています。
D列に「単価×数量」を計算した「金額」を入れたいと思います。
そこで、
- 処理は基本的には一緒
- 処理の中に出てくる数字だけが変わる
ような表現を考えてみてください。
いきなり、VBAの言葉で考えるのが難しいときは、まずは、日本語で処理を考えてみましょう。
ほとんど同じだけれど「数字だけが違う」処理を考える
たとえば、次のような表現が考えられます。
- 1行目のD列に1行目のB列×1行目のC列の結果を表示
- 2行目のD列に2行目のB列×2行目のC列の結果を表示
- 3行目のD列に3行目のB列×3行目のC列の結果を表示
- 4行目のD列に4行目のB列×4行目のC列の結果を表示
↓VBAの言葉で書くと、
Cells(1, 4).Value = Cells(1, 2).Value * Cells(1, 3).Value
Cells(2, 4).Value = Cells(2, 2).Value * Cells(2, 3).Value
Cells(3, 4).Value = Cells(3, 2).Value * Cells(3, 3).Value
Cells(4, 4).Value = Cells(4, 2).Value * Cells(4, 3).Value
For~Nextに置き換える
ここまで来れば、あとはFor~Nextに置き換えるだけです。
Dim Row As Long
For Row = 1 To 4
Cells(Row, 4).Value = Cells(Row, 2).Value * Cells(Row, 3).Value
Next
実際にプログラムを動かすと、次のようになります。
例2:シート名を「1」「2」「3」・・・という名前に変更する
各シートの名前を「1」「2」「3」・・・に変更します。
ほとんど同じだけれど「数字だけが違う」処理を考える
たとえば、次のような表現が考えられます。
- 1つ目のシートの名前を1に変更
- 2つ目のシートの名前を2に変更
- 3つ目のシートの名前を3に変更
- 4つ目のシートの名前を4に変更
↓VBAの言葉で書くと、
Worksheets(1).Name = "1"
Worksheets(2).Name = "2"
Worksheets(3).Name = "3"
Worksheets(4).Name = "4"
For~Nextに置き換える
ここまで来れば、あとはFor~Nextに置き換えるだけです。
Dim SheetNo As Long
For SheetNo = 1 To 4
Worksheets(SheetNo).Name = SheetNo
Next
実際にプログラムを動かすと、次のようになります。
6. For~Nextを使うときの細かい注意点
何点か気をつけたほうがいい点を書いていきます。
「カウンタ変数」はわかりやすい名前をつけよう
Forループで指定する「カウンタ変数」の名前は自由に付けることができます。
そこで、後でプログラムを見たときのために、できるだけわかりやすい名前を付けましょう。
このページの例では、
カウンタ変数に「行」を入れる場合 | Row |
---|---|
カウンタ変数に「シート番号」を入れる場合 | SheetNo |
という変数名を付けています。
「カウンタ変数」は事前にDimが必要
標準モジュールの先頭で「Option Explicit」を入れて、変数宣言必須にしている場合。
Forで使うカウンタ変数も「Dim」による宣言が必要です。
データ型含め宣言をする場合には「As Long」というように「長整数型」を使うようにしましょう。
ダウンロード
このページで説明に使ったエクセルシートは下記からダウンロードできます↓
→fornext.zip のダウンロードはこちら
上記Zipファイル中にはエクセルファイルが3つ入っています。
エクセルファイルを取り出してお使いください。