VBA実務メモ

Excel VBAのAutoFilterで
範囲を明示する理由

空白行を含む変則的なシートで、単一セルに任せた範囲認識が想定とずれた。実際の失敗から、安定したフィルター処理を整理します。

Excel VBAで表を処理するとき、データを別の場所へ転記するより、必要な行だけをフィルタリングした方が簡単な場合があります。

今回実現したかったのは、対象ブックとシートを直接編集し、そのまま印刷する次の処理です。

  1. 01
    H列で絞り込む指定した値に一致する行だけを表示
  2. 02
    行全体をグレーにする表示されているデータ行だけを処理
  3. 03
    絞り込みを解除する次のフィルターへ進む前に全件表示
  4. 04
    F列で絞り込んで印刷する確認中は印刷プレビューを使用
i

実際のブック名・シート名・検索値は、すべてサンプル用の名称に置き換えています。

SHEET STRUCTURE

今回のシートは少し変則的

3行目に見出しがあり、4~6行目が空白、7行目からデータが始まる構成でした。データの直上にフィルターを置くため、6行目をAutoFilterの基準行として使います。

サンプルシート
ABCDEFGH
3管理No.日付工程内容担当区分備考状態
4
5
6
70019/1組立点検佐藤A対象値1
80029/2検査確認鈴木B再確認完了
90039/3加工交換高橋B対象値1
100049/4組立調整田中A継続確認中
110059/5検査記録伊藤B完了

4~6行目に空白があり、7行目からデータが始まります。

THE PROBLEM

単一セルだけを指定していた

当初は、6行目の左端セルだけを指定してAutoFilterを実行していました。

VBA
ws.Range("A6").AutoFilter

単一セルだけを指定すると、AutoFilterを適用する表の範囲はExcel側の自動認識に委ねられます。

今回のように空白行を含む特殊な構成では、自動認識された範囲が後続の処理と一致せず、絞り込んだ行だけではなく、表全体がグレーになる現象が発生しました。

原因は検索条件ではなく、「どこからどこまでを表として扱うか」が曖昧だったこと。

THE FIX

A6からH列の最終行までを指定する

対策はシンプルです。Excelに範囲を推測させず、フィルターを適用する長方形の範囲をコードで明示します。

VBA
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:=8

A列から始まる範囲の8列目、つまりH列を対象にする。

Criteria1

絞り込みに使用する検索条件を指定する。

最終行を取得する書き方

VBA
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row

A列の一番下から上方向へ移動し、最初に値が見つかった行番号を取得しています。この例では、A列が必ず入力されることを前提にしています。

VISIBLE ROWS

表示されているデータ行だけを塗る

実際のデータは7行目から始まるため、塗りつぶす範囲も素直にA7:H最終行と指定します。

VBA
Set visibleRows = ws.Range("A7:H" & lastRow) _
    .SpecialCells(xlCellTypeVisible)

visibleRows.EntireRow.Interior.Color = RGB(217, 217, 217)

SpecialCells(xlCellTypeVisible)で、フィルター後も表示されているセルだけを取得します。今回はEntireRowを付け、該当する行全体をグレーにしています。

行全体を塗るvisibleRows.EntireRow.Interior.Color
A~H列だけを塗るvisibleRows.Interior.Color

ERROR HANDLING

On Error GoTo 0は「0へ飛ぶ」ではない

検索条件に一致する行がないと、SpecialCellsがエラーになることがあります。その箇所だけ一時的にエラーを無視します。

VBA
'該当行がない場合のエラーだけ一時的に無視
On Error Resume Next

Set visibleRows = ws.Range("A7:H" & lastRow) _
    .SpecialCells(xlCellTypeVisible)

'通常のエラー処理に戻す
On Error GoTo 0

On Error GoTo 0は、0番の行へ移動する命令でも、処理を終了する命令でもありません。On Error Resume Nextによるエラー無視を終了し、通常の状態に戻す命令です。

COMPLETE SAMPLE

処理全体のサンプル

処理の流れを追いやすくするため、変数は最終行と表示行の2つに絞っています。

VBA
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は、必ずしも整った表ばかりではありません。だからこそ、コード側で対象範囲を明確にしておくことが、安定した処理につながります。

VBA・Excel自動化の記事