和風スパゲティのレシピ

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

オートフィルターをクリアして全て表示する

オートフィルターのクリア(すべての抽出をリセットして、すべての行を表示させる)を、コピペして使えるユーティリティ関数にしたものを紹介します。
オートフィルターのクリア

お忙しい方は、ソースコードをコピーして、使い方のように呼び出すだけでOKです。
コードをしっかり読みたい方は、解説をどうぞ。

ソースコード

' フィルターのクリア
Sub フィルターをクリアする(指定シート As Worksheet)
    If Isフィルターで抽出されている(指定シート) Then
        指定シート.ShowAllData
    End If    
End Sub

' 現在抽出されているか判定
Function Isフィルターで抽出されている(判定シート As Worksheet) As Boolean
    If 判定シート.AutoFilterMode = True Then ' フィルタが設置されていて
        If 判定シート.AutoFilter.FilterMode = True Then ' いずれかの抽出あり
            Isフィルターで抽出されている = True
        End If
    End If
End Function

使い方

Call フィルターをクリアする(ActiveSheet)
Call フィルターで抽出する("みかん", くだもの売上表の列.品物, ActiveSheet)
Call フィルターで抽出する(">=2", くだもの売上表の列.個数, ActiveSheet)
  • すでにかかっている絞り込みを解除してから処理に入りたいときや、処理の後にフィルターを元に戻すときに使う。
  • すでに全表示(どの列も抽出されていない)でも実行できる。

※ 一緒に使われている関数:オートフィルターで抽出する
※ くだもの売上表の列:列番号を定数で定義したものです(B列なら2などの数値です)

コードの解説

オートフィルターの各プロパティのエラーを回避する

実はオートフィルターのクリア自体は、

フィルターをクリアしたいワークシート.ShowAllData

の一発で終わります。

しかし、これを実行するには、どこかの列で抽出がかかっていないといけません。
どの列でも抽出をかけていない状態で実行すると、「メソッドが失敗しました」エラーで止まってしまいます。
割と好き勝手するAutoFilterさんですが、変なところは律儀ですね。

ということで、ワークシート.AutoFilter.FilterMode がTrueかどうかで、
どこかの列で抽出がかかっているかを調べてから実行する必要があります。


がしかし、こっちはこっちでオートフィルターが既に設置されている必要があり、
未設置だと「オブジェクトまたはWith~」エラーで止まります。
気の利かないやつめ。

ということで、実際は↓のコードを書かないといけません。

If 処理シート.AutoFilterMode = True Then
    If 処理シート.AutoFilter.FilterMode = True Then
        処理シート.ShowAllData
    End If
End If


さて5行も使ってこれをメインコードに書いたとして、後で見返したときに、これがフィルターのクリアだとすぐにわかるでしょうか?

また、このコードを実際に書こうと思ったとき、

.AutoFilterMode
.AutoFilter.FilterMode

この間違い探しのような記述を正確に記憶しておけますか?

そういう労力を払うくらいならユーティリティ関数を作っちゃいましょう。

Call フィルターをクリアする(処理シート)

わかりやすい!

マクロの目的と関係のない大量のIfでメインコードが汚れないように、
関数に隠してしまうのは、とても大事なテクニックです。

抽出されているかを判定する関数も作る

単にオートフィルターをクリアするだけなら↑の5行を関数にすればいいのですが、
せっかくなので「フィルターで抽出されているか判定する」部分をさらに関数にしています。

おかげでクリアする関数はものすごい単純になってますね。

判定関数を別に作っておけば、フィルターをクリアする以外にも、

If Isフィルターで抽出されている(処理シート) Then
    MsgBox ("別の抽出作業が残っています。クリアしてから実行してください。")
    Exit Sub
End If

のような別の使い方もできるかもしれません。

短い関数は悪いなんてことはまったくないので、躊躇せずにどんどん作っていきましょう。

おまけ:奥義 On Error Resume Next を使う

On Error Resume Next は、発生するエラーをすべて無視するステートメントです。
想定されるエラーを熟知せず使うのは、大事なエラーも無視しそうで、メインコードでまるごと使うのは怖いです。

間違っても「どんなエラーが出るかわからんがやっちゃえ」精神で使ってはいけません。

しかし、短い関数内で、発生するエラーがわかった上で使うにはとても便利です。

表題のユーティリティ関数2本は、On Error Resume Nextを利用すると↓のように書き換えることができます。

Sub フィルターをクリアする(指定シート As Worksheet)
    On Error Resume Next
    指定シート.ShowAllData
End Sub

Function Isフィルターで抽出されている(判定シート As Worksheet) As Boolean
    On Error Resume Next
    Isフィルターで抽出されている = 判定シート.AutoFilter.FilterMode
End Function

短い!
どちらも、On Error Resume Next を除けばたった1行になります。


どちらの書き方を採用するかは好みでいいと思いますが、個人的には、

  • ユーティリティ関数は、呼び出して使う以外に、中身のコードをコピペするための「サンプルコードの辞書」としても使いたい。
  • 気づいていないだけで、無視してはいけないエラーがあるかもしれない。

という想いがあるので、メソッドやプロパティに関するコードは、しっかり書き切るようにしています。

どちらを採用するにしても、この「短い関数をゴリ押しするためのOn Error Resume Next」はとても便利なので、テクニックとして覚えておいて損はないでしょう。