ユーザーフォームの×ボタンを無効化する方法(VBA)
今回はユーザーフォームの×ボタンを無効化する方法を紹介します。
また、後半には×ボタンを押されると誤動作する例を紹介します。
ユーザーフォームの×ボタンを無効化する方法
×ボタンを無効化するにはイベントを利用します
ユーザーフォームには「UserForm_QueryClose」というイベントがあります。
これはユーザーフォームが閉じる前に発生するイベントで、このイベントを利用することで×ボタンの無効化ができます。
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
'×ボタンを押しても閉じない
If CloseMode = 0 Then
MsgBox "×ボタンで閉じないでください"
Cancel = 1 '閉じる操作をキャンセル
End If
End Sub
上記のプログラムをユーザーフォームのコードに貼付けると、×ボタンを押してもユーザーフォームを閉じられなくすることができます。
UserForm_QueryCloseにはCancelとCloseModeという2つの引数があり、Cancelの値を0以外の値にするとユーザーフォームを閉じる動作がキャンセルされます。
また、CloseModeはQueryCloseイベントが発生した原因を示す引数です。
原因は以下のように分類され、×ボタンによりイベントが発生した場合は引数の値が0となっています。
vbFormControlMenu | 0 | ユーザーが、UserForm の コントロール メニューで [閉じる] コマンドを選択しました。 |
vbFormCode | 1 | コードから Unload ステートメントが呼び出されます。 |
vbAppWindows | 2 | 現在の Windows オペレーティング環境セッションが終了しようとしています。 |
vbAppTaskManager | 3 | Windows タスク マネージャー がアプリケーションを閉じようとしています。 |
上記のプログラムは、CloseModeが0(×ボタンにより閉じられる)の場合に、Cancelの値を変更してユーザーフォームが閉じる動作をキャンセルする、という仕組みです。
×ボタンを押されると誤動作する例
×ボタンを押されると困るのは、ユーザーフォームを閉じた後に処理を行う場合です。
何が起こるかを簡単なコードを使って説明します。
Public strYesNo As String
Sub CallUF()
'ユーザーフォームを呼び出すプロシージャ
strYesNo = "" '変数の初期化
Dim uf As UserForm1: Set uf = New UserForm1
uf.Show
Set uf = Nothing
MsgBox strYesNo
End Sub
'ユーザーフォームのコード
Private Sub CommandButton1_Click()
'はいボタン
strYesNo = "はい"
Unload Me 'ユーザーフォームを閉じる
End Sub
Private Sub CommandButton2_Click()
'いいえボタン
strYesNo = "いいえ"
Unload Me 'ユーザーフォームを閉じる
End Sub
これは上がユーザーフォームを呼び出すCallUFプロシージャ、下がユーザーフォームのプロシージャです。
CallUFプロシージャを実行すると画像のユーザーフォームが表示され、押したボタンの種類に応じて「はい」もしくは「いいえ」のメッセージが表示されます。
押したボタンに応じて、strYesNo変数に"はい"もしくは"いいえ"を格納する仕組みになっています。
×ボタンを押すと何が起きるか
一見、問題の無さそうなプログラムに見えますが、×ボタンを押すと隠れた問題が分かります。
×ボタンを押すと、空白のメッセージが出ます。
これは何が起きているかというと、×ボタンを押すことでstrYesNoに文字が代入されることなくユーザーフォームが終了しています。
そしてユーザーフォームが終わると処理がCallUFプロシージャへ戻され、MsgBoxが実行されているのです。
strYesNoには何も代入されていないため、初期値の空白が表示されています。
誤動作を防ぐ2つの対策方法
対策方法の1つは最初に紹介した×ボタンを無効化することです。
もう1つはユーザーフォームを呼び出すプロシージャに、後の処理を書かないことです
Public strYesNo As String
Sub CallUF()
'ユーザーフォームを呼び出すプロシージャ
strYesNo = "" '変数の初期化
Dim uf As UserForm1: Set uf = New UserForm1
uf.Show
Set uf = Nothing
'処理を書かない!
End Sub
代わりに、ボタンクリックイベントで後の処理を呼び出すようにします。
Private Sub CommandButton1_Click()
'はいボタン
strYesNo = "はい"
Unload Me 'ユーザーフォームを閉じる
Call OutputProcess '後の処理を呼び出す
End Sub
Private Sub CommandButton2_Click()
'いいえボタン
strYesNo = "いいえ"
Unload Me 'ユーザーフォームを閉じる
Call OutputProcess '後の処理を呼び出す
End Sub
Sub OutputProcess()
'ユーザーフォーム後の処理
MsgBox strYesNo
End Sub
こうしておけば、×ボタンを押したとしてもユーザーフォーム後の処理は実行されないため、誤動作を防ぐことができます。