VBAとデストラクタ
VBA (Visual Basic for applications)は、多くの現場でインストール済みの開発環境というのが魅力ですが、なにぶん20世紀の言語なだけに使いづらいところも多いです。
そのうちの一つとして、例外処理があります。
try catch どころか finally がないことに苦心します。
そんな VBA ですが、オブジェクト指向が流行り始めた時期に乗ってクラスがあり、そこにデストラクタがあることに救いがあります。
Sub Class_Terminate がそれですね。
また VBA は、参照カウント方式でこれを呼び出す仕様となっています。
つまり、デストラクタを呼び出すタイミングをプログラマが制御できるわけです。
Application のプロパティでの例
ごたくを並べすぎました。
つまり、「この処理をしたら、それに対応する処理を終了するまでにしておく」ということをこれで実装できるわけです。
具体的には、Application のプロパティの一時変更などに向いています。
まずは、Application.Cursor と Application.Calculation を実例にあげて見ていきましょう。
Private mResumeCalculation As Boolean
Private mOrgValCalculation As XlCalculation
Private mResumeCursor As Boolean
Private mOrgValCursor As XlMousePointer
Public Property Let TemporaryCalculation(ByVal NewVal As XlCalculation)
If Not mResumeCalculation Then
mOrgValCalculation = Application.Calculation
End If
mResumeCalculation = True
Application.Calculation = NewVal
End Property
Public Property Let TemporaryCursor(ByVal NewVal As XlMousePointer)
If Not mResumeCursor Then
mOrgValCursor = Application.Cursor
End If
mResumeCursor = True
Application.Cursor = NewVal
End Property
Private Sub Class_Initialize()
mResumeCalculation = False
mResumeCursor = False
End Sub
Private Sub Class_Terminate()
Call ResumeAll
End Sub
Private Sub ResumeAll()
If mResumeCalculation Then
Application.Calculation = mOrgValCalculation
End If
If mResumeCursor Then
Application.Cursor = mOrgValCursor
End If
End Sub
プロパティを初めて変えた時だけ変更前の値のバックアップを取っておいて、デストラクタでその値に戻すわけです。
プロシージャ単位で使うなら冒頭で宣言すればあとは何も書かなくてもそのプロシージャの終了時に戻してくれます。
Sub SampleProc
Dim AppTempMode As New ApplicationTemporaryMode
AppTempMode.TemporaryCursor = xlWait
'(一時変更している間に実行する処理)
End Sub
プロシージャの途中での一時利用なら、With New
でも使えば手軽です。
With New ApplicationTemporaryMode
.TemporaryCursor = xlWait
.TemporaryCalculation = xlCalculationManual
'(一時変更している間に実行する処理)
End With
プロパティをいくつ変更しようが、End With
一つで戻りますからね。
応用範囲
これでうれしいのは、エラーで中断しようがExit Sub
しようが、このブロックを抜けたときに必ず実行されるということです。
そういう対応漏れは、自他ともによく見かけますからね。
ここでは
Application.Cursor
-
Application.Calculation
だけを取り上げましたが、Application
のプロパティだけでも他に Application.DisplayAlerts
Application.ScreenUpdating
-
Application.Visible
など、一時変更したいプロパティは色々あるので、割とよく使えるのではないでしょうか。
一時変更するものとしては他に Application.Selection
- ブックの一時的なオープン
などもありますが、これらはもう少し面倒なことがあるので、また別の機会に。