オートフィルタを掛けてみる。

執筆者:

カテゴリ:

目的

  • オートフィルタを掛けたい。
  • オートフィルタが掛かっているかどうかを調べたい。

オートフィルタを掛ける、かける、どちらの字で書いた方が良いのか分かりません。

オートフィルタモードにしてみる

Excel では以下の画像のような操作になると思います。

データ > フィルタ > オートフィルタ
データ > フィルタ > オートフィルタ

VBA での操作を試してみます。

  1. 下記の状態でテストしてみます。
下向き矢印が表示されていません。オートフィルタモードになっていない状態です。
下向き矢印が表示されていません。オートフィルタモードになっていない状態です。
  • 下記 URL に元データをアップロードしてあります。タブ区切りのテキストファイルになっています。
    https://pulogu.net/wordpress/wp-content/uploads/2024/02/sample.txt
    1. 上記 URL のデータをすべてコピー。
    2. Excel の A1 セルを右クリック。
    3. 「形式を選択して貼り付け」をクリック。
    4. 「HTML」「unicode テキスト」「テキスト」の中から「テキスト」をクリック。
    5. A1:C6 の範囲にデータがコピーされる。
  • 下記マクロを実行してみます。
    Sub オートフィルタモードになっているかを調べる()
    Debug.Print Worksheets(1).AutoFilterMode
    End Sub
    1. 実行結果は以下のようになりました。
  • False
    False
  • オートフィルタモードにしてみます。
    Sub オートフィルタモードにしてみる()
    Range("A1:C6").AutoFilter
    End Sub
    1. 実行結果は以下のようになりました。
  • 下向きの矢印が表示されている。オートフィルタモードになったようです。
    下向きの矢印が表示されている。オートフィルタモードになったようです。
  • 上記 3 のマクロを再度実行してみます。
    1. 実行結果は以下のようになりました。
  • オートフィルタモードが解除されている。
    オートフィルタモードが解除されている。
  • 上記 3 のマクロをもう一度実行してみます。
    1. 実行結果は以下のようになりました。
  • オートフィルタモードに戻っている。
    オートフィルタモードに戻っている。
  • 上記 3 のマクロを実行する度にオートフィルタモードの ON / OFF が切り替わりました。

  • オートフィルタモードになっている状態で、再度、AutoFilterMode プロパティを取得してみます。
    Sub 再度AutoFilterModeプロパティを取得()
    Debug.Print Worksheets(1).AutoFilterMode
    End Sub
    1. 実行結果は以下のようになりました。
  • True
    True
  • AutoFilterMode プロパティは False を設定できるようです。
    Sub AutoFilterModeをfalseに設定してみる()
    Worksheets(1).AutoFilterMode = False
    End Sub
    1. 実行結果は以下のようになりました。
  • オートフィルタモードが解除されている。
    オートフィルタモードが解除されている。
  • AutoFilterMode = True に設定しようとするとエラーが発生しました。False のみ設定可能なようです。
  • 実行時エラー'1004' Worksheet クラスの AutoFilterMode プロパティを設定できません。
    実行時エラー’1004′ Worksheet クラスの AutoFilterMode プロパティを設定できません。

    各列にフィルタを掛ける

    Excel では以下の画像のような操作になると思います。

    オートフィルタの範囲の 2 列目(B 列)にフィルタを掛けようとしている。
    オートフィルタの範囲の 2 列目(B 列)にフィルタを掛けようとしている。

    VBA での操作を試してみます。

    1. 下記の状態でテストしてみます。
    フィルタは掛かっていない状態です。
    フィルタは掛かっていない状態です。
  • 下記マクロを実行してみます。
    Sub 一列目数値3以上()
    Range("A1:C6").AutoFilter 1, ">=3"
    End Sub
    1. 「AutoFilter 1」
      「1」はオートフィルタの範囲「A1:C6」の 1 列目という意味です。
    2. 「”>=3″」
      3 以上という意味です。
    3. 実行結果は以下のようになりました。
  • 1 列目(A 列)で数値が 3 以上のデータのみ表示されている。自動的にオートフィルタモードにもなったようです。
    1 列目(A 列)で数値が 3 以上のデータのみ表示されている。自動的にオートフィルタモードにもなったようです。
  • ここで FilterMode プロパティの値を取得してみます。
    Sub 非表示の行があるかどうかを取得()
    Debug.Print Worksheets(1).FilterMode
    End Sub
    1. FilterMode
      非表示の行がある場合「True」を返すようです。上記で 1 列目にフィルタを掛けたので「True」が返ってくる予定です。
    2. 実行結果です。
  • True
    True
  • 一列目に掛けたフィルタを解除してみます。
    Sub 一列目すべて表示()
    Range("A1:C6").AutoFilter 1
    End Sub
    1. 実行結果です。
  • 1 列目のすべてのデータが表示されている。
    1 列目のすべてのデータが表示されている。
  • ここでもう一度 FilterMode プロパティの値を取得してみます。
    Sub すべてのデータが表示されている状態でFilterModeを取得()
    Debug.Print Worksheets(1).FilterMode
    End Sub
    1. 実行結果です。
  • False
    False
  • AND で複数の条件に一致するデータのみ表示してみます。
    Sub 一列目_数値3以上で4以下()
    Range("A1:C6").AutoFilter 1, ">=3", xlAnd, "<=4"
    End Sub
    1. xlAnd
      OR の場合は定数「xlOr」を指定するようです。
    2. 実行結果です。
  • 1 列目 3 以上 4 以下
    1 列目 3 以上 4 以下
  • マウス、キーボードで操作する場合、以下のような画面で同じ事をできると思います。
  • (オプション ... )を選択。
    (オプション … )を選択。
    オートフィルタオプションの画面で複数の条件を設定。
    オートフィルタオプションの画面で複数の条件を設定。
  • 1 から 3 列目に同時にフィルタを掛けてみます。
    Sub 一列目2以上_二列目C以外_三列目Bで始まる文字()
    Range("A1:C6").AutoFilter 1, ">=2"
    Range("A1:C6").AutoFilter 2, "<>C"
    Range("A1:C6").AutoFilter 3, "b*"
    End Sub
    1. 「AutoFilter 2」「AutoFilter 3」
      オートフィルタを掛けている範囲「A1:C6」の 2 列目、3 列目という意味です。
    2. 「b*」
      文字「b」と「*」アスタリスクを記述しています。「*」はその部分に複数の文字があることを表現しています。
    3. 実行結果です。
  • 各列にフィルタが掛かっています。
    各列にフィルタが掛かっています。
  • 1 から 3 列目のデータを順番に表示してみます。
    Sub 一二三列目全て表示()
    Range("A1:C6").AutoFilter 1
    Range("A1:C6").AutoFilter 2
    Range("A1:C6").AutoFilter 3
    End Sub
    1. 実行結果です。
  • すべてのデータが表示されています。
    すべてのデータが表示されています。
  • 2 列目の空白セルのみ表示してみます。元データは 3,5 行目が空白セルになっています。
    Sub 二列目空白()
    Range("A1:C6").AutoFilter 2, "="
    End Sub
    1. 実行結果です。
  • 3,5 行目の空白セルのみ表示されている。
    3,5 行目の空白セルのみ表示されている。
  • 2 列目の空白セル以外を表示してみます。2,4,6 行目が表示される予定です。
    Sub 二列目空白以外のフィルタ()
    Range("A1:C6").AutoFilter 2, "<>"
    End Sub
    1. 実行結果です。
  • 2,4,6 行目が表示されている。
    2,4,6 行目が表示されている。

    AutoFilter オブジェクト

    上記では「Raneg(“A1:C6”).AutoFilter」のように Range オブジェクトの AutoFilter “メソッド” を使用しましたが、Worksheet オブジェクトの AutoFilter “プロパティ” で「AutoFilter オブジェクト」というものを取得できるようです。

    1. オートフィルタモードになっている状態でテストしてみます。
    オートフィルタモードになっている。
    オートフィルタモードになっている。
  • 下記マクロを実行してみます。
    Sub AutoFilterオブジェクト取得()
      Dim a
      Set a = Worksheets(1).AutoFilter
      Debug.Print TypeName(a)
    Debug.Print VarType(a) '9 は vbObject
    End Sub
    1. Worksheets(1).AutoFilter
      Worksheets オブジェクトの AutoFilter プロパティで AutoFilter オブジェクトを取得しています。
    2. 実行結果は以下のようになりました。
  • AutoFilter
