
こんにちは。すたユキです。
ユーザーフォームを使用する際は、×ボタンで閉じられることも想定しておきたいですね。
予期せぬタイミングで×ボタンを押されると具合が悪いというケースは多いと思います。
対策方法は、大きく次の2つに分かれます。
①の場合は、Windows APIを使うことで実現できますが、
Alt+F4で閉じてしまい、その回避処理も書くと煩雑になるため、あまりおすすめしません。
ということで、今回は②の方法をご紹介しますが、定番のQueryCloseイベントは使いません。
ただ、やや力業?のような方法でもあるので、善し悪しはご自身でご判断ください。
サンプルUserFormの作成
下記のようなユーザーフォームを作るとします。

処理内容は下記のようにします。
フォームを閉じてテキストボックスの値を表示するメッセージボックスを表示する。
「×ボタンで閉じられました。」というメッセージボックスを表示する。
フォームの構成は下記のとおりです。

でも、実はもう1つ隠れているコントロールがいます。

これが今回の最大のポイントになります。
これはユーザーには見えないのですが、実はLabelが隠されています。
これを変数のように操作することで、グローバル変数を使わなくても標準モジュールへ状態を伝えることができるわけです。

プロパティを見ればわかりますが、文字色(ForeColor)と背景色(BackColor)がフォームの背景と同じ色になっているんですね。
意外に古典的なやり方だったり。
そして、Captionの初期値をTrueに設定しておきます。初期化時に明示しても良いですね。

UserForm内の処理
次に、ユーザーフォーム内の処理を見ていきます。
内容は下記のとおり、とてもシンプルなものとなっています。
ポイントは、実行ボタンが押されたときに隠しラベルのCaptionをFalseにするところです。
その後自身をHideで隠していますが、こちらは保険のような意味合いが強いです。
とは言え、特別な理由がない限りはUnloadではなくHideをおすすめします。
標準モジュール内の処理
最後に、標準モジュール内の処理について見ていきましょう。
構成はとてもシンプルですが、極力グローバル(Public)変数を使わない思想で書いています。
グローバル変数を使わずにユーザーフォームへ値を渡す方法については、こちらの記事に詳しく書いています。
一番重要なポイントは、Withステートメントを使いUserForm(TestForm)に関連する処理を括っているところです。
前のUserFormの節で少し触れた、Unloadしていても動くと書いていたのは、この書き方が前提となっています。
このWithステートメントを抜けるまでは、UserForm内の値を呼び出すことが可能です。
UserForm内でHideしておいた場合には、Withステートメントの外で.Show以降の処理を書いても正常に動くはずです。
ですので、基本的にUserForm内ではUnloadせずにHideしておく方が無難で、その後の処理に柔軟性を持たせられるということですね。
説明は不要かもしれませんが、念のため記載しておきます。
冒頭の部分です。ここはUserFormの初期化と表示までの部分です。
このようにShow前に記述することでUserForm_Initializeイベントが不要となります。
隠しラベル(lbCancel)の初期値を明示したい場合はコメントアウトを解除してください。
TestFormが閉じら(隠さ)れた後の処理です。
×ボタンで閉じられた場合は、lbCancelの値は初期値のTrueのままとなり、
実行ボタンで閉じられた場合は、Falseになるので上記のような分岐が可能となります。
また、×ボタンの場合はTestFormはUnloadされた状態になるので、その後はUnloadせずに終了させます。
今回の実行ボタンでの操作は、メッセージボックスの表示ですが、tbTest.ValueのようにUserFormの値を受け取ることができるので、任意の処理を書くことが可能です。
任意の処理は、「任意の処理を記載」部分に書いていただければ問題ありません。
そして、最後に忘れずにTestFormをUnloadしてやります。
ちなみに、隠しラベルの値はTrue・Falseでなくても構いません。0・1や“ON”・”OFF”など、ご自身がわかりやすい任意の値でOKです。
True・Falseの場合はダブルクォーテーション(“)で囲む必要がなく、見た目もわかりやすいので、私はこれを使っています。
本記事の内容は以上となります。
最後まで読んでいただきありがとうございました。
コメント