パソコンスキルの教科書

パソコンスキルの教科書

東京大学大学院卒。博士課程に進学を志すも、担当教授と折が合わず、無職になる。医者を目指すも結局断念。田舎で派遣社員として働く。「スキルがなければ、仕事ももらえない」と悟り、ビジネススキルを学ぶ。プログラミング、英語を学び、一部上場企業へ転職。年間100時間以上の業務効率化を行い、社内講師に抜擢。海外の案件を担当し、数億円のプロジェクトに携わる。個人の事業でも、月売上100万を達成。現在は、自分の価値を高めるためのスキル向上支援を行う

マクロVBAのForNext文を12事例で解説|Continue,抜ける,配列,ifなどの使い方

f:id:gene320:20190117223632j:plain

エクセルマクロVBAでは、ForNext文を頻繁に使います。

実際、このFor next文を自在に使えるとマクロの幅がグッと広がります。

そこで、VBAでの自動化に必須であるForNext文について、事例を使って解説をしていきます。

VBAのForNext文とは

VBAで使用されるFor next文は以下の構文で示されます。

'一般式
For カウンター  = 開始 To 終了
    繰り返し処理したい内容
Next

このプログラムを分かりやすく伝えると「"開始"から"終了"まで"繰り返し処理したい内容"を実行する」ということです。

しかし、このような一般式で説明されてもイマイチ分かりません。

そこで、事例を使ってFor Next文について理解を深めていただきます。

この記事では以下の事例を解説していきます。

●記事で紹介するFor Next文の事例
事例1|For Next文で文字列を入力
事例2|事例2|For Next文でカウントアップ
事例3|For Next文とIf文の組み合わせ
事例4|For Next文とIf文とカウントアップ
事例5|For Next文の2つ以上(複数)の組み合わせ
事例6|For Next文で最終行を自動取得する
事例7|For Next文を1度スキップしてループ省略(Continue)
事例8|For Next文から抜けて次に進む(Exit For)
事例9|For Next文をStep-1(逆順に後ろから回す)
事例10|For Next文をStep 3 (3つずつ足す)
事例11|For Next文をLboundとUboundで回す
事例12|For Next文をworksheet.countで回す

それでは、一つずつ紹介していきます。

ForNext文1|VBAでの繰り返しの基本形

最初に紹介するのは、VBAで繰り返しプログラムを作るときの基本となる以下の2つです。

事例1|For Next文で文字列を入力
事例2|For Next文でカウントアップ

以下でプログラムの解説をします。

事例1|For Next文で文字列を入力

ForNext文を使って、「セルA1」から「セルA10」まで文字列「a」を入力する事例です。

'事例1|For Next文で文字列を入力
Sub Sample1()
    Dim i As Long
    For i = 1 To 10
        Range("A" & i).Value = "a"
    Next
End Sub

重要なのは4行目の 「For = i 1 to 10」と5行目の「Range("A" & i).Value」です。

まず、4行目が i=1,2,3,・・・,10と加算しながら繰り返すプログラムを意味します。

一方、5行目の Range("A" & i).Value はセルAi の値を意味します。

したがって、4行目と5行目を組み合わせると、セルA1、セルA2、・・・セルA10と増やすことができます。

その結果、「セルA1からセルA10まで"a"を入力する」となります。

マクロ実行前

f:id:gene320:20190116234601j:plain

マクロ実行後

f:id:gene320:20190116234609j:plain

事例2|For Next文でカウントアップ

ForNext文を使って数値をカウントアップしていく事例を紹介します。

ForNext文を使って、「セルA1」から「セルA10」まで i を入力する事例です。

i は1から10まで1ずつ増えていくので、セルA1には1、セルA2には2といったように、セル行数と出力される値が同時に増えていきます。

'事例2|For Next文でカウントアップ
Sub Sample2()
    Dim i As Long
    For i = 1 To 10
        Range("A" & i).Value = i
    Next
End Sub

重要なのは、5行目の「Range("A" & i).Value = i」です。

左辺が「セルA1、セルA2、・・・セルA10」と繰り返しが進むと同時に、右辺も「i = 1,2,・・・10」と繰り返します。