9
    AutoFilter
    9
  • オートフィルタモードになっていない場合は Nothing を返すようです。
  • Nothing
9
    Nothing
    9
  • オートフィルタのセル範囲のアドレスを取得してみます。
    Sub オートフィルタのデータ範囲取得()
    Dim a As AutoFilter
    Set a = Worksheets(1).AutoFilter
    Debug.Print a.Range.Address
    End Sub
    1. Dim a As AutoFilter
      「a」「.(ピリオド)」と続けて入力すると、入力候補が出てきて便利なので、AutoFilter として宣言しています。
    2. 実行結果は以下のようになりました。
  • $A$1:$C$6。オートフィルタの範囲と一致しています。
    $A$1:$C$6。オートフィルタの範囲と一致しています。
  • フィルタの数を取得してみます。
    Sub フィルタの数を取得()
    Dim a As AutoFilter
    Set a = Worksheets(1).AutoFilter
    Debug.Print a.Filters.Count
    End Sub
    1. 実行結果は以下のようになりました。
  • オートフィルタの範囲に 3 列あるので 3 が返ってきたようです。
    オートフィルタの範囲に 3 列あるので 3 が返ってきたようです。
  • 上記で実行したマクロですが、下記マクロを実行してみます。
    Sub 一列目_数値3以上で4以下_二回目()
    Range("A1:C6").AutoFilter 1, ">=3", xlAnd, "<=4"
    End Sub
    1. 実行結果は以下のようになりました。
  • 1 列目にフィルタが掛かっている。
    1 列目にフィルタが掛かっている。
  • 各列にフィルタが掛かっているかどうかを取得してみます。
    Sub 各列のフィルタの状態()
    Dim a As AutoFilter
    Set a = Worksheets(1).AutoFilter
    Debug.Print a.Filters.Item(1).On
    Debug.Print a.Filters.Item(2).On
    Debug.Print a.Filters.Item(3).On
    End Sub
    1. 「.Item(1)」
      1 列目は (1) になります。2,3 列目は (2),(3) になります。
    2. 「.On」
      フィルタが掛かっている状態だと「true」を返すようです。下向き矢印が青くなっていると「true」を返すのだと思います。
    3. 実行結果は以下のようになりました。
  • 2,3 列目はフィルタが掛かっていないようです。
    2,3 列目はフィルタが掛かっていないようです。
  • 1 列目のフィルタの条件を取得してみます。
    Sub 一列目のフィルタの条件を取得()
    Dim a As AutoFilter
    Set a = Worksheets(1).AutoFilter
    Debug.Print a.Filters.Item(1).Criteria1
    Debug.Print a.Filters.Item(1).Criteria2
    Debug.Print a.Filters.Item(1).Operator
    End Sub
    1. 「.Criteria1」「.Criteria2」
      フィルタの 1 つ目の条件と 2 つ目の条件です。
  • フィルタの条件
    フィルタの条件
  • 「.Operator」
    AND,OR などの条件が定数で返ってくるようです。xlAnd = 1 , xlOr = 2 など。
  • 実行結果は以下のようになりました。
  • >=3
