With構文を使う高速化
同じオブジェクトに何度もアクセスする処理を「ひとまとまり」にすると、可読性が上がり、無駄な参照解決が減って少し速くなります。VBAの With 構文は、Range や Worksheet、Chart などの連続操作を簡潔・効率的に書くための基本テクです。
基本構文と効果
'Without With
Sub NoWith()
Range("A1").Font.Bold = True
Range("A1").Font.Size = 14
Range("A1").Interior.Color = vbYellow
End Sub
'Withでまとめる
Sub UseWith()
With Range("A1")
.Font.Bold = True
.Font.Size = 14
.Interior.Color = vbYellow
End With
End Sub
VB- ポイント: オブジェクト参照(例: Range(“A1”))を繰り返さないので、記述が短く、参照解決回数を減らして軽微な速度向上が期待できます。モダン環境では主に可読性メリットが大きいですが、実務では「無駄アクセスの削減」による僅かな改善も得られます。
- 書き方のコツ: With ターゲットの直後に「.メンバー」を並べ、最後に End With で閉じます。
実務テンプレート
1) セル書式をまとめて設定
'1) セル書式をまとめて設定
Sub FormatBlock()
With Range("B2:B1000")
.NumberFormat = "#,##0"
.Font.Color = RGB(0, 102, 204)
.Interior.Color = RGB(235, 241, 222)
.HorizontalAlignment = xlRight
End With
End Sub
VB2) シートと範囲操作を階層的に
'2) シートと範囲操作を階層的に
Sub SheetAndRange()
Dim sht As Worksheet
Set sht = ThisWorkbook.Worksheets("明細")
With sht
.Cells(1, 1).Value = "タイトル"
With .Range("C2:D50000")
.Value = 0
.Borders.LineStyle = xlContinuous
End With
End With
End Sub
VB3) グラフの体裁を一気に調整
'3) グラフの体裁を一気に調整
Sub ChartStyle()
Dim ch As ChartObject
Set ch = ActiveSheet.ChartObjects(1)
With ch.Chart
.ChartTitle.Text = "売上推移"
.Legend.Position = xlLegendPositionBottom
.HasTitle = True
.Axes(xlCategory).HasTitle = True
.Axes(xlCategory).AxisTitle.Text = "月"
End With
End Sub
VB- ポイント: 同一オブジェクト(sht、Range、Chart)への操作を塊にして、コード短縮と参照解決の削減で効率化します。
ループと組み合わせる高速パターン
'行ごとに1回だけ With を張り、列操作をまとめる
Sub LoopWithRow()
Dim r As Long, last As Long
last = Cells(Rows.Count, "A").End(xlUp).Row
For r = 2 To last
With Cells(r, 1).EntireRow
.Columns("E").Value = Cells(r, "C").Value * Cells(r, "D").Value
.Columns("F").Value = "処理済"
End With
Next r
End Sub
'巨大範囲は配列×一括書き戻し + Withで体裁
Sub ArrayThenFormat()
Dim rg As Range, v As Variant
Set rg = Range("E2:H100000")
v = rg.Value
Dim i As Long, j As Long
For i = 1 To UBound(v, 1)
For j = 1 To UBound(v, 2)
If IsNumeric(v(i, j)) Then v(i, j) = v(i, j) * 1.1
Next j
Next i
rg.Value = v
With rg
.NumberFormat = "#,##0.00"
.Interior.Color = RGB(242, 242, 242)
End With
End Sub
VB- ポイント: セル個別アクセスは遅いので、計算は配列で一括、整形は With で塊に。これが「見た目の一括適用+処理の最小アクセス」の定石です。
ネストと複合例
'シート→レンジ→Font/Interior を段階的に
Sub NestedWith()
With Worksheets("Report")
.Cells(1, 1).Value = "サマリー"
With .Range("A2:D2")
.Value = Array("顧客", "金額", "数量", "単価")
With .Font
.Bold = True
.Color = RGB(255, 255, 255)
End With
With .Interior
.Color = RGB(0, 102, 204)
End With
End With
End With
End Sub
VB- ポイント: With のネストで構造を明確化。対象が変わる階層ごとにまとめると読みやすく、修正しやすいコードになります。
例題で練習
'例題1:A1にタイトルと書式を一気に適用
Sub Example_Title()
With Range("A1")
.Value = "月次レポート"
.Font.Bold = True
.Font.Size = 16
.HorizontalAlignment = xlCenter
End With
End Sub
'例題2:選択範囲の見た目を整える(罫線・塗り・フォント)
Sub Example_FormatSelection()
If TypeName(Selection) = "Range" Then
With Selection
.Borders.LineStyle = xlContinuous
.Interior.Color = RGB(255, 255, 204)
.Font.Color = RGB(0, 51, 102)
End With
End If
End Sub
'例題3:ChartObjectのサイズ・位置・体裁をまとめて
Sub Example_ChartLayout()
Dim co As ChartObject
Set co = ActiveSheet.ChartObjects(1)
With co
.Left = 20
.Top = 40
.Width = 480
.Height = 280
.Chart.Legend.Position = xlLegendPositionRight
End With
End Sub
VB落とし穴と対策
- ドットの付け忘れ: With ブロック内は「.プロパティ/.メソッド」で記述。付け忘れると別オブジェクト参照になり、意図しない動作やエラーの原因になります。
- ターゲットの誤指定: With の対象はブロック開始時に解決されます。途中で別対象に切り替わる想定の処理には不向きなので、ブロックを分けて書きます。
- 過度なネスト: 深すぎる入れ子は可読性を損なうため、シート→範囲→書式の3段階程度までに抑えると保守性が高いです。
- 速度の期待値: With は参照の繰り返しを減らせますが、効果は「主に可読性と微かな効率化」。大幅な高速化は「配列一括・SpecialCells・計算モード制御」と併用するのが現実的です。
使い分けの指針
- 書式や値設定を連続適用する場面: With で対象をまとめて、短く・安全に記述。
- 重い処理(大量計算・参照置換): With は体裁適用に留め、計算は配列・辞書で行うのが速い。
- 保守・可読性重視: ネストの深さは控えめに、変数へ Set してから With を使うと対象が明確になります。