したがって、「セルA1には"1"を入力」、「セルA2には"2"を入力」・・・「セルA10には"10"を入力」となります。

マクロ実行前

f:id:gene320:20190116235116j:plain

マクロ実行後

f:id:gene320:20190116235124j:plain

ForNext文2|条件分岐「If文」との組み合わせ

「For next文」と「If文」の組み合わせについて解説します。

For next文を実践で使う場合、IF文と組み合わせて使うことは非常に多いです。ぜひ覚えておくことをお勧めします。

事例3|For Next文とIf文の組み合わせ
事例4|For Next文とIf文とカウントアップ

以下でプログラムの解説をします。

事例3|For Next文とIf文の組み合わせ

2で割ったときの余りが 0(2の倍数)ならば、A列に"a"を出力するプログラムです。

'事例3|For Next文とIf文の組み合わせ
Sub Sample3()
    Dim i As Long
    For i = 1 To 10
        If i Mod 2 = 0 Then
            Range("A" & i).Value = "a"
        End If
    Next
End Sub

重要なのは、5行目の「If i Mod 2 = 0 Then」です。

これは、「もし、i を2で割ったときの余りが 0(2の倍数)ならば」という意味です。

したがって、2の倍数ならば、6行目の「Range("A" & i).Value = "a"」が実行されます。

逆に2の倍数でないならば、6行目の「Range("A" & i).Value = "a"」が実行されません。

マクロ実行前

f:id:gene320:20190116235242j:plain

マクロ実行後

f:id:gene320:20190116235253j:plain

補足|Modとは、余りを示す演算子

Sample3の5行目の「Mod」は余りを示す演算子です。

例えば
「10 Mod 2」であれば余りは0です。2で割ると、5と余り0だからです。

一方で、「3 Mod 2」であれば、余りは1です。2で割ると、余りが1になるからです。

つまり5行目の「If i Mod 2 = 0 then」とは、2で割り切れるなら「True」で、6行目が実行されます

逆に、2で割り切れないなら「False」で、6行目が実行されません。

事例4|For Next文とIf文とカウントアップ

2で割ったときの余りが 0(2の倍数)ならば、A列に数値を入れるプログラムです。

ただし、A列に入る数値をカウントアップ(+1)させます。

'事例4|For Next文とIf文とカウントアップ
Sub Sample4()
    Dim i As Long
    Dim k As Long
    k = 1
    
    For i = 1 To 10
        If i Mod 2 = 0 Then
            Range("A" & i).Value = k
            k = k + 1
        End If
    Next
End Sub

重要なのは、5行目の「k=1」と10行目の「k=k+1」です。

5行目でk=1と設定しておかないと、k=0と自動で認識されてしまいます。

10行目は、8行目の「If i Mod 2 = 0 Then」でTrueの場合に実行されます。

したがって、事例4では i が2で割り切れる数字になるたびに、kに1ずつ加算されていきます。

ただし、5行目でk=1としているので、k=1からのスタートになります。

マクロ実行前

f:id:gene320:20190117000213j:plain

マクロ実行後

f:id:gene320:20190117000220j:plain

ForNext文3|2つ以上の複数のForを入れ子(ネスト)にする

次にFor next文を2つ以上入れる場合について紹介します。

For next文の中に、For next文が入ってきます。

事例5|For Next文の2つ以上(複数)の組み合わせ

以下でプログラムの解説をします。

事例5|For Next文の2つ以上(複数)の組み合わせ

セルA1からセルJ10までの10×10のセル領域に一つずつ "a"を入力していきます。

'事例5|For Next文の2つ以上(複数)の組み合わせ
Sub Sample5()
    Dim i As Long
    Dim k As Long
    
    For i = 1 To 10
        For k = 1 To 10
            Cells(i, k).Value = "a"
        Next
    Next
End Sub

6行目~10行目で i は 1,2,3,・・・10というループを行います。

7行目~9行目で k は1,2,3,・・・10というループを行います。

したがって、i=1のまま k=1~10のループが実行され、i=2の状態でk=1~10のループが実行されます。

そして、これを i=10になるまで繰り返します。

マクロ実行前

