師も走りまわる12月。。皆様(師)も走りまわっていることでしょう。
私は。。。走りません、はい。
本題です。
ExcelのVBAでToggleButtonを排他的に使いたいのです。
調べるとオプションボタンになさいと書かれてはいるのですが・・・。
ワークシート上にToggleButton1~3があります。
1を押す(凹)と“処理A”,もう一度押す(凸)と“処理Z”
2 同上 “処理B”, 同上
3 同上 “処理C”, 同上
以下のコードでなんとなく動くのですが,排他的動作の際には,TrueなToggleButton#の動作をおこなってしまいます。
Excel2007,Windows7です。
師の皆様の良い御提案が御座いましたら御教示下さい。
----ボタンがあるシートモジュールに記載----------------------------------------
Option Explicit
Dim strCode As Variant
Private Sub ToggleButton1_Click()
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
Private Sub ToggleButton2_Click()
If ToggleButton2.Value = False Then
strCode = "処理中Z"
' Debug.Print "BからZに戻します。"
Else
strCode = "処理中B"
' Debug.Print "Bを押しました。"
ToggleButton1.Value = False
ToggleButton3.Value = False
End If
'Debug.Print "Bでの処理をします。"
Call 処理(strCode)
'Debug.Print "Bから処理をしました。"
End Sub
Private Sub ToggleButton3_Click()
If ToggleButton3.Value = False Then
strCode = "処理中Z"
Else
strCode = "処理中C"
ToggleButton1.Value = False
ToggleButton2.Value = False
End If
Call 処理(strCode)
End Sub
Sub 処理(strCode)
Dim i As Long
Dim Start As Single
Dim Finish As Single
Start = timer
i = 0
'Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For i = 1 To 1000
i = i + 1
Cells(2, 1).Value = strCode & i
Next i
Application.Calculation = xlCalculationAutomatic
'Application.ScreenUpdating = True
Cells(1, 1).Value = strCode
Finish = timer
Cells(3, 1).Value = Format$(Int((Finish - Start) * 10 ^ 4 + 0.5) / 10 ^ 4)
End Sub
---------------------------------------------------------------------------
おまけ:
上記サンプルを作ってみましたが,ToggleButton1だけ相対的に処理速度が速いです・・・。
なぜなんでしょう??
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
といったぐあいで …
お礼
こんばんは♪ お礼が遅れてすみません。 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で良いでしょうか。。。 自助努力が足りなくてすみませんが,宜しくご教示下さい。