- ベストアンサー
Excel VBAで、ユーザーフォームをモードレス表示している間、処理を止めるには?
VBA初心者です。 タイトルの通りですが、例えばサブルーチン(1)の途中でユーザーフォーム(1)をモードレス表示している間、処理を止めることは可能でしょうか? サブルーチン(1)を、ユーザーフォーム(1)を表示する前後に分割して、ユーザーフォーム(1)を閉じた時にサブルーチン(1-後半)を呼び出すことも考えたのですが・・・サブルーチン(1-前半)を別のサブルーチン(2)から呼び出した場合に、サブルーチン(1-前半)をEnd Subした時点で、サブルーチン(2)が進行してしまいます。 分かり難い質問で申し訳ありませんが、皆様の知恵をお貸しください。よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>コードを解説していただけないでしょうか? どこらへんが、わからないんでしょうか? >UserForm1.Show (vbModeless) はもともとやっておられるから >Do While form >dummy = DoEvents() >Loop ですか? Do While ~ Loop は、条件が成立している間ループするということです。 この場合の条件は「form」ですが、これは、Boolean ですので、 True と False の値をとります。 True は、条件が成立しているということを表します。 つまり、form の値がTrue から False に変化するまでループを実行するということです。 DoEvents 関数は、OSにたまっている処理を実行させる処理をします。 単純に、 Do While True '処理は何もない Loop とかすると、ものすごい勢いでループをして、他のプログラムが何かを処理する機会が与えられないので他のプログラムは動作できなくなります。そういう場合に、他のプログラムに対して処理する機会を与える(OSがやります)ことができます。 Dummy は、DoEventsが返す値はこの場合、別に必要ないですが、関数を関数形で呼び出す場合には、何かに代入する形にしてやる必要があります。 手続きではなくて関数を呼び出しているということをはっきりさせるためにそのようにしています。(他の人ならそのようには書かないかもしれません、そういうのは趣味で分かれる範疇です)
その他の回答 (4)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>エクセルのセルへの入力などはおこなえないようですね ウチで試してみたところでは、 UserForm1 を表示中セルへの入力は、行えますけど・・
お礼
セルへの入力をおこなうことができました!ありがとうございました。おかげさまで、目的とする結果を得ることができました。 これだけつきあっていただいて厚かましいお願いですが、もしお手数でなければコードを解説していただけないでしょうか?(なにぶん初心者なもので、よくわかりません)
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>Do Loopなどを使って処理を中断することも試してみたのですが、うまくいきませんでした。 ループで待つのは、あんまり良いとは思えませんが、もちろんできますよ。 例えば、呼び出し側を 大域変数を Public form As Boolean のように準備して Public Sub test() Dim dummy As Integer MsgBox "前処理" form = True 'フォームを呼び出す前にセット UserForm1.Show (vbModeless) Do While form dummy = DoEvents() Loop MsgBox "後処理" End Sub のようにしてフォームの側で大域変数の状態を変更するまで待てます。 フォームの側では、 Private Sub CommandButton1_Click() Unload UserForm1 End Sub Private Sub UserForm_Terminate() form = False End Sub のようにアンロードされる時にFalse にセットします。 セットと解除のタイミングについては、 フォームのinitialize やactivate, deactivate (アンロードでなくHide の場合とか)でしてもいいと思います。
お礼
アドバイス通りに記述してみたところ、処理は止まったのですが、エクセルのセルへの入力などはおこなえないようですね。度々のお返事、本当にありがとうございます。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
>(ここが止まらない) の部分は、後半処理部分として全て移動するという意味です。 中身が無い場合、止まらなくても問題ないように思いますが・
お礼
再びお返事ありがとうございます。 やはり別のサブルーチンの(ここが止まらないの部分)も分割しなければなりませんか・・・。Do Loopなどを使って処理を中断することも試してみたのですが、うまくいきませんでした。 ありがとうございました。
- BLUEPIXY
- ベストアンサー率50% (3003/5914)
後半処理部分を ユーザーフォームが閉じる時のイベント処理に移したらどうでしょうか Private Sub UserForm_Terminate() '後半部分処理 End Sub
お礼
お返事ありがとうございます。アドバイスをまだ試していないのですが・・・ 前半処理部分を別のサブルーチンから呼び出した場合、後半処理部分をユーザーフォームが閉じる時のイベント処理に移しても、別のサブルーチンが進行してしまうような気がするのですが? Sub 別Sub() ↓ 前半→→→→→Sub 前半() ↓ UserForm1.Show vbModeless→→→後半 ↓←←←←←←End Sub ↓ ↓(ここが止まらない) ↓ End Sub
お礼
>どこらへんが、わからないんでしょうか? Do Loopについて Do While form=True と言う記述方法しか知りませんでした。また、DoEventsについても、初めて知りました。 長い間おつきあい頂き、本当にありがとうございました。感謝です。