• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ExcelのToggleButtonを排他的に。。)

ExcelのToggleButtonを排他的に使う方法

このQ&Aのポイント
  • ExcelのVBAを使用してToggleButtonを排他的に使う方法を教えてください。
  • ワークシート上にToggleButton1~3があり、各ボタンを押すと異なる処理が行われます。しかし、現在のコードでは排他的な動作がうまく働いていません。Excel2007とWindows7を使用しています。改善策を教えてください。
  • ToggleButton1を押すと処理A、ToggleButton2を押すと処理B、ToggleButton3を押すと処理Cが行われるようにしたいのですが、現在のコードでは必ずしも排他的に動作しません。Excel2007とWindows7で動作する改善策を教えてください。

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

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

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 といったぐあいで …

mayu1992
質問者

お礼

こんばんは♪ お礼が遅れてすみません。 callは省略できるのがわかりました!!! 制限がある様でいまひとつ難解でしたが,希望通り良いぐあいです(^^) 誠にありがとうございました♪

mayu1992
質問者

補足

かなり開けてしまいましたが,あけましておめでとうございます♪ お礼が遅れましてすみません。 コードをみると,直接打ち込んでいらっしゃるのでしょうか。すごいです♪ 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で良いでしょうか。。。 自助努力が足りなくてすみませんが,宜しくご教示下さい。

その他の回答 (3)

回答No.4

EnableEventsはOn,Offの操作でするのがよさそうですね。noname#157639

mayu1992
質問者

お礼

こんばんは。 ご助言ありがとうございました。

回答No.3

こんにちは。 >Application.EnableEventsで 制御できないんじゃないかな … 「排他的動作の際には,TrueなToggleButton#の動作をおこなってしまいます。」 というコメントから発想を考えたわけです。他の方法もありますが、一般的には、再帰的なイベントをEnableEventsはOn・Offで操作するのが定番のはずです。 #2さんのテクニック的には、面白いのですが、結果的には、再帰的に、別のActiveX Control オブジェクトに戻ってきてしまいますね。ActiveX Control オブジェクトが大量のある場合に、それでも同じだと言えるのかどうか、試してみないので、これは、答えようがありません。ただ、私は、それを嫌って解除しようとしたわけです。元のご質問をどのように解釈しているのかもよりますが……。

mayu1992
質問者

お礼

こんばんは。 定番ってところにWindFaller様の凄さが伺えました。 他の場面でも活用したいと思います。 ありがとうございました♪

回答No.1

こんにちは。 >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 '//

mayu1992
質問者

お礼

こんばんは♪ おまけの方なのですが,画面更新する状態で動作を確認しておりました。 トグルボタンを初めて使用したのですが,ワークシート上に上・中・下とボタン配置をしました。 なんとなくボタン配置を変えた所,一番上(垂直方向)にあるボタンの動作が速い事が解りました。 「中ボタンの上辺」が少しでも「上ボタンの下辺」に重なると両方とも遅くなる。(水平方向にずれていても) 画面更新をしない状態にすると,全て同程度で速い動作になりました。 パソコンの環境かも知れませんがご報告までに。。。 誠にありがとう御座いました♪

mayu1992
質問者

補足

あけましておめでとうございます。 御返答が遅れてすみません。 質問したコードに誤りがありました。 >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」に着目して頂いておりますが,質問の要領がよくなかった様ですみませんでした。(意図は汲み取って頂けていたとは思いますが。。。)