和風スパゲティのレシピ

日本語でコーディングするExcelVBA

イベントマクロを無効化する - EnableEvents

Worksheet_BeforeDoubleClickやWorksheet_Changeなど、
ユーザーの操作を検知して実行するマクロをイベントマクロと呼びます。

このイベントマクロの実行(検知)を停止させるには、
Application.EnableEventsプロパティを使用します。


※ その他Applicationによるマクロ高速化シリーズのまとめ記事はこちらをどうぞ

基本構文

' イベントマクロの停止
Application.EnableEvents = False

' イベントマクロの再開
Application.EnableEvents = True

サンプルコード

Sub サンプルマクロ()

    ' マクロ実行冒頭でイベントマクロを停止
    Application.EnableEvents = False

    ' マクロのメインコード
    Dim R As Long
    For R = 1 To 1000
        Cells(R, 1) = 1
    Next
    ' ※ もしイベントを停止していない場合は
    ' ここでWorksheet_Changeが1000回Callされる

    ' ブックを開く際のWorkbook_Openも無効化して開く
    Workbooks.Open "~~\○○.xlsm"

    ' マクロ終了時にイベントマクロの検知を再開
    Application.EnableEvents = True

End Sub

解説

イベントマクロの実行を一時的に無効にするには、
Application.EnableEventsプロパティを使用します。

代入して設定するタイプのプロパティで、
Falseで無効化でき、Trueで再開することが出来ます。


マクロの終了とともにTrueに戻るわけではありませんので、
終了時にTrueに戻すコードを忘れずに実行して下さい。

これをやらないと、マクロ終了後もイベントが止まったままになってしまいます。


このコードはイミディエイトウィンドウでも実行できます。

もしエラーなどでマクロが中断しイベントが停止したままになったら、

Application.EnableEvents = True

これをイミディエイトウィンドウで実行すればイベントを再開可能です。

主な使い道

Application.EnableEventsの主な使い道は以下の4つです。

Worksheet_ChangeやWorkbook_Openを無効化して処理

これはサンプルで紹介した通りのストレートな使い方です。

  • マクロの冒頭でイベントを無効化し、最後に再開する
  • Openなどのコードの直前で無効化し、直後に再開する

いずれかの方法で使用してください。

マクロの高速化

↑の使い方とちょっとかぶりますが、マクロ全体の高速化を目的として、
マクロの冒頭でScreenUpdatingなどと同時に設定する使い方です。

Sub サンプルマクロ()

    ' Excelの自動更新を停止
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual
    Application.EnableEvents = False
    Application.Cursor = xlWait

    ' マクロのメインコード

    ' Excelの自動更新を再開
    Application.ScreenUpdating = True
    Application.Calculation = xlCalculationAutomatic
    Application.EnableEvents = True
    Application.Cursor = xlDefault

End Sub

これもよくある使い方ですね。

Change系のイベントが設定されたブックにおいては、
大量のイベントがCallされることを防ぐことで高速化できます。


ちなみにこの使い方をするときは、
汎用関数化するのがおすすめです。

Sub サンプルマクロ()

    Call Excelの自動更新を停止する

    ' マクロのメインコード

    Call Excelの自動更新を再開する

End Sub

' マクロ高速化用汎用関数
Sub Excelの自動更新を停止する()
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    Application.Calculation = xlCalculationManual
    Application.Cursor = xlWait
End Sub
Sub Excelの自動更新を再開する()
    Application.ScreenUpdating = True
    Application.EnableEvents = True
    Application.Calculation = xlCalculationAutomatic
    Application.Cursor = xlDefault
End Sub

こんな風にメインコードを前後1行ずつで済ますことが出来ますので、
気に入ったらこの方法で記載してみて下さい。

イベントマクロの再帰呼出を防ぐ

こちらもかなり重要な使い方です。

例えば、値の変更を検知するWorksheet_Chaneイベントは、

Private Sub Worksheet_Change(ByVal Target As Range)

    Cells(1, 1) = 1 ' ← ここでWorksheet_ChangeがCallされる

End Sub

こんな風にChangeがChangeを呼んで無限ループしてしまいます。

これを防ぐために、Change系のイベントではイベントを無効にしておきましょう。

マクロの開発段階でのイベント実行を停止

マクロを開発(コードを記述)している間は、
作りかけのイベントが発生すると鬱陶しいことも多いです。

前述の通りEnableEventsはイミディエイトウィンドウでも設定できますので、

Application.EnableEvents = False

をイミディエイトで実行し、コーディング中のイベントを停止できます。

この使い方も便利ですので覚えておきましょう。


以上がApplication.EnableEventsの主な使い方になります。

いろいろと使い道があるプロパティですので、
しっかり覚えておきましょう。