はじめに
ユーザーフォームで入力画面を作成する際、「必須項目が入力されるまで、フォームを閉じられないようにしたい」という制御が必要になることがあります。例えば、利用規約への同意チェックボックスがオンになるまで、右上の「×」ボタンを無効化したい、といったケースです。
VBAのユーザーフォームには、フォームが閉じられようとする直前に発生する QueryClose
という特別なイベントが用意されています。これを利用すれば、特定の条件を満たさない限り、フォームが閉じるのをキャンセル(中断)させることができます。
この記事では、QueryClose
イベントを使って、フォームが閉じられるのを制御するスマートな方法を解説します。
フォームが閉じるのを防ぐVBAサンプルコード
このマクロは、ユーザーフォームの右上の「×」ボタンが押されたときなど、フォームが閉じられようとした瞬間に動作します。
ここでは、「利用規約に同意する」というチェックボックス(AgreeCheckBox
)がオンになっていない限り、フォームを閉じさせない、という例を作成します。
ユーザーフォームのコード (MainForm
)
このコードは、ユーザーフォームのコードモジュールに直接記述します。
- VBEで対象のユーザーフォームをダブルクリックして表示します。
- フォームの何もないところをダブルクリックしてコードウィンドウを開きます。
- 上部のドロップダウンで
(General)
からUserForm
を選び、右側のドロップダウンでQueryClose
を選びます。
' フォームが閉じられようとするときに実行されるイベント
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
' --- チェックボックス(AgreeCheckBox)がオフの場合 ---
If Me.AgreeCheckBox.Value = False Then
' CloseMode = 0 は、右上の「×」ボタンが押されたことを示す
If CloseMode = vbFormControlMenu Then
' 処理をキャンセルし、メッセージを表示
MsgBox "利用規約への同意が必要です。", vbExclamation, "確認"
Cancel = True
End If
End If
End Sub
コードの解説
Private Sub UserForm_QueryClose(...)
QueryClose
イベントは、フォームが閉じられようとする、あらゆる操作を検知して発生します。このプロシージャには、2つの重要な引数が渡されます。
Cancel As Integer
: この引数にTrue
を設定すると、フォームを閉じる操作がキャンセルされます。これがこのテクニックの核心です。CloseMode As Integer
: フォームがどのような理由で閉じられようとしているかを示す数値が入っています。
If CloseMode = vbFormControlMenu Then
CloseMode
に入る値はいくつかありますが、最も重要なのは 0
(VBAの定数では vbFormControlMenu
)です。これは、ユーザーがフォームの右上にある「×」ボタンをクリックしたことを意味します。
Unload Me
のようなコードでフォームを閉じた場合は 1
(vbFormCode
) になります。意図しない動作を防ぐため、「ユーザーが『×』ボタンで閉じようとしたときだけ」チェックするように、If
文で条件分岐させています。
Cancel = True
チェックボックスがオフの状態で「×」ボタンが押された場合に、このコードが実行されます。Cancel
引数を True
にすることで、Excelに対して「今やろうとしているフォームを閉じる操作は、やめてください」と命令していることになり、結果としてフォームは閉じられずに表示され続けます。
まとめ
今回は、UserForm_QueryClose
イベントを利用して、特定の条件を満たすまでフォームが閉じられるのを防ぐ方法を解説しました。
QueryClose
イベントは、フォームが閉じられる直前に発生する。Cancel
引数をTrue
に設定すると、閉じる動作を中断できる。CloseMode
引数をチェックすることで、なぜフォームが閉じられようとしているのか(例: 「×」ボタンが押された)を判別できる。
このイベントを使いこなせば、ユーザーに入力を強制したり、データの整合性を保ったりと、より堅牢で親切な入力フォームを作成することができます。