<=4
 1
    >=3
    <=4
    1
  • 上記マクロの「Item(1)」の「1」を「2」「3」に変更すると下記のエラーが発生しました。2,3 列目にはフィルタが掛かっていないのでエラーになったようです。
    フィルタ条件を「Criteria1」のみ設定して「Criteria2」を取得しようとしても同じエラーが発生しました。
  • 実行時エラー '1004' アプリケーション定義またはオブジェクト定義エラーです。
    実行時エラー ‘1004’ アプリケーション定義またはオブジェクト定義エラーです。
    エラー発生行。
    エラー発生行

    結果を操作する

    オートフィルタを掛けた結果、表示されるデータがあると思いますが、そのデータを操作してみます。

    表示されているデータの取得を行ってみます。

    1. 下記の状態でテストしてみます。
    オートフィルタは掛かっていない。
    オートフィルタは掛かっていない。
  • オートフィルタを掛けてみます。
    Sub 二列目が空白以外でフィルタを掛ける()
    Range("A1:C6").AutoFilter 2, "<>"
    End Sub
    1. 実行結果は以下のようになりました。
  • 2 列目の空白以外のデータが表示されている。
    2 列目の空白以外のデータが表示されている。
  • 表示されているセルをループ処理してみます。
    Sub オートフィルタの結果をループする()
    Dim a As Range
    For Each a In Range("A2:C6").SpecialCells(xlCellTypeVisible)
    Debug.Print a
    Next
    End Sub
    1. 実行結果は以下のようになりました。
  • 表示中のデータのみになっている。
    表示中のデータのみになっている。
  • Range(“A2:C6”)
    見出し以外の範囲をループ処理する予定です。
  • SpecialCells(xlCellTypeVisible)
    Range(“A2:C6”) の中の可視セル(Visible)のみを取得しています。
  • Range(“A2:C6”).SpecialCells(xlCellTypeVisible) が返す範囲を取得してみます。
    Sub xlCellTypeVisibleが返す範囲()
    Debug.Print Range("A2:C6").SpecialCells(xlCellTypeVisible).Address
    End Sub
    1. 実行結果は以下のようになりました。
  • 3 つのエリアが取得出来ました。
    3 つのエリアが取得出来ました。
  • cells.SpecialCells(xlCellTypeVisible) が返す範囲を取得してみます。
    Sub cells_xlCellTypeVisibleが返す範囲()
    Debug.Print Cells.SpecialCells(xlCellTypeVisible).Address
    End Sub
    1. 実行結果は以下のようになりました。
  • 3 つのエリアが出力されました。
    3 つのエリアが出力されました。

    次は、行単位の操作を試してみます。

    1. 下記マクロを実行してみます。
      Sub オートフィルタの結果を行単位で操作()
      Debug.Print Range("A2:C6").SpecialCells(xlCellTypeVisible).EntireRow.Address
      End Sub
      1. 実行結果は以下のようになりました。
    行単位のアドレスが出力されている。
    行単位のアドレスが出力されている。
  • 「.(ドット)」EntireRow
    「.」の前までで指定したセルを含む複数行を取得できます。
  • 行を削除してみます。
    Sub オートフィルタの結果を行単位で削除()
    Range("A2:C6").SpecialCells(xlCellTypeVisible).EntireRow.Delete
    End Sub
    1. 実行結果は以下のようになりました。
  • データが削除されている。
    データが削除されている。
  • オートフィルタを解除してみます。
    Sub オートフィルタを解除()
    Sheet1.AutoFilterMode = False
    End Sub
    1. 実行結果は以下のようになりました。
  • データが 3 行分削除されて 2 行のデータが残っている。
    データが 3 行分削除されて 2 行のデータが残っている。
  • Sheet1
    「シート1」のオブジェクト名を使用しています。普通の Worksheets(1) でも良いと思います。
    各シートのオブジェクト名は VBE で見る事が出来ます。
  • (1)
