質問: not activesheet.commandbutton1.enabled msgbox "here" end sub 上記のプロシージャに期待したのは、enabeldの状態が反転した後、 hereの文字が表示されると言うものですが、 実際は先にhereの文字が表示されてしまいます。 また、不思議なことにdoeventsを二つ連続でmsgboxの前に入れると きちんと動きます。 (ステップ実行でもきちんと動きます。) 最終的には、もっと長いプログラムの中で使う予定なので、 全てのenabled文の後にdoeventsを二連続で書くという対症療法以外で、 良い解決方法が無いか、お教えいただけると幸いです。 なお、環境はwindowsxp、excel2003です。 よろしくお願いいたします。
回答: >良い解決方法が無いか、お教えいただけると幸いです。 vb6でもそうなんですが、vbaのコマンドボタン(いわゆるforms2.0)はこういう仕様になっています。 少し難しい話になってしまいますが enabledプロパティの状態が即座に反映されるようになるには、 コマンドボタンの再描画の結果を待つことが必要になります。 そしてこの現象は、再描画が完了する前にmsgbox(モーダルなフォーム)が出現してしまい、 再描画が待たされている状態なんですね。 (基本的にメッセージボックスが出てしまったら、その親は画面の再描画が出来なくなる) で、vb6/vbaでは再描画を待つということがdoeventsでしか(ほぼ)出来ないのです。 >全てのenabled文の後にdoeventsを二連続で書くという対症療法 ですので、これは対症療法ではありません。 もっとも、元々のコードが酷いからこのような結論になってしまうのですが(^^; test()では、「アクティブシートのcommandbutton1」の状態しか変えることが出来ませんよね。 アクティブシートにコマンドボタンが無ければ、 いや「commnandbutton1」というオブジェクトが無ければエラーになってしまいます。 このようなコードを私は書かないわけでは決してないんですが、 「全てのenabled文の後に・・・」という愚痴は、絶対に言いません。だって、それは分かりきって書いていますから。 だったらこうするべきでしょう。 'msforms.commandbuttonでエラーになる場合は"object"で sub changestatus(ocmd as msforms.commandbutton) doevents ocmd.enabled = not ocmd.enabled doevents 'msgbox "here" end sub sub test() call changestatus(activesheet.commandbutton1) msgbox "here" end sub '-------------------------------- つまり、「コマンドボタンの状態を変え、doeventsを発行する」という一連の作業を関数にしてしまえばいいんですよ。 ちなみにdoeventsは状態を変える前と後で発行してもうまく行きます。