|
診断(4)
マクロ実行中のメッセージを出したい
「先生,何やってるんですか? 診療の時間ですよ」
「おぉ,もうそんな時間か。カーナビにワンセグのチューナーを取り付けておったのじゃよ」
「ナスビにワンタン?」
「これじゃ」
「なんだテレビじゃないですかぁ」
「デジタル放送じゃぞ!」
「ふ~ん」
「それだけかい!」
「はいはい。さ,お仕事しましょ」
|
「ふむふむ,これははまりがちな問題じゃな」
「先生,それは処方できないという意味ですか?」
「うむ,完治は難しいかもしれん。じゃが,対処療法ならある」
「それはどういうことですか?」
相談者がお悩みのように,メッセージボックスを表示すると,ユーザーがボタンをクリックしてメッセージボックスが消えるまで,次のステートメントは実行されません。というか,次を実行されてはメッセージボックスを出す意味がありません。これは仕様です。
しかし,何らかの表示をしながら,バックグラウンドでマクロを実行したい状況はあります。リスト1のように,ウィンドウ一番下のステータスバーに文字列を表示することはできますが,ステータスバーは目立たないので,ユーザーが気づかない可能性が高いです。
|
リスト1●ステータスバーに文字列を表示するプロシジャ |
やはり,もっと目立つようにメッセージを表示したい,そして,マクロが終了したらそのメッセージを消したい──そういうケースもあるでしょう。このような場合,ちょっとしたテクニックを使えば,希望に近いものを作ることができます。例えば,ワークシートのセルを使ってプログレスバー(進ちょく状況を表示するバー)を描画するという手もあります。ここでは,ユーザーフォームを使って,擬似的なメッセージボックスを表示するテクニックを紹介しましょう。
なお,ユーザーフォームを使う場合でも,それを表示するステートメントの次のステートメントは,ユーザーフォームが非表示(UnloadまたはHide)になるまで実行されません。例えば,リスト2のマクロは,ユーザーフォームが表示されている間は,(1)のステートメントは実行されず,メッセージボックスは表示されません。ユーザーフォームを閉じると,メッセージボックスが表示されます。
|
リスト2●ユーザーフォームのテスト |
したがって,ここまではユーザーフォームもメッセージボックスも同じです。つまり,ユーザーフォームを表示するステートメントと,実際に処理を実行するステートメントを同じプロシジャに記述したのでは,希望の動作はしないということです。
しかし,ユーザーフォームにはイベントプロシジャがあります。今回使用するのは,Activateイベントです。このイベントは,ユーザーフォームがアクティブになると発生します。そしてUserForm_Activateプロシジャが記述されていると,それを実行します。
このUserForm_Activateプロシジャの中に,処理のステートメントを記述すれば,まるでユーザーフォームのバックグラウンドで処理が実行されているかのように見えます。「じゃあ,これで問題解決?」というと,そう簡単ではありません。
UserForm_Activateプロシジャの実行中は,ユーザーフォーム自体は表示されても,ユーザーフォーム上に配置したコントロールが表示されません。つまり,「マクロ実行中」といったラベルをユーザーフォーム上に配置しても無意味なのです。では,どのようにしてメッセージをユーザーに伝えるのか? 唯一表示されるのが,ユーザーフォームのCaptionです。これを利用して,ユーザーにメッセージを伝えます。
では,順を追って説明しましょう。
(1)ユーザーフォームを作成する
まず,ユーザーフォームを作成します。VBEのメニューから[挿入]-[ユーザーフォーム]の順にクリックするとユーザーフォームが作成されます(図1)。
| |
図1●ユーザーフォームの作成 [画像のクリックで拡大表示] |
(2)UserFormのCaptionプロパティを変更
プロパティウィンドウで,ユーザーフォームのキャプションを変更します(図2)。
| |
図2●ユーザーフォームのキャプションを変更する [画像のクリックで拡大表示] |
(3)UserForm_Activateプロシジャを作成
[コードの表示]ボタンをクリックすると,ユーザーフォームのモジュールが表示されます。「オブジェクトボックス」で,「UserForm」を選ぶとUserForm_Clickプロシジャが自動的に作成されますが,これは削除してください。次に「イベントボックス」で「Activate」をクリックすると,UserForm_Activateプロシジャが作成されます(図3)。
| |
図3●UserForm_Activateプロシジャを作成する [画像のクリックで拡大表示] |
(4)処理のステートメントを記述
UserForm_Activateプロシジャに,処理のステートメントを記述します。例えば,リスト3のように記述すると,ユーザーフォームが表示されると同時に「MAKE_DATA」プロシジャが実行されます。
|
リスト3●UserForm_Activateプロシジャの例 |
(5)ユーザーフォームを非表示にするステートメントを記述
実行したい処理のステートメントの後に,ユーザーフォームを非表示にするステートメントを記述します(リスト4)。これにより,「MAKE_DATA」プロシジャが実行された後,すぐにユーザーフォームは非表示になります。
|
リスト4●UserForm_Activateプロシジャの例その2 |
(6)標準モジュールを作成
VBEのメニューから[挿入]-[ユーザーフォーム]の順にクリックして標準モジュールを作成します。
(7)標準モジュールにユーザーフォームを表示するプロシジャを記述
リスト5のShowメソッドのオプションは,ユーザーフォーム表示中にExcelの操作を認めるかどうかの選択です。このオプションを省略,またはvbModalにした場合は,ユーザーフォームを表示中にExcelの操作はできません。vbModelesにした場合は,ユーザーフォームを表示中であってもExcelの操作が可能です。
|
リスト5●ユーザーフォームを表示するプロシジャ |
(8)ワークシートにマクロを実行するボタンを配置
最後にワークシート上にボタンを配置し,ユーザーフォームを表示するマクロを登録します(図4)。
図4●ボタンを配置し,マクロを登録する |
図5の「マクロの登録」ウィンドウで,登録するマクロを選び,[OK]ボタンをクリックして完了です。
図5●マクロの登録ウィンドウ |
「どうじゃな? こうすれば,マクロ実行中はユーザーフォームが表示され,マクロ終了と同時に消えるじゃろ?」
「はい,先生,すばらしい出来です。でも,マクロを実行して終ったことが確認できません」
「どういうことじゃ?」
「マクロを実行する前と終った後が同じ画面の場合,もしかしたらマクロを実行していないのかもって思っちゃうんです」
「ほー,では,こんなのはどうかな?」
| |
図6●マクロ実行後にメッセージを表示 [画像のクリックで拡大表示] |
「これなら,マクロ実行中に席を離れて戻ってきたときでも,マクロを実行して終ったことがはっきりわかりますね」
「そうじゃろ」
「先生,このマクロはどうなってるんですか?」
ユーザーフォームにラベルを一つ配置し,処理をするマクロを実行後にラベルのCaptionプロパティの値を変更します(1)。その代わりに,ユーザーフォームを非表示にするステートメントを削除しました(リスト6)。
|
リスト6●「完了」を表示するマクロ |
「実は,処理するマクロ(MAKE_DATA)が終了するまで,ラベルは表示されないから,プロパティ設定で,初めからキャプションを『マクロの実行が完了しました』にしておいても結果は同じなんじゃがね」
「え~! じゃあ,(1)のステートメントは無意味じゃないですか」
「……」
「先生?」
「次の方,ど~ぞ~」