はじめに
VBAのユーザーフォームを操作画面として提供する場合、「フォームが閉じられたタイミングで、後片付けの処理を自動で実行したい」ということがあります。例えば、入力された内容をシートに書き出したり、作業ログを記録したり、といったケースです。
VBAのユーザーフォームには、フォームが完全に閉じられ、メモリから破棄される直前に発生する Terminate
というイベントが用意されています。これを利用すれば、フォームの終了をトリガーにして、特定のクリーンアップ処理や最終処理を確実に実行させることができます。
この記事では、Terminate
イベントを使って、フォームが閉じられる際に特定の処理を自動実行する方法を解説します。
フォームが閉じる時に処理を実行するVBAサンプルコード
このマクロは、ユーザーフォームが Unload
されるか、右上の「×」ボタンで閉じられて、メモリから解放される直前に動作します。
ここでは、「Log」という名前のシートのA列最終行に、フォームが閉じられた時刻を記録する、という例を作成します。
ユーザーフォームのコード (DataForm
)
このコードは、ユーザーフォームのコードモジュールに直接記述します。
- VBEで対象のユーザーフォームをダブルクリックして表示します。
- フォームの何もないところをダブルクリックしてコードウィンドウを開きます。
- 上部のドロップダウンで
(General)
からUserForm
を選び、右側のドロップダウンでTerminate
を選びます。
VB.Net
' フォームがメモリから破棄される直前に実行されるイベント
Private Sub UserForm_Terminate()
' 標準モジュールに記述したクリーンアップ処理を呼び出す
Call CleanUpProcess
End Sub
標準モジュールのコード (Module1
)
フォームが閉じたときに実行したい具体的な処理は、標準モジュールに記述しておくと管理がしやすくなります。
' フォーム終了時に呼び出される後片付け処理
Sub CleanUpProcess()
Dim logSheet As Worksheet
Dim lastRow As Long
On Error Resume Next
Set logSheet = ThisWorkbook.Worksheets("Log")
On Error GoTo 0
If logSheet Is Nothing Then
' Logシートがなければ作成
Set logSheet = ThisWorkbook.Worksheets.Add
logSheet.Name = "Log"
End If
' LogシートのA列最終行を取得
lastRow = logSheet.Cells(logSheet.Rows.Count, "A").End(xlUp).Row + 1
' 終了ログを書き込み
logSheet.Cells(lastRow, "A").Value = "フォームが " & Now() & " に閉じられました。"
End Sub
コードの解説
Private Sub UserForm_Terminate()
Terminate
イベントは、フォームのインスタンスがメモリから完全に解放される直前に一度だけ発生します。フォームを Unload
ステートメントで閉じた場合や、「×」ボタンで閉じた場合に、このイベントがトリガーされます。
注意: フォームを .Hide
メソッドで非表示にしただけでは、フォームはメモリ上に存在し続けるため、この Terminate
イベントは発生しません。
Call CleanUpProcess
Terminate
イベントプロシージャの中から、標準モジュールに記述した CleanUpProcess
マクロを呼び出しています。終了時の処理が複雑になる場合でも、このように処理を別のモジュールに分離しておくことで、コードの見通しが良くなります。
CleanUpProcess
マクロの処理
このマクロは、Log
という名前のワークシートを探し、もし存在しなければ新規に作成します。その後、A列の最終行に「フォームが(現在の日時)に閉じられました。」という文字列を記録します。これにより、ユーザーがいつフォームでの作業を終えたかを追跡できます。
QueryClose
と Terminate
の違い
前回解説した QueryClose
イベントとの違いを理解することが重要です。
QueryClose
: フォームが閉じられようとする直前に発生。「閉じるのをキャンセルする」ことが可能。Terminate
: フォームが完全に閉じられ、メモリから消える直前に発生。「閉じるのをキャンセルする」ことはできない。
つまり、閉じる操作の検証や確認を行いたい場合は QueryClose
を、閉ることが確定した後の最終的な後片付けを行いたい場合は Terminate
を使います。
まとめ
今回は、UserForm_Terminate
イベントを利用して、フォームが閉じられるタイミングで後片付けの処理を自動実行する方法を解説しました。
- フォームの終了処理には
Terminate
イベントを利用する。 Terminate
はフォームがメモリから解放される直前に発生する。.Hide
ではTerminate
イベントは発生しない。
このイベントを使いこなせば、ツールの終了時に設定を元に戻したり、作業内容を保存したりと、利用者が安心して使える、より完成度の高いアプリケーションを作成することができます。