こんにちは。すたユキです。
ユーザーフォームを使用する際は、×ボタンで閉じられることも想定しておきたいですね。
予期せぬタイミングで×ボタンを押されると具合が悪いというケースは多いと思います。
対策方法は、大きく次の2つに分かれます。
①の場合は、Windows APIを使うことで実現できますが、
Alt+F4で閉じてしまい、その回避処理も書くと煩雑になるため、あまりおすすめしません。
ということで、今回は②の方法をご紹介しますが、定番のQueryCloseイベントは使いません。
ただ、やや力業?のような方法でもあるので、善し悪しはご自身でご判断ください。
サンプルUserFormの作成
下記のようなユーザーフォームを作るとします。
処理内容は下記のようにします。
フォームを閉じてテキストボックスの値を表示するメッセージボックスを表示する。
「×ボタンで閉じられました。」というメッセージボックスを表示する。
フォームの構成は下記のとおりです。
でも、実はもう1つ隠れているコントロールがいます。
これが今回の最大のポイントになります。
これはユーザーには見えないのですが、実はLabelが隠されています。
これを変数のように操作することで、グローバル変数を使わなくても標準モジュールへ状態を伝えることができるわけです。
プロパティを見ればわかりますが、文字色(ForeColor)と背景色(BackColor)がフォームの背景と同じ色になっているんですね。
意外に古典的なやり方だったり。
そして、Captionの初期値をTrueに設定しておきます。初期化時に明示しても良いですね。
UserForm内の処理
次に、ユーザーフォーム内の処理を見ていきます。
内容は下記のとおり、とてもシンプルなものとなっています。
1 2 3 4 5 6 7 8 9 10 |
Option Explicit '実行ボタンが押されたときの処理 Private Sub btTest_Click() '隠しラベルのCaptionをFalseに Me.lbCancel.Caption = False 'UserFormを隠す Me.Hide End Sub |
ポイントは、実行ボタンが押されたときに隠しラベルのCaptionをFalseにするところです。
その後自身をHideで隠していますが、こちらは保険のような意味合いが強いです。
とは言え、特別な理由がない限りはUnloadではなくHideをおすすめします。
標準モジュール内の処理
最後に、標準モジュール内の処理について見ていきましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
Option Explicit Sub CloseTest() With TestForm 'テキストボックスに任意の値を設定 .tbTest.Value = "Hello Sutayuki" '隠しラベルの初期値を明示する場合 '.lbCancel.Caption = True '初期化 'ユーザーフォームを表示 .Show '×ボタンで閉じられたかどうかを判定 If .lbCancel.Caption = True Then MsgBox "×ボタンで閉じられました。" Exit Sub Else MsgBox .tbTest.Value '**** 任意の処理を記載 **** End If '**** 任意の処理を記載 **** '隠れているだけなので処理の最後にフォームを閉じる Unload TestForm End With End Sub |
構成はとてもシンプルですが、極力グローバル(Public)変数を使わない思想で書いています。
グローバル変数を使わずにユーザーフォームへ値を渡す方法については、こちらの記事に詳しく書いています。
一番重要なポイントは、Withステートメントを使いUserForm(TestForm)に関連する処理を括っているところです。
前のUserFormの節で少し触れた、Unloadしていても動くと書いていたのは、この書き方が前提となっています。
このWithステートメントを抜けるまでは、UserForm内の値を呼び出すことが可能です。
UserForm内でHideしておいた場合には、Withステートメントの外で.Show以降の処理を書いても正常に動くはずです。
ですので、基本的にUserForm内ではUnloadせずにHideしておく方が無難で、その後の処理に柔軟性を持たせられるということですね。
説明は不要かもしれませんが、念のため記載しておきます。
1 2 3 4 5 6 7 8 9 |
With TestForm 'テキストボックスに任意の値を設定 .tbTest.Value = "Hello Sutayuki" '隠しラベルの初期値を明示する場合 '.lbCancel.Caption = True '初期化 'ユーザーフォームを表示 .Show |
冒頭の部分です。ここはUserFormの初期化と表示までの部分です。
このようにShow前に記述することでUserForm_Initializeイベントが不要となります。
隠しラベル(lbCancel)の初期値を明示したい場合はコメントアウトを解除してください。
1 2 3 4 5 6 7 8 9 10 |
'×ボタンで閉じられたかどうかを判定 If .lbCancel.Caption = True Then MsgBox "×ボタンで閉じられました。" Exit Sub Else MsgBox .tbTest.Value '**** 任意の処理を記載 **** End If |
TestFormが閉じら(隠さ)れた後の処理です。
×ボタンで閉じられた場合は、lbCancelの値は初期値のTrueのままとなり、
実行ボタンで閉じられた場合は、Falseになるので上記のような分岐が可能となります。
また、×ボタンの場合はTestFormはUnloadされた状態になるので、その後はUnloadせずに終了させます。
今回の実行ボタンでの操作は、メッセージボックスの表示ですが、tbTest.ValueのようにUserFormの値を受け取ることができるので、任意の処理を書くことが可能です。
任意の処理は、「任意の処理を記載」部分に書いていただければ問題ありません。
1 2 3 4 5 6 |
'**** 任意の処理を記載 **** '隠れているだけなので処理の最後にフォームを閉じる Unload TestForm End With |
そして、最後に忘れずにTestFormをUnloadしてやります。
ちなみに、隠しラベルの値はTrue・Falseでなくても構いません。0・1や“ON”・”OFF”など、ご自身がわかりやすい任意の値でOKです。
True・Falseの場合はダブルクォーテーション(“)で囲む必要がなく、見た目もわかりやすいので、私はこれを使っています。
本記事の内容は以上となります。
最後まで読んでいただきありがとうございました。
コメント