
コマンドボタンの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です。
よろしくお願いいたします。
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は状態を変える前と後で発行してもうまく行きます。
ご回答、ありがとうございます。
自分でも散々調べたのですが、理由がわからず困っておりました。
しかし、piyo2000様の明快な回答を拝見させていただき、スッキリいたしました!
また、作業を関数にして解決する案、目から鱗が落ちた感じです。
こういう解決方法があったんですね。大変参考になりました。
本当にありがとうございました。
No.2
- 回答日時:
CommandButtonなどはUserFormで使うことが前提のためのように思います
ご質問と同様のことをUserForm上で実現すると
Enabledを変更した後にDoEventsを一度実行すればMsgBoxを表示する前に状態は変化するようです
Worksheet上の場合は2度の実行が必要なようですが …
ご回答ありがとうございます。
恥ずかしながらCommandButtonなどはUserFormで使うと言う前提も知らずに
使っておりました。
勉強になります。
しかし、worksheet上の場合は二回実行しないと動かないと言うのも、
面白いものですね。困ったときのDoEventsと言う感じですね。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
マンガでよめる痔のこと・薬のこと
「痔かもしれない」と思っているあなたに
-
VBA シートのボタン名を変更したい
Visual Basic(VBA)
-
エクセルVBAでオプションボタンを無効にする方法
Excel(エクセル)
-
Excel-VBA>コントロールをグレイアウトするには?
Excel(エクセル)
-
4
【Excel VBA】マクロでExcel自体を終了させたい
Excel(エクセル)
-
5
'Range'メソッドは失敗しました
Excel(エクセル)
-
6
エクセルのラベルの値(文字列)を垂直方向で中央揃えにするには?
Excel(エクセル)
-
7
VBAでブックを非表示で開いて処理して閉じる方法
Excel(エクセル)
-
8
EXCEL-VBAでコマンドボタンに条件を追加したい
Visual Basic(VBA)
-
9
Excel VBA コンボボックスの初期値の設定について
Excel(エクセル)
-
10
エクセルVBAでOptionButtonのオンオフ取得
Excel(エクセル)
-
11
Sub ***( ) と Private Sub ***( ) の違い
Visual Basic(VBA)
-
12
動的配列が存在(要素が有る)か否かを判定できますか?
Visual Basic(VBA)
-
13
メッセージボックスに表示する文字を大きくしたい
Excel(エクセル)
-
14
【Excel VBA】セルの値が変更されたらマクロを実行
その他(Microsoft Office)
-
15
CommandButtonのCaptionを変化させたい
Visual Basic(VBA)
-
16
エクセルのエラーメッセージ「400」って?
Visual Basic(VBA)
-
17
VBA 実行時エラー1004 rangeメソッドは失敗しました。globalオブジェクトのエラー
Excel(エクセル)
-
18
EXCEL VBAのユーザーフォームに引数を渡す方法について
Excel(エクセル)
-
19
VBAでユーザーフォームの表示を確認
Visual Basic(VBA)
-
20
Range(A1")⇔cells(1,1)の変換。"
Excel(エクセル)
関連するQ&A
- 1 Excel VBA Internet Explore コントロールのオートメーション操作でFrame内のボタンを押したい
- 2 Excel VBA コマンドボタン
- 3 エクセルVBA:全部のコマンドボタンに反映させる方法。
- 4 EXCEL VBA:IEの操作であるラジオボタンを選択する方法
- 5 Excel VBA: 自動でxlsファイルを開くマクロでメッセージが現れたとき自動でボタンを押す方法
- 6 コマンドボタンでコマンドボタンを作成
- 7 EXECEL VBA コマンドボタンからのモジュール呼び出し
- 8 [Excel VBA]コマンドボタンの入力待ち方法
- 9 複数のコマンドボタン(VBAで)を一つにまとめたい。
- 10 【EXCEL VBA】Range("A:A").Find(What:="キーワード")の1行目について
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
人気Q&Aランキング
-
4
vb.netでテキストボックス内の...
-
5
VB 6.0 PictureBox のプロパテ...
-
6
panelのスクロール表示について
-
7
Labelの文字をスクロールする際...
-
8
Visual Studio.Netで株価チャー...
-
9
花火のアルゴリズム
-
10
VB2010のChartで、何本もの線を...
-
11
.net chartでの積層棒グラフの...
-
12
VB.NETでグラフィックを描くと...
-
13
VB.NETでPictureBoxへの描画に...
-
14
VBAでpng画像に文字列を描画す...
-
15
Form1 Load で実行されない。
-
16
Excel VBA:コントロールボタン...
-
17
図の削除直後の再描画
-
18
フロートチャートをVBAで表すには
-
19
OpenOffice Calcで株価チャート...
-
20
グラフの交点の求め方(Excel)
おすすめ情報