Excel の「シート1」と VBE のプロジェクトエクスプローラーの「(シート1)」が一致している。
(2)
VBE のプロジェクトエクスプローラーの「Sheet1」とプロパティウィンドウのオブジェクト名の「Sheet1」が一致している。
    (1)
    Excel の「シート1」と VBE のプロジェクトエクスプローラーの「(シート1)」が一致している。
    (2)
    VBE のプロジェクトエクスプローラーの「Sheet1」とプロパティウィンドウのオブジェクト名の「Sheet1」が一致している。
  • ワークシートのオブジェクト名は下記のようなマクロで取得することも出来るようです。
    Sub ワークシート1のコード名取得()
    Debug.Print Worksheets(1).CodeName
    End Sub
    1. 実行結果は以下のようになりました。
  • Excel のヘルプを見るとコード名という名称になっていました。
    Excel のヘルプを見るとコード名という名称になっていました。

    マクロストック

    Sub 一列目の下向き矢印を非表示にする()
      Range("A1:C6").AutoFilter 1, ">=3", xlAnd, "<=4", False
    End Sub

    第 5 引数「VisibleDropDown」を「False」に設定しています。

    下向き矢印が表示されていない。
    下向き矢印が表示されていない。

    テスト環境

    • Windows 10(64 ビット)
    • Microsoft Office Excel 2003

    以上、閲覧ありがとうございました。