f:id:gene320:20190117000643j:plain

マクロ実行後

f:id:gene320:20190117000652j:plain

ForNext文4|自動取得した最終行までプログラムを繰り返す

ここまで、i=1 to 10と繰り返しの回数が分かっている事例を紹介してきました。

しかし実際の業務で使うときは、繰り返しの数が分かっているとは限りません。

むしろ多くの場合、繰り返しの数は分かっていません。

そこで、繰り返しの回数を自動で決定するプログラムを紹介します。

事例6|For Next文で最終行を自動取得する

以下でプログラムの解説をします。

事例6|For Next文で最終行を自動取得する

エクセルのA列のデータが記載されている最終行を自動取得し、その最終行まで処理を行うプログラムです。

'事例6|For Next文で最終行を自動取得する
Sub Sample6()
    Dim i As Long
    Dim cmax As Long
    cmax = Range("A65536").End(xlUp).Row
    
    For i = 1 To cmax
        Range("A" & i).Value = i
    Next
End Sub

重要なのは、5行目の「cmax = Range("A65536").End(xlUp).Row」と7行目の「For i = 1 To cmax」です。

5行目は「変数"cmax"を、セルA65536から数えて最初に文字が含まれるセルの存在する行にする」という意味です。

要するに、「cmax = A列の最終行を取得」ということです。

7行目は、「i = 1,2,・・・cmax」を意味します。

マクロ実行前

f:id:gene320:20190117210217j:plain

マクロ実行後

f:id:gene320:20190117210226j:plain

ForNext文5|「スキップして抜ける」「次に進む」

事例7|For Next文を1度スキップしてループを省略する(Continueと同じ)
事例8|For Next文から抜けて次に進む(Exit For)

以下でプログラムの解説をします。

事例7|For Next文を1度スキップしてループを省略する(Continueと同じ)

VBA以外のプログラムを書くと、continueというスキップ機能を使うことができます。

Continueを使うと、for文のような繰り返し処理の途中でループをスキップし、ループの先頭(次のループ)から実行する処理することができます。

例えば、i=8のときは処理をしたくないとします。

i=7まで処理を行い、Continueを使って i=8のときのみ処理をスキップし、i=9からまた処理を行うことができるのです。

しかし、VBAにはContinueの機能がありません。

ただVBAでは疑似的にContinueを作ることで対応することができます。以下で、その方法を紹介します。

'事例7|For Next文を1度スキップしてループを省略する(Continueと同じ)
Sub Sample7()
    Dim i As Long
    
    For i = 1 To 10
        If i Mod 2 = 0 Then
            GoTo SkipLoop
        End If

        Range("A" & i).Value = i
    
SkipLoop:
    Next
    
End Sub

重要なのは7行目「GoTo SkipLoop」と12行目の「SkipLoop」です。

7行目の「GoTo SkipLoop」は、i が2で割り切れるとき実行されるプログラムです。

i が2で割り切れるとき「GoTo SkipLoop」が実行され、10行目がスキップされ12行目の「SkipLoop」に移動します。

つまり、2で割り切れないときのみ、10行目「Range("A" & i).Value = i」が実行されることになります。

このとき「SkipLoop」はNext(13行目)の直前に置くのがコツです。

マクロ実行前

f:id:gene320:20190117223005j:plain

マクロ実行後

f:id:gene320:20190117223012j:plain

事例8|For Next文から抜けて次に進む(Exit For)

Continueは一度のスキップですが、For next文から抜け出したいときがあります。

そのときは、Exit Forを使います。

例えば、i が8を越えたらFor Nextを止めたいとします。

その場合は、以下のプログラムを使います。

'事例8|For Next文から抜けて次に進む(Exit For)
Sub Sample8()
    Dim i As Long
    
    For i = 1 To 10
        If i > 8 Then
            Exit For
        End If

        Range("A" & i).Value = "a"
    Next    
End Sub

重要なのは6行目「If i > 8 Then」と7行目の「Exit For」です。

6行目の「If i > 8 Then」は、i が8より大きい場合に実行されるプログラムです。

したがって、i=9となると7行目の「Exit For」が実行されます。

