悩んでる人VB.NETのFor Each文の使い方がよく分からない



For文との違いってなんだろう? どっちを使えばいいのか、いつも迷ってしまう。
開発現場に入ると、配列やリストを扱う場面って本当にたくさん出てきます。
「ループ処理」は、基本中の基本ですが、複数の書き方から、どれを選べばいいか迷うことも多いと思います。
ループ処理の使い分けって、なかなか難しいですよね。
本記事では、VB.NETのFor Each文について、初心者の方にも分かるように丁寧に解説していきます。
サンプルコードを交えながら、実際の現場でも使えるテクニックまでまとめましたので、理解のお役に立てれば幸いです。
For Each文とは
For Each文とは、「コレクション」の中身を、1つずつ順番に取り出して処理する構文です。



コレクションって何?
簡単に言うと、複数の値をまとめて入れておける箱のようなものです!
例えば、配列やList、Dictionary、DataTableなどがコレクションに該当します。
スーパーで買ってきた食材が入った袋をイメージしてみてください!
「袋(配列やリスト)」の中から「食材(要素)」を1つずつ取り出して、決まった処理(洗う・切る)をしていく、というイメージです。
VB.NETのFor Each文の基本的な書き方
For Each文の基本的な書き方は以下の通りです。
For Each 取り出した要素の変数 As データ型 In コレクション
' ここに処理を書く
Next各部分の意味を整理すると、以下のようになります。
- 取り出した要素の変数:
- コレクションから1つずつ取り出された値が入る変数
- データ型:
- 取り出される要素の型(Integer、Stringなど)
- コレクション:
- 処理対象となる配列やリストなど
- Next:
- For Each文の終わりを表す(必須)
書き方さえ覚えてしまえば、あとはコレクションを指定するだけで、要素の数だけループ処理を実行してくれます。
ループ回数を自分で計算しなくていいので、すごく便利ですよね!
For Each文の具体的なサンプルコード
ここからは、実際にFor Each文を使ったサンプルコードを紹介していきます。
手元にVisual Studioがある方は、ぜひ実際にコードを書いて動かしてみてください!
配列をループする場合
まずは、一番基本的な配列をループする例です。
Module Module1
Sub Main()
' 文字列の配列を準備
Dim fruits() As String = {"りんご", "みかん", "バナナ"}
' For Each文で配列の中身を順番に取り出す
For Each fruit As String In fruits
Console.WriteLine(fruit)
Next
Console.ReadKey()
End Sub
End Module実行結果は以下のようになります。
りんご
みかん
バナナ
配列の中身が、順番に1つずつ取り出されているのが分かります。
Listをループする場合
次に、Listをループする例です。
Module Module1
Sub Main()
' Integer型のListを準備
Dim numbers As New List(Of Integer) From {10, 20, 30, 40, 50}
' For Each文でListの中身を順番に取り出す
Dim sum As Integer = 0
For Each num As Integer In numbers
sum = sum + num
Next
Console.WriteLine("合計:" & sum)
Console.ReadKey()
End Sub
End Module実行結果は以下の通りです。
合計:150
Listの中身を1つずつ取り出して、合計値を計算しています。
DataTableをループする場合
実務でよく出てくるのが、DataTableのループです。
データベースから取得したデータを処理する場面で、本当によく使います。
Module Module1
Sub Main()
' DataTableを準備
Dim dt As New DataTable()
dt.Columns.Add("名前", GetType(String))
dt.Columns.Add("年齢", GetType(Integer))
' データを追加
dt.Rows.Add("田中", 25)
dt.Rows.Add("鈴木", 30)
dt.Rows.Add("佐藤", 28)
' For Each文でDataTableの行を順番に取り出す
For Each row As DataRow In dt.Rows
Console.WriteLine(row("名前") & "さん:" & row("年齢") & "歳")
Next
Console.ReadKey()
End Sub
End Module実行結果は以下のようになります。
田中さん:25歳
鈴木さん:30歳
佐藤さん:28歳
DataTableの行(DataRow)を1行ずつ取り出して、列の値を表示しています。
DataTableのループは現場でめちゃくちゃ使うので、書き方を覚えておくと便利ですよ!
For Each文を途中で終わらせる・スキップする方法
ループの途中で終了したり、特定の処理をスキップしたい場面ってありますよね。
そんなときに使うのが、Exit ForとContinue Forです。
Exit For:ループを途中で終了する
Exit Forを使うと、ループ処理を途中で終了させることができます。
Module Module1
Sub Main()
Dim numbers() As Integer = {1, 2, 3, 4, 5}
For Each num As Integer In numbers
' 値が3になったらループを抜ける
If num = 3 Then
Exit For
End If
Console.WriteLine(num)
Next
Console.ReadKey()
End Sub
End Module実行結果は以下の通りです。
1
2
値が3になった時点でループが終了するので、3以降は処理されません。
Continue For:特定の処理をスキップする
Continue Forを使うと、その回だけスキップして次のループに進むことができます。
Module Module1
Sub Main()
Dim numbers() As Integer = {1, 2, 3, 4, 5}
For Each num As Integer In numbers
' 値が3のときだけスキップする
If num = 3 Then
Continue For
End If
Console.WriteLine(num)
Next
Console.ReadKey()
End Sub
End Module実行結果は以下のようになります。
1
2
4
5
3のときだけスキップされて、それ以降の処理は通常通り続いています。
For文とFor Each文の使い分け



