オートフィルタの設定と解除方法

オートフィルタは使い勝手がよく、とても便利な機能です。VBAでもオートフィルタの設定が可能で、シートに表形式のデータを作成した場合などに、自動でオートフィルタの設定をすることができます。

ただし、VBAでオートフィルタのコードを書くときには注意が必要です。

いくつか問題があるのですが、それらの問題を考慮した上で、オートフィルタの設定を行う関数と、解除を行う関数をページの最後で紹介しています。


AutoFilterメソッドは設定と解除の両方を行う

オートフィルタの設定と解除は、どちらもRangeオブジェクトのAutoFilterメソッドで行います。

コードとしては以下の2行目のように設定も解除も全く同じ書き方になります。

当然、見ての通り、これでは設定するのか解除するのか分かりません。

AutoFilterプロパティはどういう挙動になるかというと、オートフィルタが設定されていれば解除し、解除されていれば設定する、という事前の状態に依存する動作になります。



AutoFilterメソッドとAutoFilterオブジェクト

上のコードで書いている「AutoFilter」メソッドの他に、同じAutoFilterという名前のオブジェクトがあります。

AutoFilterメソッドとAutoFilterオブジェクトはそれぞれ用途が異なります。

後でも書いていますが、AutoFilterメソッドはRangeオブジェクトのメソッドで、AutoFilterオブジェクトはワークシートのオブジェクトです。

個人的にはこういう混乱をまねくような、設定と解除が同じメソッド名で実装されていたり、プロパティとメソッドの名前が同じなのはVBAの言語としての実装ミスと思うのですが、そうは言っても仕方ありませんし、対応方法はありますので以下を参照してください。


オートフィルタが設定されているかの確認方法

オートフィルタの設定と解除を行う前に、今のシートがどういう状況かを確認する必要があります。

オートフィルタが設定され、絞込みができる状況にあるかどうかを調べるにはシートのAutoFilterModeプロパティで判定します。

Trueの場合は設定済み、Falseの場合は未設定です。



オートフィルタで絞込みが行われているかの確認方法

オートフィルタで何かの値で絞込みが行われているかどうかの確認はFilterModeプロパティで判定します。

FilterModeプロパティはシートのAutoFilterオブジェクトのプロパティになります。

なお、Excel操作で絞り込みを解除する場合は、データタブの「並べ替えとフィルター」のクリアボタンを押します。




AutoFilterオブジェクトとAutoFilterプロパティの違い

オートフィルタ周りのコードを書く際に「AutoFilter」と書く個所が出てきますが、文字は同じでも使い方には2種類あります。

1つはワークシートのオブジェクト(というかクラス)としてのAutoFilterで、もう1つはRangeオブジェクトのメソッドとしてのAutoFilterです。


ワークシートのAutoFilterクラス

ワークシートのAutoFilterクラス(オブジェクト)は先に紹介しているFilterModeプロパティなどを持つクラスになります。

クラスのため、オブジェクト変数にコピーすることも可能です。

こんな感じです。

2行目で変数定義、5行目でクラス変数をコピー、8行目でクラス変数を使ってプロパティを利用しています。



RangeオブジェクトのAutoFilterメソッド

RangeオブジェクトのAutoFilterメソッドは、オートフィルターの設定と解除を行います。

全く同じコードで、設定と解除それぞれの処理を行いますので、確実に設定もしくは解除を行いたい場合はAutoFilterメソッドを使う前にオートフィルターの設定状況を確認する必要があります。

例えばこんなソースがあった場合、事前にオートフィルタが設定されているかどうかで結果が変わります。

設定されていれば、解除し、解除されていれば設定します。

しかし実際にコーディングする場合はそういうのは困るので、こんな感じで事前チェックを行った方が無難です。



オートフィルタの設定と解除を明確に切り分ける方法

先に書いたとおり、オートフィルタの設定と解除は同じ書き方で書けるのですが、そういうことをやると混乱の元ですのでやらない方がいいです。

ではどうするかというと、設定用の関数と解除用の関数をそれぞれ用意し、必要なときに呼び出すようにします。

オートフィルタ設定関数

オートフィルタ解除関数

上記の2つ関数ではAutoFilterメソッドで設定と解除を行っていますが、その関数自体の用途でどちらを行うのかを明確にしています。

それぞれの関数の先頭で、オートフィルタの状態を判定した上で処理を行うようにしています。

こうすることでより用途が明確になります。