ユーザーフォームの×ボタンを無効化する方法(VBA)

ユーザーフォームの×ボタンを無効化

今回はユーザーフォームの×ボタンを無効化する方法を紹介します。

また、後半には×ボタンを押されると誤動作する例を紹介します。

ユーザーフォームの×ボタンを無効化する方法

×ボタンを無効化するにはイベントを利用します

QueryClose

ユーザーフォームには「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となっています。

vbFormControlMenu0ユーザーが、UserForm の コントロール メニューで [閉じる] コマンドを選択しました。
vbFormCode1コードから Unload ステートメントが呼び出されます。
vbAppWindows2現在の Windows オペレーティング環境セッションが終了しようとしています。
vbAppTaskManager3Windows タスク マネージャー がアプリケーションを閉じようとしています。
https://docs.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/queryclose-event

上記のプログラムは、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

こうしておけば、×ボタンを押したとしてもユーザーフォーム後の処理は実行されないため、誤動作を防ぐことができます。

《VBA初心者におすすめの本》
VBA初心者には、株式会社すごい改善さんの本が分かりやすくておすすめです。

created by Rinker
技術評論社
¥2,178 (2021/12/01 14:22:42時点 Amazon調べ-詳細)

動画で学びたい人には、すごい改善さんのUdemy講座をおすすめします。
【累計36万部著者が教える】たった1日で!まったくの初心者でも最短でExcel VBAを仕事で活用できるようになる講座

他の「VBA」の記事はこちらからどうぞ

VBA

Posted by やろまい