標準モジュールへ作成したものは、いちいち実行しなければならないので、面倒くさい。
では、もっと自動化できないか、ということで、「
イベントマクロ」というものを利用してみる。
「イベント」とは「セルの入力内容が変更された」「選択セルを変更」などのソフトウェア上の変化。
「セルの入力内容が変更された」というイベントを利用してみる。
シートの見出しを右クリックして表示されるショートカットメニューから、
を選択してVBEを起動。
上記VBE画面で左側、
オブジェクトボックス((General)と表示されている)から、Worksheetを選択、
また、その右側の
プロシージャボックスからChangeを選択するとその過程で次のようなコードが
自動的に作成される。
Private Sub Worksheet_Change(ByVal Target As Range)
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
End Sub
今回はWorksheet_Changeの方へ記録をもとに作成した前記Macro3のコードの中身を移し替えてみる。
Private Sub Worksheet_Change(ByVal Target As Range)
If ActiveSheet.FilterMode Then Cells.AutoFilter
With Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown))
.AutoFilter Field:=1, Criteria1:=Range("A1").Text
End With
End Sub
このままではシート内のセルが変更されるたびにオートフィルタを実行してしまうので、多少わずらわしい。
A1セルが変更された時、オートフィルタが実行されれば良いというのがわかっているので、
そのように書き換えてみる。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) = "A1" Then
If ActiveSheet.FilterMode Then Cells.AutoFilter
With Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown))
.AutoFilter Field:=1, Criteria1:=Range("A1").Text
End With
End If
End Sub
この場合、TargetとRange("A1")は同一なので、次のように書き換えることも出来る。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address(0, 0) = "A1" Then
If ActiveSheet.FilterMode Then Cells.AutoFilter
With Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown))
.AutoFilter Field:=1, Criteria1:=Target.Text
End With
End If
End Sub
これで、「セルA1を変更したら、リストのA列でA1の値をもとにフィルタリングする」マクロが出来た。
少し欲を出して、A列だけでなくて、リストの全てのフィールドにも同様の自動フィルタ機能を
持たせてみる。
直前の例ではTargetとなるセルをA1だけに限定したが、フィルタの条件となるセルを
「一行目で、リストの見出しに対応する(同じ列の)セル」に拡張してみる。
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub
If Target.Row <> 1 Then Exit Sub
If Target.Column > Range("A2").End(xlToRight).Column Then Exit Sub
If ActiveSheet.FilterMode Then Cells.AutoFilter
With Range(Range("A2"), Range("A2").End(xlToRight).End(xlDown))
.AutoFilter Field:=Target.Column, Criteria1:=Target.Text
End With
If WorksheetFunction.CountA(Range("1:1")) = 0 Then
Cells.AutoFilter
End If
End Sub
Target.Countは変更したセルの数(セルの数が複数になると都合が悪い)、
Target.Rowは変更したセルの行位置、Target.Columnは変更した列位置を示す。
また、Field:=1 のままでは「リストの一列目」だけをフィルタの対象とするので、
Field:=Target.Column とすることで、「変更したセルと同じ列」という可変性を持たせる。
最後の3行はフィルタ条件が全てクリアされた時にリストを全表示するためのものである。
なお、条件を指定する場合は比較演算子(<,>,=)、およびワイルドカード(*,?)を使用することが出来る。