7行目の「Exit For」が実行されるとFor next文から抜け出し、12行目の「End Sub」に移動します。

マクロ実行前

f:id:gene320:20190117223143j:plain

マクロ実行後

f:id:gene320:20190117223156j:plain

ForNext文6|Step-1で逆からカウントダウンで繰り返す

ここまで、数字がカウントアップされる例を紹介してきました。

カウントアップとは、i = 1,2,・・・10というように数字が増えていくパターンです。

しかし、場合によってはカウントダウンを使いたいときもあります。

例えば、i = 10,9,・・・1というように数字が減っていくパターンです。

実際、行を削除していく場合はカウントダウンを使います。

ここでは、以下の事例を紹介します。

事例9|For Next文をStep-1する(逆順に後ろから回す)

以下でプログラムの解説をします。

事例9|For Next文をStep-1する(逆順に後ろから回す)

Step-1という方法で10行目から1行目に向かって、処理を行うプログラムです。

'事例9|For Next文をStep-1する(逆順に後ろから回す)
Sub Sample9()
    Dim i As Long
    
    For i = 10 To 1 Step -1
        Range("A" & i).Value = "a"
    Next
    
End Sub

重要なのは5行目「For i = 10 To 1 Step -1」です。

この5行目は、「i を10から開始して1になるまで、-1ずつしていく」という意味です。

したがって、i = 10,9,8,・・・1と数字が減りながら繰り返していきます。

マクロ実行前

f:id:gene320:20190117211446j:plain

マクロ実行後

f:id:gene320:20190117211454j:plain

ForNext文7|Stepの数を変えて複数カウントアップする

ここまで、数字が1ずつ増やしたり減らしたりする例を紹介してきました。

しかし、1以外の数字で増やしたり減らしたりするこも可能です。

例えば、i = 1,4,7,10・・・というように3ずつ増やすパターンです。

事例10|For Next文をStep 3する(3つずつ足す)

以下でプログラムの解説をします。

事例10|For Next文をStep 3する(3つずつ足す)

セルA1、セルA4、セルA7、セルA10と3つずつ増やして、それぞれのセルに"a"を出力するプログラムです。

'事例10|For Next文をStep 3する(3つずつ足す)
Sub Sample10()
    Dim i As Long
    
    For i = 1 To 10 Step 3
        Range("A" & i).Value = "a"
    Next
    
End Sub

重要なのは5行目「For i = 1 To 10 Step 3」です。

この5行目は、「i を1から開始して10になるまで、3ずつしていく」という意味です。

したがって、i=1,4,7,10と処理を行っていきます。途中の2,3,5,6,8,9は処理を行いません。

マクロ実行前

f:id:gene320:20190117211849j:plain

マクロ実行後

f:id:gene320:20190117211856j:plain

ForNext文8|配列との組み合わせ

ここまで「For i = 1 to 10」のように、1から10までの数字を使ってきました。

しかし配列と組み合わせてFor next文を使うと、このような数字を入力する必要がなくなります。

それは、LboundやUboundといった配列に含まれる数を取得できる関数があるからです。

LBound関数|配列内の始まりの要素番号
UBound関数|配列内の終わりの要素番号

正確に言うと、LBound関数は指定した配列で使用できる最も小さいインデックス番号を返します。

一方、UBound関数は指定した配列で使用できる最も大きいインデックス番号を返します。

For next文では、LBound関数とUBound関数は使うことで数字を入れることなく繰り返し処理を行うことができます。

事例11|For Next文をLboundとUboundで回す

事例11|For Next文をLboundとUboundで回す

ここでは、「"あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ"」の10コの要素を含む配列に対して、LboundとUboundとFor nextをどのように組み合わせるか解説をします。

具体的には、配列の各要素をセルA1からセルA10に出力していきます。

'事例11|For Next文をLboundとUboundで回す
Sub Sample11()
    Dim i As Long
    Dim myArray As Variant
    
    myArray = Array("あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ")
    
    For i = LBound(myArray) To UBound(myArray)
        Range("A" & i + 1).Value = myArray(i)
    Next
    
End Sub

重要なのは以下の3箇所です。

