オブジェクトのイベントを“自作クラス”で受け取る方法
クラスモジュールの強力な機能のひとつが WithEvents を使ってイベントを受け取れることです。
通常、イベントは
- Worksheet_Change
- Workbook_Open など、決められた場所でしか扱えません。
しかし WithEvents を使うと、 自作クラスの中で Worksheet や Application のイベントを受け取れるようになり、 コードの構造化・再利用性が大幅に向上します。
1. WithEvents とは?
WithEvents は、 「イベントを持つオブジェクトを、クラス内でイベント付きで扱う」 ための宣言です。
vb
Private WithEvents ws As Worksheet
このように宣言すると、 クラス内で ws_Change や ws_SelectionChange などのイベントを扱えるようになります。
2. WithEvents を使うための基本構造
イベントを扱うには、次の3ステップが必要です。
① クラスモジュールで WithEvents を宣言
② イベントを実装
③ 標準モジュールでインスタンスを生成
順番に見ていきましょう。
3. 実例:Worksheet_Change をクラスで扱う
▼ クラスモジュール(clsSheetWatcher)
Option Explicit
Private WithEvents ws As Worksheet
'監視対象のシートをセットする
Public Sub SetTarget(ByVal target As Worksheet)
Set ws = target
End Sub
'イベント:セルが変更されたとき
Private Sub ws_Change(ByVal Target As Range)
MsgBox "変更されました:" & Target.Address
End Sub
ポイント
- WithEvents で宣言した
wsに対してイベントが発生する - ws にセットしたシートだけが監視対象になる
- イベント名は自動補完で選べる(ws_Change など)
4. 標準モジュールでインスタンスを生成
Dim watcher As clsSheetWatcher
Sub StartWatch()
Set watcher = New clsSheetWatcher
watcher.SetTarget Worksheets("Sheet1")
End Sub
これで、Sheet1 のセルが変更されると クラス内の ws_Change が発火します。
5. WithEvents の“よくある落とし穴”
❌ ローカル変数でインスタンスを作るとイベントが動かない
Sub BadExample()
Dim w As New clsSheetWatcher
w.SetTarget Sheet1
End Sub
プロシージャ終了と同時に w が破棄されるため、 イベントが発火しなくなる。
✔ 正しい方法:モジュールレベルで保持する
Dim watcher As clsSheetWatcher
プロシージャ外で宣言しておくことで、 インスタンスが生き続け、イベントが動作します。
6. Application イベントもクラスで扱える
WithEvents は Worksheet だけでなく、 Application(Excel全体)のイベントも扱えます。
例:Application のイベントを受け取るクラス
Option Explicit
Private WithEvents app As Application
Private Sub Class_Initialize()
Set app = Application
End Sub
Private Sub app_SheetChange(ByVal Sh As Object, ByVal Target As Range)
Debug.Print "どこかのシートが変更されました"
End Sub
標準モジュールでインスタンスを保持すれば、 Excel 全体のイベントをクラスで扱えるようになります。
7. 実務での活用例
▼ 1. 入力チェッククラス
特定シートの変更を監視し、入力ミスを即時チェック。
▼ 2. ログ記録クラス
変更されたセルをログに書き出す。
▼ 3. UI制御クラス
選択セルに応じてボタンの表示・非表示を切り替える。
▼ 4. Applicationイベントで全体監視
複数シートの変更を一括管理。
WithEvents を使うと、 イベント処理をクラスに閉じ込めて構造化できるため、 標準モジュールがスッキリし、保守性が大幅に向上します。
8. まとめ
- WithEvents は「イベント付きオブジェクト」を扱うための仕組み
- クラス内で Worksheet や Application のイベントを受け取れる
- インスタンスはモジュールレベルで保持する必要がある
- イベント処理をクラスに閉じ込めることで構造化・再利用性が向上
クラスモジュールを本格的に使うなら、 WithEvents は避けて通れない重要テクニックです。
コメント