VBA 繰り返し処理
エクセルVBAでは、繰り返し処理(ループ) を活用することで、同じ操作を効率的に行うことができます。本記事では、VBAの代表的なループ処理について、主な使用例を添えて詳細に解説します。
まず、繰り返し処理は大まかに3種類に分けることができます。
- 指定した回数だけ処理を繰り返すループ処理 【For...Next ループ】
- 指定した条件で処理を繰り返すループ処理 【Do While ループ/Do Until ループ(Do ループ While/Do ループ Until)】
- 指定したすべての要素に対して処理を繰り返すループ処理 【For Each...Next ループ】
① 指定した回数だけ処理を繰り返すループ処理
【For...Next ループ】
For...Next ループは、指定した回数だけ処理を繰り返す場合に使用します。そのため、何行から何行まで処理する、といったように回数が決まっている場合に主に用います。
構文:
For...Next ループの構文は以下のようになります。(尚、Stepについては省略可能となります)
For "変数" = "開始数値" To "終了数値" Step "ステップ値"
'・・・処理・・・'
Next "変数"
変数にはカウントに用いる数値変数を指定します。そして、その数値変数の開始数値と終了数値を設定します。
ステップ値にはカウントの増減幅を指定します。デフォルトは1となりますが、この値を2とすることで1,3,5...といったように1つ置きで処理を行うことができます。
また、ステップ値には、マイナス数値も指定することができます。例えば、-1とすれば、iは1ずつ減っていきます。
セルの行を下から処理したい場合や、シートを後ろから処理したい場合に用います。これはとても便利で、使用機会も多いかと思います。
使用例:
例. 1~5の数値を出力する場合
Sub ForNextLoop()
Dim i As Integer
For i = 1 To 5
Debug.Print i
Next i
End Sub
出力結果
1
2
3
4
5
このコードでは、変数 i を1から5まで増加させながら、順番に出力します。
ステップ値は特に指定していないため、デフォルトの1となり、1ずつ増えていきます。
ここで忘れがちになるのが、カウントに用いる数値変数の宣言です。ここでは、Dim i As Integer というように宣言しています。これでFor文の中でカウントの変数が使えるようになります。
補足:ここでデバッグ機能の一つである ステップ イン を紹介したいと思います。ステップ イン とは、マクロを1行ずつ実行する方法になります。F8キーを押すことで1行ずつ実行を確認しながら、検証を進めていくことが可能となります。
これから実行する行には黄色いハイライトが出ます。F8を押すごとに、次の行へと実行を進めていくことができます。また、マウスカーソルを変数の上に乗せることで、その時の値がポップアップ表示されます。
次に1つ置きに処理する場合を見ていきます。
例. 1~5までの数値を1つ置きに出力する場合
Sub ForNextLoop()
Dim i As Integer
For i = 1 To 5 Step 2
Debug.Print i
Next i
End Sub
出力結果
1
3
5
先ほどとの違いは Step 2を入れていることくらいですが、これにより1行置きに処理することが可能となります。
次に逆順に処理する場合を見ていきます。
例. 1~5の数値を逆順に出力する場合
Sub ForNextLoop()
Dim i As Integer
For i = 5 To 1 Step -1
Debug.Print i
Next i
End Sub
出力結果
5
4
3
2
1
出力結果は i = 1 To 5 の逆になっていることが分かるかと思います。
処理を逆順にするには、Stepを-1とすることで実現可能となります。
例えば、セルの最終行から逆順に処理していきたい場合などは、以下のようにします。
例. セルの最終行から逆順に処理する場合(A1-A5に1-5の数値が入力されているとする)
Sub ForNextLoop()
Dim i As Long
Dim xlLastRow As Long
Dim LastRow As Long
'Excel自体の最終行を取得
xlLastRow = Cells(Rows.Count, 1).Row
' A列の最終行の行数を取得
LastRow = Cells(xlLastRow, 1).End(xlUp).Row
For i = LastRow To 1 Step -1
Debug.Print Cells(i, 1).Value
Next i
End Sub
出力結果
5
4
3
2
1
Excel自体の最終行を取得する理由としては、単純にExcelの入力データの最終行を入手するやり方(End(xlDown))だと、途中で空白セルがあった場合に空白セルの一個上のセルを最終行と認識してしまうからです。それを防ぐために、いったんExcel自体の一番下のセルまで飛んで、上に上がっていくという手法をとっています。
(ちなみにExcel自体の一番下は、Excel2003形式(拡張子が.xls)では65536行目で、Excel2007以降(拡張子が.xlsx)では1048576行目です。)
一番下のセルの行数は Rows.Count で取得し、上に上がる処理には End(xlUp) を使います。
合わせてセルの最終列も考慮して処理していく場合は、以下のように入れ子の形で書いていきます。
例. 最終セルから逆順に処理する場合(A1-C3に1-9の数値が入力されているとする)
Sub ForNextLoop()
Dim i As Long
Dim j As Long
Dim xlLastRow As Long
Dim LastRow As Long
Dim xlLastColumn As Long
Dim LastColumn As Long
'Excel自体の最終行を取得
xlLastRow = Cells(Rows.Count, 1).Row
' A列の最終行の行数を取得
LastRow = Cells(xlLastRow, 1).End(xlUp).Row
'Excel自体の最終列を取得
xlLastColumn = Cells(1, Columns.Count).Column
' 1行目の最終列の列数を取得
LastColumn = Cells(1, xlLastColumn).End(xlToLeft).Column
For i = LastRow To 1 Step -1
For j = LastColumn To 1 Step -1
Debug.Print Cells(i, j).Value
Next j
Next i
End Sub
出力結果
9
8
7
6
5
4
3
2
1
最終列から処理する場合でも最終行同様に、Excel自体の最終列を取得して、左に処理していくという手法をとっています。そうすることで、途中で空白セルがあった場合でも全ての入力列まで処理ができるようになります。
一番右端のセルの列数は Columns.Count で取得し、左に処理していくには End(xlToLeft) を使います。
次にループを抜けるやり方を見ていきます。
処理の条件によっては途中でループを抜けたい、といった場合がおそらく出てくるかと思います。
For...Next ループを抜けるには Exit For を使います。
例. 特定の条件の時にループを抜ける場合(For...Next ループ)
Sub ForNextLoop()
Dim i As Integer
For i = 1 To 5
If i = 4 Then Exit For
Debug.Print i
Next i
End Sub
出力結果
1
2
3
特定の条件の時だけ処理をスキップして、それ以降も引き続き処理を行う場合は、以下のように GoTo を利用します。
例. 特定の条件の時だけ処理をスキップする場合(For...Next ループ)
Sub ForNextLoop()
Dim i As Integer
For i = 1 To 5
If i = 4 Then GoTo CONTINUE:
Debug.Print i
CONTINUE:
Next i
End Sub
出力結果
1
2
3
5
他の記事へ
Excel VBA でよく使う繰り返し処理【②Do While ループ/Do Until ループ(Do ループ While/Do ループ Until)】