沢山のチェックボックス ① 繰り返し処理

先日職場で、あるものを見かけた。再現すると、こんな感じだ。
f:id:Infoment:20200525225356p:plain

コードを見てみると、こんなことが書いてあった。
f:id:Infoment:20200525225513p:plain

チェックボックスをクリックすると、その他のチェックボックスのチェックが外れる仕掛けだ。

ここでは10個に留めたが、実際は40個近いチェックボックスが配置され、その全てのクリックイベントが書き込まれていた。

こんなとき、どう振舞うのが正解なのだろう。特に、このツールが完成していて、問題なく動いているときは。

少なくとも、このコードを否定したりなど、余計なことを言うのは是非避けたい。

ということで、その方がもし改善を目的として検索するときのため、ここで段階的にこれを改善してみよう。

まず ↓ この部分。これを繰り返し処理で書いてみる。

Private Sub CheckBox1_Click()
    If CheckBox1.Value = True Then
        CheckBox2.Value = False
        CheckBox3.Value = False
        CheckBox4.Value = False
        CheckBox5.Value = False
        CheckBox6.Value = False
        CheckBox7.Value = False
        CheckBox8.Value = False
        CheckBox9.Value = False
        CheckBox10.Value = False
    End If
End Sub

例えばCheckBox1は、こう書くことができる。

Me.Controls("CheckBox" & 1)

Meとはこの場合、チェックボックスが配置されたユーザーフォームを指す。
結果、このようになる。

Private Sub CheckBox1_Click()
    If Me.Controls("CheckBox" & 1).Value = True Then
        Me.Controls("CheckBox" & 2).Value = False
        Me.Controls("CheckBox" & 3).Value = False
        Me.Controls("CheckBox" & 4).Value = False
        Me.Controls("CheckBox" & 5).Value = False
        Me.Controls("CheckBox" & 6).Value = False
        Me.Controls("CheckBox" & 7).Value = False
        Me.Controls("CheckBox" & 8).Value = False
        Me.Controls("CheckBox" & 9).Value = False
        Me.Controls("CheckBox" & 10).Value = False
    End If
End Sub

さっきより字数が増えている。しかし御覧のとおり、CheckBoxの番号が&で結合されているため、これを変数に置き換えることが可能になった。こんな感じだ。

Private Sub CheckBox1_Click()
    Dim i As Long
    If Me.Controls("CheckBox" & 1).Value = True Then
        For i = 2 To 10
            Me.Controls("CheckBox" & i).Value = False
        Next
    End If
End Sub

切り替え部分を共通化すると、さらに簡素化出来る。

Sub SwichCheckBox(checkbox_number As Long)
    Dim i As Long
        If Me.Controls("CheckBox" & checkbox_number) = False Then
            Exit Sub
        End If
        
        For i = 1 To 10
            Select Case i
                Case checkbox_number
                    Me.Controls("CheckBox" & i) = True
                Case Else
                    Me.Controls("CheckBox" & i) = False
            End Select
        Next
End Sub

Private Sub CheckBox1_Click()
    SwichCheckBox 1
End Sub

Private Sub CheckBox2_Click()
    SwichCheckBox 2
End Sub

Private Sub CheckBox3_Click()
    SwichCheckBox 3
End Sub

' 以降、省略。

最初より、ずっと短くなった。

明日に続きます。

参考まで。