「10以上」や「15以上20以下」など、オートフィルターによる数値の条件・区間での絞り込みを、コピペして使えるユーティリティ関数にしたものを紹介します。
お忙しい方は、ソースコードをコピーして、使い方のように呼び出すだけでOKです。
コードをしっかり読みたい方は、解説をどうぞ。
1つの条件(10以上 や 0以外 など)で抽出する
まずは「10以上」「0以外」など、1つの条件で絞り込む方法です。
実は結構簡単で、↓のようにAutoFilterの引数Criteria1に「>=10」や「<>0」などの条件式を渡すだけでよいです。
Range("A1:C10").AutoFilter field:=1, Criteria1:=">=10"
コードの書き方は、完全一致でフィルターするときとまったく変わらないので、
ユーティリティ関数も「オートフィルターで抽出する」で紹介したものの使いまわしでOK。
Sub みかんを2個以上買った人に絞る() Call フィルターを設置する(Range("B2:E2")) Call フィルターで抽出する("みかん", くだもの売上表の列.品物, ActiveSheet) Call フィルターで抽出する(">=2", くだもの売上表の列.個数, ActiveSheet) End Sub
このように、同じ関数を引数だけ変えるだけで、完全一致・条件抽出のどちらにも使えます。
この関数は「オートフィルターで抽出する」で解説していますが、コピペ用にコードだけ再掲します。
ソースコード
' フィルター設置 Sub フィルターを設置する(設置エリア As Range) ' 既に設置されているフィルターを解除してから設置 設置エリア.Parent.AutoFilterMode = False 設置エリア.AutoFilter End Sub ' フィルター抽出 Sub フィルターで抽出する(ByVal 抽出キー As Variant, 抽出列 As Long, 対象シート As Worksheet) With 対象シート.AutoFilter.Range ' 数値が書式の影響を受けるのを回避 If IsNumeric(抽出キー) Then .AutoFilter field:=抽出列 - .Column + 1, Criteria1:=">=" & 抽出キー _ , Operator:=xlAnd, Criteria2:="<=" & 抽出キー ' メインの処理 Else .AutoFilter field:=抽出列 - .Column + 1, Criteria1:=抽出キー End If End With End Sub
- まずは設置する関数を呼び、そのあとで抽出する関数を呼んでいく。
- すでにフィルターが設置してある場合は、設置の関数は使わなくてよい。
- 抽出する列の指定に、列番号をそのまま渡せる。
※ 元の仕様である「フィルター範囲で何列目」から変更している
※ くだもの売上表の列:列番号を定数で定義したものです(B列なら2などの数値です)
2つの条件で挟まれた数値の区間(10以上20以下 など)で抽出する
次に、2つの条件に囲まれた範囲を絞り込む方法です。
こちらもそこまで難しくはなく、Criteria2に↑と同じように条件式を渡し、
Range("A1:C10").AutoFilter field:=1 _ , Criteria1:=">=10", Operator:=xlAnd, Criteria2:="<=20"
↑のように「Operator:=xlAnd」でつなげばOKです。
さてユーティリティ関数を作りましょう。
Call ふたつの条件でフィルターを抽出する(">=10","<=20", CNoくだもの売上表.個数, ActiveSheet)
↑こんなものでも十分かもしれませんが、せっかくなのでもうちょっと便利にします。
ソースコード
' 数値区間でフィルター Sub フィルターで数値の区間を抽出する(ByVal 下限値 As Double, ByVal 上限値 As Double _ , 抽出列 As Long, 指定シート As Worksheet _ , Optional is下限値を抽出に含む As Boolean = True _ , Optional is上限値を抽出に含む As Boolean = True) With 指定シート.AutoFilter.Range .AutoFilter field:=抽出列 - .Column + 1 _ , Criteria1:=">" & IIf(is下限値を抽出に含む, "=", "") & 下限値 _ , Operator:=xlAnd _ , Criteria2:="<" & IIf(is上限値を抽出に含む, "=", "") & 上限値 End With End Sub
使い方
Call フィルターを設置する(Range("B2:E2")) ' 10 <= x <= 20 で絞り込む Call フィルターで数値の区間を抽出する(10, 20, CNoくだもの売上表.個数, ActiveSheet) ' 10 < x < 20 で絞り込む Call フィルターで数値の区間を抽出する(10, 20, CNoくだもの売上表.個数, ActiveSheet, False, False)
- 引数には、「>」などは付けずに数値をそのまま渡せる。
- 「=」をつけるかどうかは「is上/下限値を含む」にTrue/Falseで指定する。
- 省略時はTrueなので、指定しない場合は「=」がついた条件になる。
※ オートフィルターで抽出する関数と同じく、列の指定に列番号をそのまま使います。
元の仕様である「フィルター範囲で何列目?」から変更している点に注意してください。
※ くだもの売上表の列:列番号を定数で定義したものです(B列なら2などの数値です)
コードの解説
実際に関数を使うときは、値をそのまま書くのでなく、変数やセルの値を関数へ渡す場合が多いです。
そのときに、「">=" & Cells(R1, C1)」のように、いちいち文字列を結合させて引数に渡すのは地味に面倒なので、それも関数にやってもらいましょう。
こうすると、"<"の方向を考える必要もなくなりますし、間違って逆にしてしまうバグもなくなりますね。
ちなみに、Optional ~~ = True という部分は、「省略可能、省略時はTrue」という意味です。
使い方のように、数字をただ渡すと「>=」「<=」で処理され、
Falseを渡すと「>」「<」で処理されます。
IIf関数について
上限値を含むのTrue/Falseで、「<」と一緒に「=」もつけるかどうかは、Ifによる分岐でなく、IIf関数で書きました。
IIf(is下限値を抽出に含む, "=", "")
初めて見る人もいるかもしれませんが、覚えるのはすごく簡単です。
早い話、これは「シート関数のIF」です。
IIf(条件式, Trueの時, Falseの時)
すごくなじみのある記述ですね。
今回の場合は、下限値を含むなら「=」、そうでないなら「」。そのまんまです。
ひとつの引数だけ違うメソッドの実行などは、Ifによる分岐を使ってしまうと、ほとんど同じコードをもう一回書く羽目になります。
IIfを使えば1行のまま分岐でき、コードがかなり短くなりますので積極的に使っていきましょう。
他のプログラミング言語だと、「三項演算子と呼び、云々~」みたいな説明が必要で知名度が低く、読みづらいから使うな、みたいな批判もあるようですが、
VBAユーザーには「シート関数と同じ書き方のIf」で通じるし、見慣れていて読みやすいのでいいですね。