HOME>IT関連>VBA>vba-nonqueryclose

VBA ユーザーフォームでQueryCloseイベントを使わずに×ボタンで閉じられたことを検出する方法

VBA

こんにちは。すたユキです。

ユーザーフォームを使用する際は、×ボタンで閉じられることも想定しておきたいですね。

予期せぬタイミングで×ボタンを押されると具合が悪いというケースは多いと思います。

対策方法は、大きく次の2つに分かれます

  • ①×ボタンを押せなくする
  • ②予め×ボタンを押された場合の処理を用意しておく

①の場合は、Windows APIを使うことで実現できますが、

Alt+F4で閉じてしまい、その回避処理も書くと煩雑になるため、あまりおすすめしません

ということで、今回は②の方法をご紹介しますが、定番のQueryCloseイベントは使いません

ただ、やや力業?のような方法でもあるので、善し悪しはご自身でご判断ください。

サンプルUserFormの作成

下記のようなユーザーフォームを作るとします。

処理内容は下記のようにします。

実行ボタンを押す

フォームを閉じてテキストボックスの値を表示するメッセージボックスを表示する。

×ボタンで閉じる

「×ボタンで閉じられました。」というメッセージボックスを表示する。

フォームの構成は下記のとおりです。

Label1(Label)・tbTest(TextBox)・btTest(CommandButton)

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

これが今回の最大のポイントになります。

これはユーザーには見えないのですが、実はLabelが隠されています

これを変数のように操作することで、グローバル変数を使わなくても標準モジュールへ状態を伝えることができるわけです。

隠しラベルのプロパティ

プロパティを見ればわかりますが、文字色(ForeColor)背景色(BackColor)フォームの背景と同じ色になっているんですね。

意外に古典的なやり方だったり。

そして、Captionの初期値をTrueに設定しておきます。初期化時に明示しても良いですね。

UserForm内の処理

次に、ユーザーフォーム内の処理を見ていきます。

内容は下記のとおり、とてもシンプルなものとなっています。

ポイントは、実行ボタンが押されたとき隠しラベルCaptionFalseにするところです。

その後自身をHideで隠していますが、こちらは保険のような意味合いが強いです。
とは言え、特別な理由がない限りUnloadではなくHideをおすすめします。

標準モジュール内の処理の書き方によってはUnloadしても動きます。(説明は後ほど)

標準モジュール内の処理

最後に、標準モジュール内の処理について見ていきましょう。

構成はとてもシンプルですが、極力グローバル(Public)変数を使わない思想で書いています。

グローバル変数を使わずにユーザーフォームへ値を渡す方法については、こちらの記事に詳しく書いています。

一番重要なポイントは、Withステートメントを使いUserForm(TestForm)に関連する処理を括っているところです。

今回は全ての処理がWith内に書かれています。

前のUserFormの節で少し触れた、Unloadしていても動くと書いていたのは、この書き方が前提となっています。

このWithステートメントを抜けるまでは、UserForm内の値を呼び出すことが可能です。

TestFormインスタンスは保持されている

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の場合はダブルクォーテーション(“)で囲む必要がなく、見た目もわかりやすいので、私はこれを使っています。

本記事の内容は以上となります。

最後まで読んでいただきありがとうございました。

コメント