Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(指定なし : 指定なし)
トグルボタンをフレーム内で唯一選択する
投稿日時: 21/02/15 12:43:33
投稿者: takodo

いつもお世話になります。
件名について、下記「Private Sub tglSelect()」のようなコードで実行しています。
フレーム名は flm並び替え
トグルボタンは名は tBtn回数順、tBtn日付順、tBtn点数順 の3つを配置しています。
実行は、
Private Sub tBtn回数順_Click()
    Call tglSelect
End Sub
などとして呼び出しています。
 
ここで、質問です。
トグルボタンをクリックしなくて、クリックしたと同じような処理を行いたいです。
そこで、次のようにしてみました。
    Me.ActiveControl = Me.flm並び替え  '*1
    Me.flm並び替え.Tag = "tBtn回数順"
    Me.tBtn回数順.Value = True
    Me.tBtnAI級順.Value = False
    Me.tBtnMy級順.Value = False
    Me.flm並び替え.SetFocus
    Call tBtn回数順_Click
すると、
*1のところで
「型が一致しません」
と、いうエラーが発生します。
トグルボタンをクリックしなくて、クリックしたと同じような処理を行うにはどうしたらよいでしょうか?
よろしくお願いいたします。
 
Option Explicit
Dim flgEvent As Boolean
Private Sub tglSelect()
    If flgEvent Then Exit Sub
    flgEvent = True
     
    Dim frm As MSForms.Frame
    Set frm = Me.ActiveControl
    Dim tgl As MSForms.ToggleButton
    Set tgl = frm.ActiveControl
     
    If tgl.Value Then
        If frm.Tag <> "" Then
            If frm.Tag <> tgl.Name Then
                Me.Controls(frm.Tag).Value = False
            End If
        End If
        frm.Tag = tgl.Name
    Else
        tgl.Value = True
    End If
  
    flgEvent = False
End Sub

回答
投稿日時: 21/02/15 13:42:57
投稿者: K.Hiwasa
投稿者のウェブサイトに移動

ActiveControlプロパティは読み取り専用ですので設定はできません。
代わりにSetFocusを使用しました。
 

'    Me.ActiveControl = Me.flm並び替え
    Me.flm並び替え.SetFocus
    Me.flm並び替え.Tag = "tBtn回数順"
    Me.tBtn回数順.Value = True         '…@
    Me.tBtn日付順.Value = False
    Me.tBtn点数順.Value = False
    Me.flm並び替え.SetFocus
    Call tBtn回数順_Click

ちなみに上記のコードでは、tBtn回数順_Clickが2回動くようです。
ChangeイベントではなくClickイベントですが、@のときに動きました。

回答
投稿日時: 21/02/15 15:05:27
投稿者: Suzu

ご質問の内容と、提示頂いたコードとの相関関係が理解できません。
 
トグルボタン 3つの Click時 に、それぞれ、Call tglSelect を 記載していると思われ、
Private Sub tglSelect()
 の内容は、 提示いただいているコードです。
 
これで、標題の 「トグルボタンをフレーム内で唯一選択する」 は実現できるはずです。
 
 
判らないのが、

    Me.ActiveControl = Me.flm並び替え  '*1
    Me.flm並び替え.Tag = "tBtn回数順"
    Me.tBtn回数順.Value = True
    Me.tBtnAI級順.Value = False
    Me.tBtnMy級順.Value = False
    Me.flm並び替え.SetFocus
    Call tBtn回数順_Click

が出てきています。
 
これは、何のコードですか?説明にない、コントロール名も出てきていますし。。
 
引用:
クリックしなくて、クリックしたと同じような処理

この説明も、説明になっていません。

回答
投稿日時: 21/02/15 15:09:42
投稿者: Suzu

ユーザーフォームですよね?
ユーザーフォームのクラスモジュールにて
 

Option Explicit

Dim flgEvent As Boolean
Private Sub tglSelect()
    If flgEvent Then Exit Sub
    flgEvent = True
     
    Dim frm As MSForms.Frame
    Set frm = Me.ActiveControl
    
    Dim tgl As MSForms.ToggleButton
    Set tgl = frm.ActiveControl
     
    If tgl.Value Then
        If frm.Tag <> "" Then
            If frm.Tag <> tgl.Name Then
                Me.Controls(frm.Tag).Value = False
            End If
        End If
        frm.Tag = tgl.Name
    Else
        tgl.Value = True
    End If
  
    flgEvent = False
End Sub

Private Sub tBtn回数順_Click()
    Call tglSelect
