【VBA】ユーザーフォームが閉じる時にマクロを実行する方法 (Terminate)

目次

はじめに

VBAのユーザーフォームを操作画面として提供する場合、「フォームが閉じられたタイミングで、後片付けの処理を自動で実行したい」ということがあります。例えば、入力された内容をシートに書き出したり、作業ログを記録したり、といったケースです。

VBAのユーザーフォームには、フォームが完全に閉じられ、メモリから破棄される直前に発生する Terminate というイベントが用意されています。これを利用すれば、フォームの終了をトリガーにして、特定のクリーンアップ処理や最終処理を確実に実行させることができます。

この記事では、Terminate イベントを使って、フォームが閉じられる際に特定の処理を自動実行する方法を解説します。


フォームが閉じる時に処理を実行するVBAサンプルコード

このマクロは、ユーザーフォームが Unload されるか、右上の「×」ボタンで閉じられて、メモリから解放される直前に動作します。

ここでは、「Log」という名前のシートのA列最終行に、フォームが閉じられた時刻を記録する、という例を作成します。

ユーザーフォームのコード (DataForm)

このコードは、ユーザーフォームのコードモジュールに直接記述します。

  1. VBEで対象のユーザーフォームをダブルクリックして表示します。
  2. フォームの何もないところをダブルクリックしてコードウィンドウを開きます。
  3. 上部のドロップダウンで (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列の最終行に「フォームが(現在の日時)に閉じられました。」という文字列を記録します。これにより、ユーザーがいつフォームでの作業を終えたかを追跡できます。


QueryCloseTerminate の違い

前回解説した QueryClose イベントとの違いを理解することが重要です。

  • QueryClose: フォームが閉じられようとする直前に発生。「閉じるのをキャンセルする」ことが可能。
  • Terminate: フォームが完全に閉じられ、メモリから消える直前に発生。「閉じるのをキャンセルする」ことはできない。

つまり、閉じる操作の検証や確認を行いたい場合は QueryClose を、閉ることが確定した後の最終的な後片付けを行いたい場合は Terminate を使います。


まとめ

今回は、UserForm_Terminate イベントを利用して、フォームが閉じられるタイミングで後片付けの処理を自動実行する方法を解説しました。

  • フォームの終了処理には Terminate イベントを利用する。
  • Terminate はフォームがメモリから解放される直前に発生する。
  • .Hide では Terminate イベントは発生しない。

このイベントを使いこなせば、ツールの終了時に設定を元に戻したり、作業内容を保存したりと、利用者が安心して使える、より完成度の高いアプリケーションを作成することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次