【VBA】クラスでイベントを扱う(WithEvents)|Worksheet・Applicationイベントの受け取り方

オブジェクトのイベントを“自作クラス”で受け取る方法

クラスモジュールの強力な機能のひとつが WithEvents を使ってイベントを受け取れることです。

通常、イベントは

  • Worksheet_Change
  • Workbook_Open など、決められた場所でしか扱えません。

しかし WithEvents を使うと、 自作クラスの中で Worksheet や Application のイベントを受け取れるようになり、 コードの構造化・再利用性が大幅に向上します。

スポンサーリンク

1. WithEvents とは?

WithEvents は、 「イベントを持つオブジェクトを、クラス内でイベント付きで扱う」 ための宣言です。

vb

Private WithEvents ws As Worksheet

このように宣言すると、 クラス内で ws_Changews_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 は避けて通れない重要テクニックです。

コメント

タイトルとURLをコピーしました