End Sub

Private Sub tBtn点数順_Click()
    Call tglSelect
End Sub

Private Sub tBtn日付順_Click()
    Call tglSelect
End Sub

 
Excel2013 にて、フレーム内のトグルボタン 1つだけ選択した状態 の動作確認を取りました。

回答
投稿日時: 21/02/15 23:02:57
投稿者: WinArrow
投稿者のウェブサイトに移動

>トグルボタンをクリックしなくて、クリックしたと同じような処理を行いたいです。
 
どんな時に・・・・という説明が抜けている。

引用:

    Me.ActiveControl = Me.flm並び替え  ★
    Me.flm並び替え.Tag = "tBtn回数順"
     Me.tBtn回数順.Value = True
     Me.tBtnAI級順.Value = False
     Me.tBtnMy級順.Value = False
     Me.flm並び替え.SetFocus    ★
     Call tBtn回数順_Click   ★

↑のコードは、ユーザーフォーム表示した時と考えてよいのかな?
 
だとすると実行順序を変更して
Userform_Ativateイベントの記述します。
     Me.tBtnAI級順.Value = False
     Me.tBtnMy級順.Value = False
    Me.flm並び替え.Tag = "tBtn回数順"
     Me.tBtn回数順.Value = True
★は不要
 

投稿日時: 21/02/16 09:21:37
投稿者: takodo

K.Hiwasa さんの引用:
ActiveControlプロパティは読み取り専用ですので設定はできません。
代わりにSetFocusを使用しました。
 
'    Me.ActiveControl = Me.flm並び替え
    Me.flm並び替え.SetFocus
    Me.flm並び替え.Tag = "tBtn回数順"
    Me.tBtn回数順.Value = True         '…@
    Me.tBtn日付順.Value = False
    Me.tBtn点数順.Value = False
    Me.flm並び替え.SetFocus
    'Call tBtn回数順_Click

ちなみに上記のコードでは、tBtn回数順_Clickが2回動くようです。
ChangeイベントではなくClickイベントですが、@のときに動きました。

早速のお返事ありがとうございます。
動きました。
Call tBtn回数順_Click
が不要なのが不思議です。★
>tBtn回数順_Clickが2回動くようです。
順番を変えて
    Me.tBtn日付順.Value = False
    Me.tBtn点数順.Value = False
    Me.tBtn回数順.Value = True '…@
としたら、Clickイベントが一度だけ実行されました。
これも不思議です。★
まずは、問題は解決しました。
ありがとうございました。
上記二つの★についての回答が寄せられればと思い「解決済みにする」
は、少し待ちたいと思います。
 

投稿日時: 21/02/16 09:26:27
投稿者: takodo

WinArrow さんの引用:
>トグルボタンをクリックしなくて、クリックしたと同じような処理を行いたいです。
 
どんな時に・・・・という説明が抜けている。
引用:

    Me.ActiveControl = Me.flm並び替え  ★
    Me.flm並び替え.Tag = "tBtn回数順"
     Me.tBtn回数順.Value = True
     Me.tBtnAI級順.Value = False
     Me.tBtnMy級順.Value = False
     Me.flm並び替え.SetFocus    ★
     Call tBtn回数順_Click   ★

↑のコードは、ユーザーフォーム表示した時と考えてよいのかな?
 
だとすると実行順序を変更して
Userform_Ativateイベントの記述します。
     Me.tBtnAI級順.Value = False
     Me.tBtnMy級順.Value = False
    Me.flm並び替え.Tag = "tBtn回数順"
     Me.tBtn回数順.Value = True
★は不要
 

丁寧な回答をありがとうございます。
     Me.flm並び替え.SetFocus    ★
これがないと、
当初のとおり
*1のところで
「型が一致しません」
のエラーが出てしまいました。
     Me.flm並び替え.SetFocus    ★
を記載することにより、目的の動きをしました。
ありがとうございました。

投稿日時: 21/02/16 09:29:54
投稿者: takodo

Suzu さんの引用:
ご質問の内容と、提示頂いたコードとの相関関係が理解できません。
これは、何のコードですか?説明にない、コントロール名も出てきていますし。。
引用:
クリックしなくて、クリックしたと同じような処理

この説明も、説明になっていません。

わかりにくい質問にもかかわらず
>Excel2013 にて、フレーム内のトグルボタン 1つだけ選択した状態 の動作確認を取りました。
など、
丁寧な回答をおよせいただきありがとうございました。

