ユーザーフォームの起動確認

ユーザーフォームの起動(読み込み)状態を確認する方法

If UserForms.Count <> 0 Then
'読み込みされたフォームの1番目のCaptionプロパティを取得
Debug.Print UserForms(0).Caption
Else: End If

ユーザーフォームの起動確認には、UserFormsコレクションを利用します
このコレクションは読み込みが実行されているユーザーフォームのコレクションになります
読み込みとはメモリ上に読み込みをされた状態なので、Showメソッドだけではなく、Loadメソッドが実行されて読み込まれた時点でコレクションに収まります

よくある起動確認でVisibleプロパティを利用することがありますが、これはあくまでも表示状態を表すプロパティですので、起動確認の目的では少しイメージが違います
なにより、ユーザーフォームのプロパティを取得しようとすると読み込みが実行されてしまいます
プロパティを取得したかっただけなのにInitializeイベントが実行され、処理を作成していた場合は実行されます
意図しないタイミングでフォームが読み込みを行う形になってしまいます

この状態でShowメソッドを実行しても、非表示状態から表示されただけの動きになってしまうので、非常に注意が必要です

そのため、フォームの起動確認にはUserFormsコレクションを利用してください
上記にあるようにこのコレクションは読み込みが実行されたものだけを対象としているので、Showメソッド含めて読み込みされていないフォーム判定が可能です

もちろん対象フォームのプロパティを取得するわけではないので、勝手に読み込みされることもありません

基本的に例コードの様にCountプロパティを利用する場面が多くなると思います
複数のフォームを同時起動して、かつその中でどのフォームだけの起動確認を行う場合は結構特殊な場面と思います

ほとんどは1つのフォームの起動確認を行う場合が多いです

コード解説

If UserForms.Count <> 0 Then

~~中略~~

Else: End If

IF文により判定を行います
Countプロパティは読み込まれたユーザーフォームの個数を返します
なのでこのプロパティが1以上を返せば、何らかのユーザーフォームが読み込まれていることが確認できます

上記にもあるように、ほとんどの場合は1つのユーザーフォームの起動確認を行う場面が多いので、このインデックス番号のフォームのプロパティを取得して判定を深堀りする必要は無いでしょう

'読み込みされたフォームの1番目のCaptionプロパティを取得
Debug.Print UserForms(0).Caption

取得が必要な場合は、ユーザーフォームの各プロパティをそのまま利用できます
インデックス番号は0から始まるので、0は確定で存在します
またCaptionプロパティや前述のVisibleプロパティも取得を行えます

実際の使用について

フォームを起動せずにコードを実行したときの動き
フォームを起動していない場合

この画像の動きはフォームを起動せずに実行した場合の動きになります
読み込みを実行していないため、Countプロパティが返す値は0となるためElseの処理が実行されます
今回は何も処理が無いので、何も起こりません

フォームを起動した状態でコードを実行したときの動き
フォームを起動した状態の場合

次にフォームを起動した状態でコードを実行しています
この状態であればCountプロパティは1を返すので、イミディエイトウィンドウに読み込みされたユーザーフォームの1番目(インデックス番号0)の表示文字列が出力されます

1つのユーザーフォームの起動確認を前提とすれば、Countプロパティが0か1かを判断すれば十分です

0なら起動されていない、1なら読み込みが実行されている
1で起動しているならVisibleプロパティで表示状態を確認しても良いでしょう
すでに読み込みされているので、プロパティを取得しても問題はありません

あとはこのIF分岐によって処理を組み込めば良いだけになります

主にこの判定処理に関しては、ユーザーフォームを自動的に起動・終了をさせるイベントや処理中にイベントの発生を容認する必要があるけど起動・終了イベントに影響が出てしまう等々の場合にユーザーフォームが起動されていれば、不要な処理は記事コードによって行わないようにする
そんな場合に使用します

最も多い場面が、自動終了させたい場合かもしれません
ExcelVBAの仕様で、Unloadステートメントを実行した場合に対象のユーザーフォームがそもそも読み込みをされていない場合Unloadという目的を達成するために、一度わざわざ読み込みを実行してからUnloadを行います

起動処理や終了処理が無い場合や、処理時間が一瞬なら大して問題は無いのですが、そうでない場合はユーザーにとっては非常に煩わしいです
注意が必要な運用方法です