- ベストアンサー
ExcelのToggleButtonを排他的に使う方法
- ExcelのVBAを使用してToggleButtonを排他的に使う方法を教えてください。
- ワークシート上にToggleButton1~3があり、各ボタンを押すと異なる処理が行われます。しかし、現在のコードでは排他的な動作がうまく働いていません。Excel2007とWindows7を使用しています。改善策を教えてください。
- ToggleButton1を押すと処理A、ToggleButton2を押すと処理B、ToggleButton3を押すと処理Cが行われるようにしたいのですが、現在のコードでは必ずしも排他的に動作しません。Excel2007とWindows7で動作する改善策を教えてください。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
Application.EnableEventsで 制御できないんじゃないかな … わたしなら モジュールレベルの変数として dim toggle, bFlag を定義 ボタンの制御プロシージャを定義 Sub ClickProc(ctl as Object) ' フラグが Trueなら そのまま戻る if bFlag then Exit Sub if IsEmpty(toggle) then toggle = Array(ToggleButton1, ToggleButton2, ToggleButton3) end if Dim ss as String bFlag = True ss = "処理Z" select case ctl.Name case "ToggleButton1" if ctl.Value then ss = "処理A" toggle(1).Value = False toggle(2).Value = False case "ToggleButton2" if ctl.Value then ss = "処理B" toggle(0).Value = False toggle(2).Value = False case "ToggleButton3" if ctl.Value then ss = "処理C" toggle(0).Value = False toggle(1).Value = False End Select 処理 ss ' 処理終了のためフラグをFalseに bFlag = False End Sub 各トグルボタンのクリックを Sub ToggleButton1_Click() ClickProc ToggleButton1 End Sub Sub ToggleButton2_Click() ClickProc ToggleButton2 End Sub Sub ToggleButton3_Click() ClickProc ToggleButton3 End Sub といったぐあいで …
その他の回答 (3)
- noname157639
- ベストアンサー率6% (2/32)
EnableEventsはOn,Offの操作でするのがよさそうですね。noname#157639
お礼
こんばんは。 ご助言ありがとうございました。
- WindFaller
- ベストアンサー率57% (465/803)
こんにちは。 >Application.EnableEventsで 制御できないんじゃないかな … 「排他的動作の際には,TrueなToggleButton#の動作をおこなってしまいます。」 というコメントから発想を考えたわけです。他の方法もありますが、一般的には、再帰的なイベントをEnableEventsはOn・Offで操作するのが定番のはずです。 #2さんのテクニック的には、面白いのですが、結果的には、再帰的に、別のActiveX Control オブジェクトに戻ってきてしまいますね。ActiveX Control オブジェクトが大量のある場合に、それでも同じだと言えるのかどうか、試してみないので、これは、答えようがありません。ただ、私は、それを嫌って解除しようとしたわけです。元のご質問をどのように解釈しているのかもよりますが……。
お礼
こんばんは。 定番ってところにWindFaller様の凄さが伺えました。 他の場面でも活用したいと思います。 ありがとうございました♪
- WindFaller
- ベストアンサー率57% (465/803)
こんにちは。 >ToggleButton1だけ相対的に処理速度が速いです これ自体は、私の環境では実現できません。ほぼ同じでしたから、実際は、もっと数が多いのではないでしょうか。もしくは、バッファに入っていることぐらいでしょうか。 今のスタイルで、ActiveX コントロールで使う分には、しょうがないという所だと思います。 ご質問は、関係のない所のトグルボタンは、Call 処理(strCode)に飛ばないようにするということと同じ意味ではありませんか? 他にも方法としては、数が多い場合に、コードを全部インスタンスに換えて、クラスで設定すれば、イベントの発生した部分を特定化できるはずです。 とりあえず、これで、イベントのオンオフをしてやればどうでしょうか。 Application.EnableEvents = False Application.EnableEvents = True '// Private Sub ToggleButton1_Click() Application.EnableEvents = False '全てのトグルボタンのコードに、これを入れて、 If ToggleButton1.Value = False Then strCode = "処理中Z" ' Debug.Print "AからZに戻します。" Else strCode = "処理中A" ' Debug.Print "Aを押しました。" ToggleButton2.Value = False '←ここにイベント発生源 ToggleButton3.Value = False '← 〃 End If 'Debug.Print "Aでの処理をします。" Call 処理(strCode) 'Debug.Print "Aから処理をしました。" End Sub Sub 処理(strCode) Dim i As Long Dim Start As Single Dim Finish As Single Start = timer '中略 Cells(3, 1).Value = Format$(Int((Finish - Start) * 10 ^ 4 + 0.5) / 10 ^ 4) Application.EnableEvents = True 'ここで戻す End Sub '//
お礼
こんばんは♪ おまけの方なのですが,画面更新する状態で動作を確認しておりました。 トグルボタンを初めて使用したのですが,ワークシート上に上・中・下とボタン配置をしました。 なんとなくボタン配置を変えた所,一番上(垂直方向)にあるボタンの動作が速い事が解りました。 「中ボタンの上辺」が少しでも「上ボタンの下辺」に重なると両方とも遅くなる。(水平方向にずれていても) 画面更新をしない状態にすると,全て同程度で速い動作になりました。 パソコンの環境かも知れませんがご報告までに。。。 誠にありがとう御座いました♪
補足
あけましておめでとうございます。 御返答が遅れてすみません。 質問したコードに誤りがありました。 >strCode = "処理中A" >ToggleButton2.Value = False >ToggleButton3.Value = False ↓ ToggleButton2.Value = False ToggleButton3.Value = False strCode = "処理中A" >>ToggleButton1だけ相対的に処理速度が速いです > これ自体は、私の環境では実現できません。ほぼ同じでしたから、実際は、もっと数が多いのではないでしょうか。もしくは、バッファに入っていることぐらいでしょうか。 上記修正したコードでi=1000になるまで,トグルボタン1のON/OFFで約0.3秒 トグルボタン2,3のON/OFFで約1.5秒です。 (サンプルというよりも、この状態で停滞しております。。。) ちなみに,パソコンのスペックは以下です。 プロセッサ:Intel Core2Duo P8700@2.53GHz,RAM:2.00GB >ご質問は、関係のない所のトグルボタンは、Call 処理(strCode)に飛ばないようにするということと同じ意味ではありませんか? 現状ですと,ToggleButton1(ON)状態でToggleButton2(ON)にすると,ToggleButton1(OFF)の処理を行った後ToggleButton2(ON)の処理を行ってしまっています。 A→Z→B を A→B としたいのです。そして,ON/OFFではA→Zとしたいのです。 WindFaller様,noname157639様ご両名とも「Application.EnableEvents」に着目して頂いておりますが,質問の要領がよくなかった様ですみませんでした。(意図は汲み取って頂けていたとは思いますが。。。)
お礼
こんばんは♪ お礼が遅れてすみません。 callは省略できるのがわかりました!!! 制限がある様でいまひとつ難解でしたが,希望通り良いぐあいです(^^) 誠にありがとうございました♪
補足
かなり開けてしまいましたが,あけましておめでとうございます♪ お礼が遅れましてすみません。 コードをみると,直接打ち込んでいらっしゃるのでしょうか。すごいです♪ Private SubとSubの違いが解っていないといいましょうか,ボタンを作ってコードを表示させると 必ずPrivate Subなので,「Sub」でもいいのですね。。。 WindFaller様はテクニカルで面白いとの事ですが,私にはなんとも言えない程解らない所で御座います。 もう少し教えて頂きたいのですが・・・ 1.ボタンに登録しているClickProc ToggleButton#は,ClickProc(ctl as Object)とどの様に関係しているのでしょうか? 2.ss = "処理Z" ,処理 ss ・・・ssに文字列の"処理Z"を入れて,最後に「処理 ss」を行う。 この「処理 ss」というのは,どういったぐわいで使えばよろしいのでしょうか?? 3.トグルボタンは5つ使用予定ですので,toggle = Arrayに1~5, toggle(#).Valueに0~4で良いでしょうか。。。 自助努力が足りなくてすみませんが,宜しくご教示下さい。