6行目|myArray = Array("あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ")
8行目|For i = LBound(myArray) To UBound(myArray)
9行目|Range("A" & i + 1).Value = myArray(i)

6行目は、「"あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ"」の10コの要素を含む配列を意味します。

8行目のLBound(myArray)は0を意味し、UBound(myArray)は9を意味します。

なぜなら6行目で指定した配列では「0番目の要素に"あ"、1番目の要素に"い"、・・・9番目の要素に"こ"」が格納されているからです。

したがって、配列内の要素の開始を示すLBound関数を使うと、LBound(myArray)は0を意味します。

一方で、配列内の要素の終了を示すUBound関数は、UBound(myArray)は9を意味するのです。

9行目は「セルA(i+1)をmyArray(i)とする」という意味です。

左辺では、i+1で右辺では i を+1せずに使っています。

なぜなら、配列の要素は0から始まるからです。

6行目で10個の要素を含む配列を設定しています。しかし、要素の開始は0から始まります。

もし、9行目の両辺を i のまま「Range("A" & i ).Value = myArray(i)」としてしまうと 「セルA0の値をmyArray(0) とする」なります。

しかし、セルA0は存在しないので、エラーが出てしまいます。

したがって、左辺を i+1 にすることでエラーを回避しています。

ちなみに配列の場合は、「myArray(i)」とします。この事例11の場合であれば、myArray(0) は"あ"、myArray(1) は"い"、・・・myArray(9) は"こ"、となります。

マクロ実行前

f:id:gene320:20190117213927j:plain

マクロ実行後

f:id:gene320:20190117213936j:plain

ForNext文9|シートを全て繰り返す

ここまでセルに対する繰り返し処理の事例を紹介してきました。

しかしFor next文で処理できるのは、セルだけではありません。

他にも多くの対象を繰り返し処理できます。

例えば、ワークシートです。エクセルブック内のシートを繰り返し処理できるのです。

事例12|For Next文をworksheet.countで回す

以下でプログラムの解説をします。

事例12|For Next文をworksheet.countで回す

For next文では、worksheets.countというワークシート数を取得する方法を使うことができます。

これを使えばシート数を自分で計算することなく、プログラムが自動でシート数を読み取って処理を行ってくれます。

以下は、worksheets.countを使って全シートのセルA1に"a"を出力するプログラムです。

'事例12|For Next文をworksheet.countで回す
Sub Sample12()
    Dim i As Long
    For i = 1 To Worksheets.Count
        Worksheets(i).Range("A1").Value = "a"
    Next
End Sub

重要なのは4行目「For i = 1 To Worksheets.Count」と5行目「Worksheets(i).Range("A1").Value = "a"」です。

4行目のWorksheets.Countは、そのエクセルファイル内のシート数を意味します。

ここではシートが3つあるので、4行目は「i を1から開始して3になるまで1ずつ増やす」となります。

5行目は「i 番目のワークシートのセルA1の値を"a"にする」という意味です。

つまり、全シートのセルA1の値を"a"にするプログラムになります。

マクロ実行前

f:id:gene320:20190117222120j:plain

マクロ実行後

f:id:gene320:20190117222131j:plain

ForNextを実践でつかう

ここまで、VBAでの自動化に必須であるForNext文について事例を使って解説をしてきました。

ただこの記事では初心者に分かりやすく説明するために、敢えて簡単な事例を使いました。

しかし仕事では、ここまでシンプルなFor next文を使うことは少ないかもしれません。

以下の記事では、より実践的な事例のプログラムを公開しています。

www.fastclassinfo.com

www.fastclassinfo.com

ぜひここで学んだ内容を定着させる意味でも、勉強してみてください。

エクセルマクロVBAのお勧め記事

以下で、エクセルマクロVBAに関するお勧め記事を紹介します。

▷エクセルマクロで出来ること
▷エクセルマクロ入門
▷エクセルマクロとは?
▷エクセルマクロの挫折しない勉強法
▷エクセルマクロの正しい学習方法
▷エクセルマクロVBAのお勧め講座
▷エクセルマクロの独学方法
▷エクセルマクロ習得者の体験談1
▷エクセルマクロ習得者の体験談2