.NET開発者のためのブログメディア
VBAでcontinue代わりになる命令文とは?GoToの使い方を紹介
- SE
- For Eachの使い方が知りたいです。
- PM
- For Eachで繰り返し処理ができます。それでは見ていきましょう。
目次
VBAには「ループの先頭に戻る」という命令がない?
C言語やJava言語など、他の言語を知っている方であれば『無限ループを作成しておいて、必要に応じてループを抜けたり、ループの先頭に戻ったりする』という処理を考えることがあるでしょう。そうすると、必須なのが『break命令』と『continue命令』です。
VBAの場合は、途中でループを抜ける「Exit」命令はあるものの、ループの先頭に戻る、continueに当たる命令が言語として実装されていません。「なんでVBAはbreakがあるのにcontinueが無いの?」「ここでcontinueしたいのに!」と、思うことも多いでしょう。
ですが、実装されていないものは仕方がないので、別の方法で解決するしかありません。ここでは、VBAでcontinueの代わりになる命令について紹介していきます。
VBAでcontinue代わりになる命令文とは?
VBAでcontinueの代用をする場合は「GoTo」という命令を使います。GoTo命令は「指定したラベル先へ処理をジャンプさせる」という命令です。処理をスキップしたり、try~catchのようなエラー処理をしたりする場合によく使われます。
ラベルは同じプロシージャ内にだけ付けることができます。他のプロシージャへジャンプさせることはできません。
では、どのようにしてGoTo命令でcontinueのような処理を実現するのか解説していきます。
VBAにおけるGoToの使い方3つ
VBAにおけるGoToの使い方として
1.For Eachの中でGoToを使い、ループをスキップするやり方
2.ループの最後のラベルに処理を移すやり方
3.ループの先頭のIf文で条件判定するやり方
の3つがあります。
早速、見ていきましょう。
1:For EachでGoToでループをスキップするやり方
VBAでのループをスキップする方法を紹介します。continueに相当します。VBAでは、GoToを使用します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
Sub macro1()
' 配列の宣言'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' 配列のForループ'
For Each Item In myArray
If Item = 3 Then
' 要素が3の場合、Continue:の行に移動'
GoTo Continue
End If
' イミディエイトウィンドウに出力'
Debug.Print (Item)
' GoTo Continueでここにくる'
Continue:
Next Item
End Sub
|
1
2
3
4
|
1
2
4
5
|
break相当の記述方法
ループの外に「Continue:」を記述すれば、break相当になります。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
Sub macro2()
' 配列'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' 配列のForループ'
For Each item In myArray
If item = 3 Then
' 要素が3の場合、Break:の行に移動'
GoTo Break
End If
' イミディエイトウィンドウに出力'
Debug.Print (item)
Next item
' GoTo Breakでここにくる'
Break:
End Sub
|
実行結果は以下のようになります。
1
2
|
1
2
|
GoToでもbreakは実現できますが、可読性が低くなるのでExit Forのほうが良いでしょう。
2:ループの最後のラベルに処理を移すやり方
ループの最後に貼ったラベルに、処理を移す方法もあります。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
Sub macro3()
Dim i
For i = 0 To 5
If i = 1 Then
' CONTINUEラベルに処理を移す
GoTo CONTINUE
ElseIf i = 3 Then
' CONTINUEラベルに処理を移す
GoTo CONTINUE
End If
' GoToしない場合はループカウンタが出力される
Debug.Print i
CONTINUE: ' 次ループ処理を行うためにループの一番最後にラベルを用意する
Next
End Sub
|
実行結果は以下のようになります。
1
2
3
4
|
0
2
4
5
|
このようにFor文やWhile文でも、continue相当の処理を実現することができます。
3:ループの先頭のIf文で条件判定するやり方
ループの先頭のIf文で条件判定をするやり方もあります。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Sub macro4()
Dim i
Dim j
For i = 0 To 5
If i <> 1 Then
For j = 0 To 5
If j = 3 Then
Debug.Print i
End If
Next
End If
Next
End Sub
|
1
2
3
4
5
|
0
2
3
4
5
|
VBAでのその他のループ処理6つ
ここまで、continueの代わりになるGoTo命令について紹介してきました。
ですが、GoTo命令は多用しすぎると、コードが複雑になって読みにくくなる⇒バグの原因になるというリスクを抱えています。
ですので、ループの書き方を工夫することでGoTo命令の使用回数が減るのであれば、それに越したことはありません。
ここでは、VBAで使用できるループを6つ、ご紹介します。
1:配列のループ
VBAでの配列のループ方法を紹介します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
|
Sub macro5()
' 配列の宣言'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' 配列のForループ'
For Each Item In myArray
' イミディエイトウィンドウに出力'
Debug.Print (Item)
Next Item
End Sub
|
実行結果は以下のようになります。Debug.Printの結果はイミディエイトウィンドウに出力されます。イミディエイトウィンドウが表示されていない場合は、「表示(V)」→「イミディエイトウィンドウ(I)」を選択してください。
1
2
3
4
5
|
1
2
3
4
5
|
配列のすべての要素が表示されていることが分かります。このように、For Eachで繰り返し処理ができます。
2:逆順ループ
VBAでの配列の逆順ループ方法を紹介します。For Eachでは逆順ループは実現できないので、代わりにFor~Nextを使用します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
Sub macro6()
' 配列の宣言'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' ループインデックス'
Dim i As Integer
' 配列の逆順Forループ'
For i = UBound(myArray) To LBound(myArray) Step -1
' イミディエイトウィンドウに出力'
Debug.Print (myArray(i))
Next i
End Sub
|
実行結果は以下のようになります。
1
2
3
4
5
|
5
4
3
2
1
|
「Step -1」の部分が、ループインデックスiをデクリメントする指定です。
初期値である「UBound(myArray)」から最終値である「LBound(myArray)」とすることで、インデックスの大きいほうから逆順に処理が行われます。
このように、逆順に繰り返し処理をすることもできます。
3:break
VBAでのループ処理を抜ける方法を紹介します。プログラミング言語でよくある「break」に相当します。VBAではbreakはないので、その代わりに「Exit For」を使用します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Sub macro7()
' 配列の宣言'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' 配列のForループ'
For Each Item In myArray
If Item = 3 Then
' 要素が3の場合、ループを抜ける'
Exit For
End If
' イミディエイトウィンドウに出力'
Debug.Print (Item)
Next Item
End Sub
|
実行結果は以下のようになります。
1
2
|
1
2
|
「Exit For」でループ処理を抜けることが分かります。
「Exit Sub」とすることで、関数を抜けます。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Sub macro8()
' 配列の宣言'
Dim myArray() As Variant
myArray = Array(1, 2, 3, 4, 5)
' 配列のForループ'
For Each item In myArray
If item = 3 Then
' 要素が3の場合、関数Subを抜ける'
Exit Sub
End If
' イミディエイトウィンドウに出力'
Debug.Print (item)
Next item
End Sub
|
実行結果は以下のようになります。
1
2
|
1
2
|
このように、Exit Forでループ処理を抜け、Exit Subで関数を抜けることが分かります。
4:Range
VBAでのRangeのループ方法を紹介します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
|
Sub macro9()
' Range'
Dim item As Range
' RangeのForループ'
For Each item In Range("A1:C3")
' イミディエイトウィンドウに出力'
Debug.Print (item.Address)
Next
End Sub
|
実行結果は以下のようになります。
1
2
3
4
5
6
7
8
9
|
$A$1
$B$1
$C$1
$A$2
$B$2
$C$2
$A$3
$B$3
$C$3
|
Range内のアドレスがすべて表示されることが分かります。
5:Selection
VBAでのSelectionのループ方法を紹介します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
8
9
10
|
Sub macro10()
' Range'
Dim item As Range
' SelectionのForループ'
For Each item In Selection
' イミディエイトウィンドウに出力'
Debug.Print (item.Address)
Next item
End Sub
|
エクセルのセルを選択した状態でマクロを実行してみてください。実行結果は以下のようになります。
1
2
3
4
5
6
7
8
9
|
$A$1
$B$1
$C$1
$A$2
$B$2
$C$2
$A$3
$B$3
$C$3
|
選択したセルのアドレスが表示されることが分かります。
6:Worksheets
VBAでのWorksheetsのループ方法を紹介します。実際のソースコードを見てみましょう。
1
2
3
4
5
6
7
|
Sub macro11()
' WorksheetsのForループ'
For Each ws In Worksheets
' イミディエイトウィンドウに出力'
Debug.Print (ws.Name)
Next ws
End Sub
|
実行結果は以下のようになります。
1
2
3
|
Sheet1
Sheet2
Sheet3
|
エクセルのシートがすべて出力されることが分かります。
VBAでループ処理が重くなったときの対処法
ループの書き方を工夫し、GoTo命令を使用することでcontinueのような処理が作れたとしても、それが重たい処理になってしまった場合は、注意が必要です。
VBAでは、重たい処理をループさせようとすると、固まってしまう場合があります。
また、GoTo命令を多用しすぎた結果、ループの終了条件を間違えてしまって無限ループにしてしまった場合も、Excelが固まってしまいます。
普通の処理では、リセットボタンを押すことで処理を止めることができますが、上記のような場合は、もうExcel自体が動かなくなっているのでリセットボタンを押しても処理が止まりません。
このように固まってしまった場合は、処理を強制終了する必要があります。
処理が固まってしまった場合の強制終了の方法は、大きく分けて2つあります。
・Excelの警告メッセージからファイルを閉じる
・EscまたはCtrl + BreakキーでVBAの処理を強制終了する
それぞれ、詳しく解説していきます。
警告メッセージからファイルを閉じよう
Excelが固まってしまうと、警告メッセージが出ることがあります。
このメッセージの『→プログラムを終了します』を選択すればExcelを閉じることができます。
この方法の欠点はファイルを強制的に閉じてしまうので、これまで行った変更が消えてしまう場合があることです。
そのため、Excelが固まってもすぐにファイルを閉じずに、しばらく待ってみることをお勧めします。そして、それでも固まったまま動かないのであれば、上記の方法でExcelを閉じてみてください。
処理を強制終了しよう
他にも、Escキーまたは、Ctrl+Breakキーを押すと、VBAの処理を強制終了することができます。
こちらの方法のメリットは今まで書いたコードを残しつつ、処理を途中で止めることができることです。
デメリットは、キーボードによってはBreakキーがついていないことがある点と、PCの負荷状況によっては操作を受け付けてくれない場合がある点です。
- SE
- このように、VBAでのループの方法は何種類もあるのですね。
- PM
- 実際に自分でコードを書いてFor Eachの使い方をマスターしましょう。
VBAでcontinueの代わりにループ処理をスキップする方法を理解しよう
いかがでしたでしょうか。
VBAではcontinueという命令が実装されていないため、ループの回し方を工夫したり、GoToをうまく使って処理をスキップしたりする必要があります。
continueが使えないことで、C言語やJava言語では考えなかったようなループ処理を検討する必要があるのもVBAの醍醐味だと考えられるでしょう。
また、『GoToはバグの元!』と嫌悪感を持つ方も時々いらっしゃいます。ですが、それはGoToを乱発していたり、変なところにGoToを使っているのでソースの可読性が下がっているだけです。
大きく言えば、break命令もcontinue命令も、ルール化されたGoTo命令ですので「continueなら乱発しても良いが、GoToを使ってはいけない」というものもおかしな話です。
GoToは正しく使えば非常に優秀で便利な命令ですので、ぜひ、みなさんも怖がらずに使ってみてください。
Search キーワード検索
Popular 人気の記事
reccomended おすすめ記事
Categories 連載一覧
Tags タグ一覧
Jobs 新着案件
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅)