沢山のチェックボックス ③ チェックボックスがクリックされたことを検知してみる

一昨日来、ユーザーフォームに配置された沢山のチェックボックスの中から、一つだけチェックする方法の簡素化に取り組んでいる。
infoment.hatenablog.com

今日も、昨日の続きから。
f:id:Infoment:20200527222803j:plain

昨日までの方法では、どう頑張ってみても、CheckBoxの数だけクリックイベントが必要になる。CheckBoxが100個あったら、クリックイベントも100個必要だ。

そこで、考え方を以下の手順に変えてみる。

  1. とにかくCheckBoxの何れかがクリックされたことを検知する。
  2. クリックされたCheckBoxの値がTrueのとき、それ以外のチェックを外す。

このために、クラスモジュールを一つ準備した。

クラスモジュール(Class1)
Private WithEvents myCheckBox As MSforms.CheckBox

Private Sub myCheckBox_Click()
    Dim CBx As Variant
        ' クリックによりチェックが外れたのなら、そこで終了。
        If myCheckBox.Value = False Then Exit Sub
        
        ' 各CheckBoxについて、クリックされたCheckBoxとキャプションが
        ' 異なる場合のみチェックを外す。
        For Each CBx In UserForm1.Controls
            If TypeName(CBx) = "CheckBox" Then
                Select Case CBx.Caption
                    Case myCheckBox.Caption
                    Case Else
                        CBx.Value = False
                End Select
            End If
        Next
End Sub

Sub SetCheckBox(ChkBox As MSforms.CheckBox)
    Set myCheckBox = ChkBox
End Sub

またUserForm側については、CheckBoxの配置もマクロで行ってみた。

f:id:Infoment:20200527223633p:plain

UserForm1
Dim col As Collection
Dim cls As Class1

Private Sub UserForm_Initialize()
    Dim i As Long
    Dim myCheckBox As MSforms.CheckBox
    
    Dim str As String
        str = "子丑寅卯辰巳午未申酉戌亥"

    Set col = New Collection
    For i = 1 To 12
        Set myCheckBox = Me.Controls.Add("Forms.CheckBox.1", _
                                               "CheckBox" & i, True)
        With myCheckBox
            .Left = 10
            .Top = 10 + (i - 1) * 30
            .Caption = Mid(str, i, 1)
        End With
        
        Set cls = New Class1
            cls.SetCheckBox myCheckBox
            col.Add cls
    Next
End Sub

結果は、以下の通り。
f:id:Infoment:20200527223913g:plain

何もなかったユーザーフォームに、CheckBoxが12個配置された。ちゃんと、一個しか選べないようになっている。これなら、12個でも100個でも、コードの長さは変わらない(ユーザーフォームの長さは変わるけど)。

明日に続きます。

参考まで。