
師も走りまわる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だけ相対的に処理速度が速いです・・・。
なぜなんでしょう??
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
といったぐあいで …
この回答への補足
かなり開けてしまいましたが,あけましておめでとうございます♪
お礼が遅れましてすみません。
コードをみると,直接打ち込んでいらっしゃるのでしょうか。すごいです♪
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で良いでしょうか。。。
自助努力が足りなくてすみませんが,宜しくご教示下さい。
こんばんは♪
お礼が遅れてすみません。
callは省略できるのがわかりました!!!
制限がある様でいまひとつ難解でしたが,希望通り良いぐあいです(^^)
誠にありがとうございました♪
No.4
- 回答日時:
EnableEventsはOn,Offの操作でするのがよさそうですね。
noname#157639No.3
- 回答日時:
こんにちは。
>Application.EnableEventsで 制御できないんじゃないかな …
「排他的動作の際には,TrueなToggleButton#の動作をおこなってしまいます。」
というコメントから発想を考えたわけです。他の方法もありますが、一般的には、再帰的なイベントをEnableEventsはOn・Offで操作するのが定番のはずです。
#2さんのテクニック的には、面白いのですが、結果的には、再帰的に、別のActiveX Control オブジェクトに戻ってきてしまいますね。ActiveX Control オブジェクトが大量のある場合に、それでも同じだと言えるのかどうか、試してみないので、これは、答えようがありません。ただ、私は、それを嫌って解除しようとしたわけです。元のご質問をどのように解釈しているのかもよりますが……。
こんばんは。
定番ってところに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
'//
この回答への補足
あけましておめでとうございます。
御返答が遅れてすみません。
質問したコードに誤りがありました。
>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」に着目して頂いておりますが,質問の要領がよくなかった様ですみませんでした。(意図は汲み取って頂けていたとは思いますが。。。)
こんばんは♪
おまけの方なのですが,画面更新する状態で動作を確認しておりました。
トグルボタンを初めて使用したのですが,ワークシート上に上・中・下とボタン配置をしました。
なんとなくボタン配置を変えた所,一番上(垂直方向)にあるボタンの動作が速い事が解りました。
「中ボタンの上辺」が少しでも「上ボタンの下辺」に重なると両方とも遅くなる。(水平方向にずれていても)
画面更新をしない状態にすると,全て同程度で速い動作になりました。
パソコンの環境かも知れませんがご報告までに。。。
誠にありがとう御座いました♪
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Visual Basic(VBA) VBA 参照先で選んだファイルをコピーし、出力先に別名で保存したい 8 2022/05/13 20:37
- Visual Basic(VBA) 動きっぱなしです。止め方とプロシージャの間違いを教えて下さい! 5 2022/08/15 23:08
- Excel(エクセル) B列に文字がはいったらA列に数字が入るマクロードを完成させたい 4 2023/04/21 01:58
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) 前回ご教授いただいたコードに覚えたてのループ処理で品名りんごAから順に20回for nextでループ 7 2023/01/13 22:01
- Excel(エクセル) VBAについて 3 2022/06/19 18:19
- Visual Basic(VBA) VBA 別ブックからの転記の高速化について VBA 別ブックからの転記の高速化についてご教授下さい。 19 2022/07/26 13:07
- Visual Basic(VBA) ユーザーフォーム「frm_基本❶」を立ち上げると新規で入力する行数を右下のNoとして表示しています。 1 2023/03/16 19:02
- Visual Basic(VBA) いつもお世話になっております、VBAで教えて頂きたいのですが 2 2022/05/05 22:20
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VB.NET DataGridViewでIsNewRo...
-
エクセルで、日付を入力すると...
-
「ご処理進めて頂きますようお...
-
銀行の窓口処理の件で知ってる...
-
switch の範囲指定
-
VBAでループ内で使う変数名を可...
-
DoEventsがやはり分からない
-
UMLでの例外処理
-
EXCEL VBA マクロ 実行する度に...
-
vba 空のデータをSplitする時の...
-
VBAでCOPYを繰り返すと、処理が...
-
【Excel】特定の文字を含むセル...
-
EXCEL2003 VBAで2つのDBに接続...
-
内部処理形式ってなんですか
-
ハードウェア処理とソフトウェ...
-
VBの質問#if 0 then ってどう...
-
VBAでセルに値が入力されるまで...
-
メルカリのメルカードで買い物...
-
Excel VBAにて2つの処理を同時...
-
月度は何て読みますか?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「ご処理進めて頂きますようお...
-
エクセルで、日付を入力すると...
-
VBAでループ内で使う変数名を可...
-
【Excel】特定の文字を含むセル...
-
switch の範囲指定
-
EXCEL VBA マクロ 実行する度に...
-
UMLでの例外処理
-
DoEventsがやはり分からない
-
月度は何て読みますか?
-
お家デートをしててハグを長い...
-
VB.NET Excelを読み込んでDataT...
-
VBの質問#if 0 then ってどう...
-
Do~Loopした回数をカウントしたい
-
VBAでCOPYを繰り返すと、処理が...
-
メルカリのメルカードで買い物...
-
インタラクティブの反対語は?
-
Loadイベント中にほかのイベン...
-
リョウ・・・量?料?
-
vba 空のデータをSplitする時の...
-
findは動くがfindnextがマクロ...
おすすめ情報