For Eachでセルを回す
For Eachは「範囲の中の各セルを、順番に1つずつ」処理するための直感的な書き方。行番号の管理やサイズ計算が不要で、初心者でも安全に使えます。用途別の最短コードと実務テンプレートをまとめました。
基本構造と最短コード
Sub ForEach_Basic()
Dim c As Range
For Each c In Range("A2:A10")
c.Value = c.Value & "★" '例:末尾に印を付ける
Next c
End Sub
VB- ポイント:
- 要素はRange: ループ変数は必ず Range 型にする。
- 範囲は連続でも非連続でもOK: UnionやSpecialCellsで作った集合も回せる。
条件付き処理(空欄スキップ、値で分岐)
Sub ForEach_Condition()
Dim c As Range
For Each c In Range("B2:B100")
If c.Value <> "" Then
If c.Value >= 80 Then
c.Interior.Color = RGB(198, 239, 206) '合格は緑
Else
c.Interior.Color = RGB(255, 199, 206) '不合格は赤
End If
End If
Next c
End Sub
VB- ポイント:
- 空欄チェック: 無駄な処理を減らす基本。
- 見やすさ改善: 背景色やフォント変更などの表示制御は効果的。
行・列をまとめて扱う(EntireRow / EntireColumn)
Sub ForEach_RowWise()
Dim c As Range
For Each c In Range("A2:A50") 'キー列だけ回す
If c.Value = "緊急" Then
c.EntireRow.Font.Bold = True '行を強調
c.EntireRow.RowHeight = 20 '高さ調整
End If
Next c
End Sub
Sub ForEach_ColumnWise()
Dim c As Range
For Each c In Range("C1:F1") '見出し行の対象列
c.EntireColumn.AutoFit
Next c
End Sub
VB- ポイント:
- 1列に限定して行単位: 行重複を避け、c.Rowで横展開がしやすい。
- 行全体変更: EntireRow/EntireColumnで範囲拡張。
非表示・フィルタ連動:見えているセルだけ回す
Sub ForEach_VisibleOnly()
Dim vis As Range, c As Range
On Error Resume Next
Set vis = Range("A2:E200").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not vis Is Nothing Then
For Each c In vis.Columns(1).Cells '1列に限定して行単位
'見出し除外
If c.Row >= 2 Then
Cells(c.Row, "G").Value = Cells(c.Row, "C").Value * Cells(c.Row, "D").Value
End If
Next c
End If
End Sub
VB- ポイント:
- SpecialCells(xlCellTypeVisible): フィルタ後の可視セルだけ取得。
- 列を1本に絞る: 「行単位処理」で重複を避ける定石。
空白セル・エラーセルだけ狙い撃ち
Sub ForEach_BlanksAndErrors()
Dim blanks As Range, errs As Range, c As Range
On Error Resume Next
Set blanks = Range("C2:C200").SpecialCells(xlCellTypeBlanks)
Set errs = Range("D2:D200").SpecialCells(xlCellTypeFormulas, xlErrors)
On Error GoTo 0
If Not blanks Is Nothing Then
For Each c In blanks
c.Value = "N/A" '空白の穴埋め
Next c
End If
If Not errs Is Nothing Then
For Each c In errs
c.ClearContents 'エラー値のクリア
Next c
End If
End Sub
VB- ポイント:
- 対象0件エラー対策: SpecialCellsは該当なしでエラーになるため、On Errorでガード。
非連続範囲をまとめて回す(Union)
Sub ForEach_UnionRanges()
Dim tgt As Range, c As Range
Set tgt = Union(Range("B2:B50"), Range("D2:D50"), Range("F2:F50"))
For Each c In tgt
c.Value = UCase$(c.Value) '大文字化
Next c
End Sub
VB- ポイント:
- Union: 離れた範囲を1つに合成して回せる。
- 書式・計算一括適用: 見出しや複数列への同じ処理に便利。
実務テンプレート:For Eachで安全・高速運用
Sub ForEach_SpeedWrap()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim c As Range
For Each c In Range("E2:E2000")
If c.Value <> "" Then c.Value = Round(c.Value, 0)
Next c
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
VB- ポイント:
- 画面更新・再計算制御: 大量処理の体感速度を改善。
- 数式セル注意: 値の上書きは数式消失。必要なら「別列へ出力」or「PasteSpecial(xlValues)」で対応。
例題で練習
例題1:氏名列を「姓, 名」へ整形
Sub Example_SplitName()
Dim c As Range, parts As Variant
For Each c In Range("B2:B100")
If InStr(c.Value, " ") > 0 Then
parts = Split(c.Value, " ")
Cells(c.Row, "G").Value = parts(0) & ", " & parts(1)
End If
Next c
End Sub
VB例題2:重要フラグ(F列=”重要”)の行だけ計算結果をG列へ
Sub Example_ImportantCalc()
Dim c As Range
For Each c In Range("F2:F200")
If c.Value = "重要" Then
Cells(c.Row, "G").Value = Cells(c.Row, "C").Value * Cells(c.Row, "D").Value
End If
Next c
End Sub
VB例題3:フィルタ表示中の金額列(E)だけ合計してH2へ
Sub Example_SumVisible()
Dim vis As Range, c As Range, s As Double
On Error Resume Next
Set vis = Range("E2:E1000").SpecialCells(xlCellTypeVisible)
On Error GoTo 0
If Not vis Is Nothing Then
For Each c In vis
s = s + Val(c.Value)
Next c
Range("H2").Value = s
End If
End Sub
VB実務の落とし穴と対策
- 行単位の重複処理: 表全体の可視セルを回すと列数分ヒットして重複処理になる。列1本に限定し、c.Rowで横展開する。
- 数式の破壊: c.Valueで上書きすると数式が消える。値化したいのか、見た目だけ変えたいのかを明確に。見た目なら Interior/Font/NumberFormat を使う。
- 0件時のエラー: SpecialCellsは該当なしでエラー。On ErrorとNothingチェックをテンプレート化。
- 速度最適化: 画面更新・自動計算OFF、Select/Activateは使わない、まとめて処理できるところは「範囲演算(dst.Value = src.Value)」に切り替える。
