オートフィルターのクリア(すべての抽出をリセットして、すべての行を表示させる)を、コピペして使えるユーティリティ関数にしたものを紹介します。
お忙しい方は、ソースコードをコピーして、使い方のように呼び出すだけで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」はとても便利なので、テクニックとして覚えておいて損はないでしょう。