For文とFor Each文って、どっちを使えばいいの?
これって、初心者の方が一番悩むところだと思います。
結論から言うと、コレクションの全要素を順番に処理するだけなら、For Each文を使うのがおすすめです。
それぞれの特徴を整理してみました。
For文が向いている場面
- ループ回数が決まっている
- インデックス(何番目の要素かという番号)を使いたい
- 逆順で処理したい
- 飛ばし飛ばしで処理したい(2つおき、3つおきなど)
For Each文が向いている場面
- コレクションの全要素を順番に処理したい
- 要素数が分からない(または気にしなくていい)
- コードをシンプルに書きたい
- インデックスを使う必要がない
For Each文のメリットは、なんといってもコードがシンプルで読みやすくなることです。
For文だと「i = 0 から始まって、何回まで」といった条件を自分で書く必要がありますが、For Each文ならそういった面倒な部分を書かなくて済みます。
その結果、バグも生みにくくなるので、要素を全件処理するならFor Each文を選ぶのがいいと思います。
For Each文を使うときの注意点
ここからは、実際に現場でハマりやすい注意点を紹介します。
知っておくとトラブルを避けられるので、しっかり押さえておきましょう。
注意点①:ループ中にコレクションの中身を変更しない
For Each文でループしている最中に、対象のコレクションに要素を追加・削除すると、エラーが発生します。
Module Module1
Sub Main()
Dim fruits As New List(Of String) From {"りんご", "みかん", "バナナ"}
For Each fruit As String In fruits
' ↓これはエラーになる
fruits.Add("いちご")
Next
End Sub
End Moduleこのコードを実行すると、InvalidOperationExceptionという例外が発生してプログラムが止まります。
ループ中にコレクションを変更したい場合は、別のリストに退避させてから処理するなど、工夫が必要です。
注意点②:要素自体は変更できない
For Each文で取り出した変数に値を代入しても、元のコレクションは変わりません。
Module Module1
Sub Main()
Dim numbers() As Integer = {1, 2, 3}
For Each num As Integer In numbers
num = num * 2 ' ←ここで変更しても、元のnumbersは変わらない
Next
For Each num As Integer In numbers
Console.WriteLine(num) ' 1, 2, 3 のまま
Next
Console.ReadKey()
End Sub
End Module要素そのものを変更したい場合は、For文を使ってインデックス指定で書き換える必要があります。
注意点③:Nothingのコレクションに注意
コレクションがNothingの状態でFor Each文を実行すると、NullReferenceExceptionが発生します。
Dim list As List(Of String) = Nothing
For Each item As String In list ' ←ここでエラー
Console.WriteLine(item)
Next実務では、データベースの検索結果など、状況によってNothingになる可能性のあるコレクションを扱う場面が出てきます。
そういう場合は、事前にIf Not list Is Nothing Thenのようにチェックしておくと安全です。
エラーで動かないと焦りますが、原因を知っておけば対策できます!
まとめ
本記事では、VB.NETのFor Each文について、基本的な使い方から実践的な注意点までを解説しました。
ポイントをまとめると、以下の通りです。
- For Each文は、配列やリストの中身を順番に取り出す繰り返し構文
- ループ回数を指定しなくていいので、コードがシンプルになる
Exit Forでループを抜ける、Continue Forで処理をスキップできる- 全要素を処理するならFor Each文、インデックスが必要ならFor文を使う
- ループ中にコレクションを変更するとエラーになるので注意
ループ処理は、システム開発でほぼ毎日と言っていいほど使う基本的な機能です。
For Each文を使いこなせるようになれば、コードもスッキリして、バグも減らせるようになります。
最初のうちは少しずつでいいので、サンプルコードを実際に動かしながら、自分の手に馴染ませていきましょう!
本記事が、VB.NETでループ処理を書くときの参考になれば嬉しいです。