回答
投稿日時: 21/02/16 10:55:19
投稿者: WinArrow
投稿者のウェブサイトに移動

引用:
これがないと、
 当初のとおり
*1のところで
「型が一致しません」
のエラーが出てしまいました。

 
なにか、勘違いしていませんか?
>*1のところ
って何?
なんで、*1の行が出てくるんですか?

回答
投稿日時: 21/02/16 10:57:46
投稿者: WinArrow
投稿者のウェブサイトに移動

参考までに当方のテストコードを掲示します。
 

Private Sub ToggleButton1_Click()
    Call seltgl
End Sub

Private Sub UserForm_Activate()
     Me.ToggleButton3.Value = False
     Me.ToggleButton2.Value = False
     Me.ToggleButton1.Value = True
End Sub


Private Sub seltgl()
Dim frm As MSForms.Frame
Dim tgl As MSForms.ToggleButton

    Set frm = Me.ActiveControl
    Set tgl = frm.ActiveControl
    
    MsgBox tgl.Value
End Sub

回答
投稿日時: 21/02/16 13:23:38
投稿者: WinArrow
投稿者のウェブサイトに移動

トグルボタン_Clickイベントは
ONでもOFFでも発生します。
また、敢えて、フレームをアクティブにする必要もありません。
 
ユーザーフォームが開いたときに
1番目のトグルボタンをONにすること

自トグルボタンをONにしたときに、他のトグルボタンをOFFにすること
を別々に考えることが必要です。
 

回答
投稿日時: 21/02/16 13:41:28
投稿者: WinArrow
投稿者のウェブサイトに移動

参考コードを紹介します。
 
テスト用のブックを作成し、動作確認をしてから
実際のマクロに組み込んでださい。
 

Option Explicit
Private myEnableEvent As Boolean

Private Sub ToggleButton1_Click()
    If myEnableEvent Then Exit Sub
    If Me.ToggleButton1.Value Then
        myEnableEvent = True
        Call settgl(tgl:=Me.ToggleButton1)
        myEnableEvent = False
    End If
    Call seltgl
End Sub

Private Sub ToggleButton2_Click()
    If myEnableEvent Then Exit Sub
    If Me.ToggleButton2.Value Then
        myEnableEvent = True
        Call settgl(tgl:=Me.ToggleButton2)
        myEnableEvent = False
    End If
    Call seltgl
End Sub

Private Sub ToggleButton3_Click()
    If myEnableEvent Then Exit Sub
    If Me.ToggleButton3.Value Then
        myEnableEvent = True
        Call settgl(tgl:=Me.ToggleButton3)
        myEnableEvent = False
    End If
    Call seltgl
End Sub

Private Sub UserForm_Activate()
    Me.ToggleButton1.Value = True
End Sub

Private Sub settgl(ByRef tgl As MSForms.ToggleButton)
Dim ctrl As MSForms.Control
    For Each ctrl In Me.Controls
        If TypeName(ctrl) = "ToggleButton" Then
            If ctrl.Name <> tgl.Name Then
                ctrl.Value = False
            End If
        End If
    Next
End Sub

Private Sub seltgl()
Dim frm As MSForms.Frame
Dim tgl As MSForms.ToggleButton

    Set frm = Me.ActiveControl
    Set tgl = frm.ActiveControl
    
    Me.Label1.Caption = tgl.Name & "  " & tgl.Value
End Sub

回答
投稿日時: 21/02/16 17:49:07
投稿者: K.Hiwasa
投稿者のウェブサイトに移動

ちょっと調査しました。
トグルボタンは値を変更すると、Changeイベントの後、Clickイベントが発生するようです。
チェックボックスも同様。
オプションボタンはちょっと違って、
値をTrueに変更したときは他と同様で、Falseに変更したときはChangeイベントのみでした。

投稿日時: 21/02/17 06:18:18
投稿者: takodo

WinArrow さんの引用:
トグルボタン_Clickイベントは
ONでもOFFでも発生します。
また、敢えて、フレームをアクティブにする必要もありません。

K.Hiwasa さんの引用:
ちょっと調査しました。
トグルボタンは値を変更すると、Changeイベントの後、Clickイベントが発生するようです。
チェックボックスも同様。
オプションボタンはちょっと違って、
値をTrueに変更したときは他と同様で、Falseに変更したときはChangeイベントのみでした。

わかりやすく教えていただきありがとうございます。
また、テスト用のコードも提示していただき、エクセルVBAについてまた少し理解が深まったような気がします。
どうもありがとうございました。