和風スパゲティのレシピ

日本語でコーディングするExcelVBA

フィルターで抽出中か判定する - FilterMode/On

オートフィルターの抽出が行われているかを判定する方法を解説します。

  • 「いずれかの列で抽出中か」を判定するにはFilterModeプロパティ
  • 「特定の列で抽出中か」を判定するにはFilters.Onプロパティ

をそれぞれ調べます。

フィルターが設置されているか判定 - AutoFilterMode

まずは抽出の前に、そもそもフィルターが設置されているかを調べるには、
WorksheetオブジェクトのAutoFilterModeプロパティを調べます。

If Worksheets("○○").AutoFilterMode = True Then
    ' フィルターが設置されている場合の処理
End If

 
記述自体は簡単なプロパティですが、ひとつ注意点として、
「テーブル」のフィルターは検知されない仕様になっています。

テーブルが設置されているかどうかは、
ListObjectの数が1以上であるかどうかで判定してください。

If Worksheets("○○").ListObjects.Count >= 1 Then
    ' テーブルが設置されている場合の処理
End If

 

いずれかの列でフィルターが抽出中か判定 - FilterMode

少なくともどこかひとつの列で抽出が行われているか調べる場合は、
FilterModeプロパティを調べます。

If Worksheets("○○").FilterMode = True Then
    ' いずれかの列でフィルターが抽出されている場合の処理
End If

先ほどのAutoFilterModeプロパティと名前が似ていますので、
混同しないように気を付けて記述してください。


なお、このFilterModeプロパティは、
Worksheet、AutoFilterのどちらのオブジェクトからも呼ぶことが可能です。

If Worksheets("○○").FilterMode = True Then
    ' ↕ どちらも同じ処理
If Worksheets("○○").AutoFilter.FilterMode = True Then

 
この二つのコードはほとんど違いがありませんが、
唯一の違いは「フィルター自体が設置されていない場合」の挙動です。


まずWorksheetオブジェクトのFilterModeプロパティですが、
こちらは「フィルターが設置されていない場合もFalse」を返します。


続いてAutoFilterオブジェクトのFilterModeプロパティですが、
こちらは「フィルターが設置されていない場合はエラー」となります。

より正確には「Worksheet.AutoFilter.FilterMode」というコードにおいて、
Worksheet.AutoFilterがそもそもないためこの時点でエラーとなります。

FilterModeプロパティにアクセスすることができないということですね。


基本はエラーにならないWorksheetオブジェクトの方を使っておけばいいと思います。

その上で、そもそも設置されているかどうかの判定が必要であれば、
前述のAutoFilterModeプロパティを使用して下さい。

特定の列でフィルターが抽出中か判定 - Filters(i).On

特定の列で抽出が実行されているか調べるには、
AutoFilter.FilterオブジェクトのOnプロパティを調べます。

AutoFilterのFilterオブジェクトはFilters(i)の形で取得できるため、
以下のコードで指定列で抽出が行われているかを判定できます。

' E列で抽出が行われているか判定されているか判定
Dim フィルター内列番号 As Long
フィルター内列番号 = 5 - Worksheets("○○").AutoFilter.Range.Column + 1
If Worksheets("○○").AutoFilter.Filters(フィルター内列番号).On Then

 

ここで注意しなければならないのが、Filters(i)のiは列番号とは異なる点です。


このiにはフィルター設置中の第何列目かを与える必要があるため、
フィルターがB列始まりの場合は列番号から1を引くなど、
シート列番号とフィルター内列番号の調整を行う必要があります。


この調整は「フィルター第1列目の列番号」を引いてから1を足せばいいため、

フィルター内列番号 = 5 - Worksheets("○○").AutoFilter.Range.Column + 1

というコードでこの計算を行っています。


なお、この記述を変数なしでやろうとすると、

If Worksheets("○○").AutoFilter.Filters(5 - Worksheets("○○").AutoFilter.Range.Column + 1).On Then

このような長大なコードになって読みづらくなります。

こういった非常に読みづらいコードは変数を使って読みやすくできますので、
この使い方も覚えておきましょう。


ちなみに小ネタですが、FilterMode、OnともにTrue/Falseを返すため、
以下のどちらの記述で書くことも可能です。

' 「= True」はシステム上は不要
If Worksheets("○○").FilterMode Then
If Worksheets("○○").AutoFilter.Filters(フィルター内列番号).On Then

' 可読性のために「= True」を書いても良い
If Worksheets("○○").FilterMode = True Then
If Worksheets("○○").AutoFilter.Filters(フィルター内列番号).On = True Then

 
個人的には、True/Falseを返しそうなプロパティは=Trueを省略し、
返さなそうなプロパティは=Trueを省略していないことが多いです。

今回はFilterModeは=Trueで判定し、Onは省略しました。


このあたりはどっちでもいいと思いますのでお好きな方で記述してください。