Excel VBAのAutoFilterで
範囲を明示する理由
空白行を含む変則的なシートで、単一セルに任せた範囲認識が想定とずれた。実際の失敗から、安定したフィルター処理を整理します。
Excel VBAで表を処理するとき、データを別の場所へ転記するより、必要な行だけをフィルタリングした方が簡単な場合があります。
今回実現したかったのは、対象ブックとシートを直接編集し、そのまま印刷する次の処理です。
- 01H列で絞り込む指定した値に一致する行だけを表示
- 02行全体をグレーにする表示されているデータ行だけを処理
- 03絞り込みを解除する次のフィルターへ進む前に全件表示
- 04F列で絞り込んで印刷する確認中は印刷プレビューを使用
実際のブック名・シート名・検索値は、すべてサンプル用の名称に置き換えています。
SHEET STRUCTURE
今回のシートは少し変則的
3行目に見出しがあり、4~6行目が空白、7行目からデータが始まる構成でした。データの直上にフィルターを置くため、6行目をAutoFilterの基準行として使います。
| A | B | C | D | E | F | G | H | |
|---|---|---|---|---|---|---|---|---|
| 3 | 管理No. | 日付 | 工程 | 内容 | 担当 | 区分 | 備考 | 状態 |
| 4 | ||||||||
| 5 | ||||||||
| 6 | ▼ | ▼ | ▼ | ▼ | ▼ | ▼ | ▼ | ▼ |
| 7 | 001 | 9/1 | 組立 | 点検 | 佐藤 | A | ― | 対象値1 |
| 8 | 002 | 9/2 | 検査 | 確認 | 鈴木 | B | 再確認 | 完了 |
| 9 | 003 | 9/3 | 加工 | 交換 | 高橋 | B | ― | 対象値1 |
| 10 | 004 | 9/4 | 組立 | 調整 | 田中 | A | 継続 | 確認中 |
| 11 | 005 | 9/5 | 検査 | 記録 | 伊藤 | B | ― | 完了 |
4~6行目に空白があり、7行目からデータが始まります。
THE PROBLEM
単一セルだけを指定していた
当初は、6行目の左端セルだけを指定してAutoFilterを実行していました。
ws.Range("A6").AutoFilter単一セルだけを指定すると、AutoFilterを適用する表の範囲はExcel側の自動認識に委ねられます。
今回のように空白行を含む特殊な構成では、自動認識された範囲が後続の処理と一致せず、絞り込んだ行だけではなく、表全体がグレーになる現象が発生しました。
原因は検索条件ではなく、「どこからどこまでを表として扱うか」が曖昧だったこと。
THE FIX
A6からH列の最終行までを指定する
対策はシンプルです。Excelに範囲を推測させず、フィルターを適用する長方形の範囲をコードで明示します。
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
ws.Range("A6:H" & lastRow).AutoFilter _
Field:=8, _
Criteria1:="対象値1"A6:Hフィルターを置く6行目から、表の右端であるH列まで。
& lastRow固定の行番号ではなく、データが入力されている最終行まで。
Field:=8A列から始まる範囲の8列目、つまりH列を対象にする。
Criteria1絞り込みに使用する検索条件を指定する。
最終行を取得する書き方
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).RowA列の一番下から上方向へ移動し、最初に値が見つかった行番号を取得しています。この例では、A列が必ず入力されることを前提にしています。
VISIBLE ROWS
表示されているデータ行だけを塗る
実際のデータは7行目から始まるため、塗りつぶす範囲も素直にA7:H最終行と指定します。
Set visibleRows = ws.Range("A7:H" & lastRow) _
.SpecialCells(xlCellTypeVisible)
visibleRows.EntireRow.Interior.Color = RGB(217, 217, 217)SpecialCells(xlCellTypeVisible)で、フィルター後も表示されているセルだけを取得します。今回はEntireRowを付け、該当する行全体をグレーにしています。
visibleRows.EntireRow.Interior.ColorvisibleRows.Interior.ColorERROR HANDLING
On Error GoTo 0は「0へ飛ぶ」ではない
検索条件に一致する行がないと、SpecialCellsがエラーになることがあります。その箇所だけ一時的にエラーを無視します。
'該当行がない場合のエラーだけ一時的に無視
On Error Resume Next
Set visibleRows = ws.Range("A7:H" & lastRow) _
.SpecialCells(xlCellTypeVisible)
'通常のエラー処理に戻す
On Error GoTo 0On Error GoTo 0は、0番の行へ移動する命令でも、処理を終了する命令でもありません。On Error Resume Nextによるエラー無視を終了し、通常の状態に戻す命令です。
COMPLETE SAMPLE
処理全体のサンプル
処理の流れを追いやすくするため、変数は最終行と表示行の2つに絞っています。
Option Explicit
Sub FilterColorAndPrint()
Dim lastRow As Long
Dim visibleRows As Range
With ThisWorkbook.Worksheets("対象シート")
'A列を基準に最終行を取得
lastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
'H列を対象値1で絞り込む
.Range("A6:H" & lastRow).AutoFilter _
Field:=8, _
Criteria1:="対象値1"
'7行目以降の表示行を取得
On Error Resume Next
Set visibleRows = .Range("A7:H" & lastRow) _
.SpecialCells(xlCellTypeVisible)
On Error GoTo 0
'該当した行をグレーにする
If Not visibleRows Is Nothing Then
visibleRows.EntireRow.Interior.Color = _
RGB(217, 217, 217)
End If
'絞り込みを解除
If .FilterMode Then
.ShowAllData
End If
'F列を対象値2で絞り込む
.Range("A6:H" & lastRow).AutoFilter _
Field:=6, _
Criteria1:="対象値2"
'動作確認時は印刷プレビューを使用
.PrintPreview
End With
End Sub動作確認中はPrintOutではなくPrintPreviewを使うと、意図しない印刷を防げます。
SUMMARY
範囲を明示すれば、変則的な表にも対応できる
- 単一セルの指定では、表の範囲認識をExcelに委ねることになる
- 空白行を含むシートでは、開始行・終了行・対象列を明示する
- 実データが7行目からなら、処理範囲も
A7:H最終行と素直に書く - 該当行が0件の場合を考慮し、エラー無視は必要な箇所だけに限定する
- AutoFilterは、着色・印刷・集計・転記にも応用できる
現場のExcelは、必ずしも整った表ばかりではありません。だからこそ、コード側で対象範囲を明確にしておくことが、安定した処理につながります。