• ベストアンサー

Excel VBA:コントロールボタンのEnabledプロパティーについての質問

コマンドボタンのEnabledプロパティーを変更したときの挙動が良くわからず 困っており、お教えいただけると幸いです。 Excelのワークシート上にCommandButtonを作り(名前をCommandButton1とします)、 module1に以下のプロシージャを書き、Enabledプロパティーを変化させます。 Sub test() ActiveSheet.CommandButton1.Enabled = Not ActiveSheet.CommandButton1.Enabled MsgBox "here" End Sub 上記のプロシージャに期待したのは、Enabeldの状態が反転した後、 hereの文字が表示されると言うものですが、 実際は先にhereの文字が表示されてしまいます。 また、不思議なことにDoEventsを二つ連続でMsgBoxの前に入れると きちんと動きます。 (ステップ実行でもきちんと動きます。) 最終的には、もっと長いプログラムの中で使う予定なので、 全てのEnabled文の後にDoEventsを二連続で書くという対症療法以外で、 良い解決方法が無いか、お教えいただけると幸いです。 なお、環境はwindowsXP、excel2003です。 よろしくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • piyo2000
  • ベストアンサー率49% (144/293)
回答No.1

>良い解決方法が無いか、お教えいただけると幸いです。 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は状態を変える前と後で発行してもうまく行きます。

sirakura3
質問者

お礼

ご回答、ありがとうございます。 自分でも散々調べたのですが、理由がわからず困っておりました。 しかし、piyo2000様の明快な回答を拝見させていただき、スッキリいたしました! また、作業を関数にして解決する案、目から鱗が落ちた感じです。 こういう解決方法があったんですね。大変参考になりました。 本当にありがとうございました。

その他の回答 (1)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

CommandButtonなどはUserFormで使うことが前提のためのように思います ご質問と同様のことをUserForm上で実現すると Enabledを変更した後にDoEventsを一度実行すればMsgBoxを表示する前に状態は変化するようです Worksheet上の場合は2度の実行が必要なようですが …

sirakura3
質問者

お礼

ご回答ありがとうございます。 恥ずかしながらCommandButtonなどはUserFormで使うと言う前提も知らずに 使っておりました。 勉強になります。 しかし、worksheet上の場合は二回実行しないと動かないと言うのも、 面白いものですね。困ったときのDoEventsと言う感じですね。 ありがとうございました。

関連するQ&A