2011-09-12 追記
よくよく考えると、わざわざカウンタ(グローバル変数)を使わないでも実装出来るかも。修正版をアップします。
「インスタンス生成時にApplication.〜の状態がTrueであればFalseにし、変更処理を行った時だけ破棄時にTrueに戻す責任がある」という実装でも、まぁだいたい対応できるんじゃないのかな、というバージョンです。
「多重で呼んでもバグらない」「どこかの処理でプロパティとして直接書き換えたとき、他の関数を呼んだらいつの間にか書きかえられてそのまんまかえってくる」さえ防げればだいたい実用レベルなのかなと思います^^;
◇ 標準モジュール modDisabler
Option Explicit Public Sub DisablerModule_Restore() ' デバッグ中の実行中断で、各機能が無効になりっぱなしになってしまった場合に呼び出します。 Application.ScreenUpdating = True Application.EnableEvents = True End Sub Public Sub DisablerModule_ScrUpdatingFlush() ' Application.ScreenUpdatingを一時的に有効にします。 Dim reg As Boolean: reg = Application.ScreenUpdating Application.ScreenUpdating = True ' 有効化 If reg = False Then Application.ScreenUpdating = False ' 元に戻す End Sub
以前のmodDisablerに比べていくつかの関数がなくなっただけです。残っている関数はそのままなので、以前の注釈を参照してください。
◇ クラス IScrUpdatingDisabler
Option Explicit Private Const STOPFLG As Boolean = False ' デバッグ用機能停止フラグ Private reg As Boolean Public Sub Class_Initialize() reg = False If STOPFLG = False Then If Application.ScreenUpdating = True Then Application.ScreenUpdating = False reg = True End If End If End Sub Public Sub Class_Terminate() If STOPFLG = False Then If (Application.ScreenUpdating = False) And (reg = True) Then Application.ScreenUpdating = True End If End Sub
◇ クラス IEventsDisabler
Option Explicit Private Const STOPFLG As Boolean = False ' デバッグ用機能停止フラグ Private reg As Boolean Public Sub Class_Initialize() reg = False If STOPFLG = False Then If Application.EnableEvents = True Then Application.EnableEvents = False reg = True End If End If End Sub Public Sub Class_Terminate() If STOPFLG = False Then If (Application.EnableEvents = False) And (reg = True) Then Application.EnableEvents = True End If End Sub
クラスの方はいくらか変わっていますが、使い方は前のバージョンと変わりありません。
できればmodDisablerを無くしたいけど、手持ちのEXCEL2000VB6で中断やAssertをするとどうしてもClass_Terminateが呼び出されないようなので、Restoreルーチンをなくすことが出来ませんでした。C++だって例外機能とコンパイラの対応は微妙な部分なので、ここは攻めすぎないほうが無難かも…