Userform OptionButtons 在两个方向上独占
Userform OptionButtons exclusive in two directions
我有一个用户表单,其中的按钮在列和行中组织得像 table。我只想为每一列和每一行激活一个按钮。
现在它适用于所有按钮都是选项按钮和同一帧中一行的所有选项按钮。
然后对于列,我开始为每个按钮编写一个子类型:
Private Sub Col1Row3_Click()
For i = 1 To 2
Me.Controls("col1Row" & i) = False
Next i
For i = 4 To 14
Me.Controls("col1Row" & i) = False
Next i
End Sub
它有效,但我相信还有更优雅的方法。有什么想法吗 ?
谢谢!
简单子程序
试图通过
演示一种简单的方法来简化与您的方法保持接近的代码
- 使用子程序
- 循环将所有选项按钮设置为 False,最后将活动按钮再次设置为 True。
Sub Only(ByVal rowNum As Long, ByVal colName As String, Optional ByVal maxRow As Long = 14)
' Purpose: set all OptionButtons to False except the one for row rowNum
Dim currRow As Long
For currRow = 1 To maxRow
Me.Controls(colName & "Row" & currRow) = False
Next
Me.Controls(colName & "Row" & rowNum) = True
End Sub
避免复杂循环的调用示例[=30=]
Private Sub col1Row3_Click()
Only 3, "col1"
End Sub
进一步提示
与其为每个选项按钮重复过程调用,不如从 class 编程 (~> WithEvents
) 中获益。如需更深入的了解,您可能会感兴趣,例如在 VBA Control arrays 中,如果你想将在 class.
中共享相同名称类型和相同事件过程的控件分组
所以,在 T.M 的帮助下回答我的问题,以防它可以帮助其他人(或者以防万一有人提出更清洁的建议)。
我发现了两种可能性:
如果控件是选项按钮,则每列和每行只允许一个选择:
- 每一行或每一列都在一个框架中,让我们说这个例子的行
- 有一个 class 控件作为 属性 和一个 control_click 作为方法。该方法检查列的所有控件(如果 controls.name 的类型为 "Name" & 变量 & numcolumn,或者由于 属性 列的数量,则按名称找到列)。
所有类型的控件的一般情况,他妈的,我没想到会在单击即可进行任何更改的复选框上遇到那么多麻烦。
- 有一个 class 控件作为 属性 和 control_click 作为方法。该方法检查所有行和列,这要归功于 属性 的 class Arr(控制行,控制列)的数组,或者仅感谢名称为 [=39= 的控件] & 行 & 列
名为 CheckBoxRxCy 的复选框示例(即 CheckBoxR01C01)
在模块中(我使用定义来声明所有内容)
Public ClickCtrl As Boolean 'the boolean which prevents the checkbox from going crazy
在 class ClassForExclusives 中(classe 在修改复选框时处理事件)
Public WithEvents ControlExcl As MSForms.CheckBox 'the control with events enabled
Private Sub ControlExcl_Click()
If ClickCtrl = False Then 'inhibits reaction to value change
GoTo line1
Else
For Each control2 In UserForm1.Controls
If control2.Name <> ControlExcl.Name Then 'avoid setting the tickbox xhanged to false
If Right(control2.Name, 2) = Right(ControlExcl.Name, 2) Or Mid(control2.Name, 10, 2) _
= Mid(ControlExcl.Name, 10, 2) Then 'same row/col
ClickCtrl = False
control2.Value = False
End If
End If
ClickCtrl = True 'allows the clicks to trigger the code again
Next control2
End If
line1:
End Sub
在用户表单中
Dim ArrControls() As New ClassForExclusives 'Set the array with the controls as ClassForExclusives
Private Sub UserForm_Initialize()
ClickCtrl = True
For Each Chkbox In Me.Controls
If TypeOf Chkbox Is MSForms.CheckBox Then
i = i + 1
ReDim Preserve ArrControls(1 To i)
Set ArrControls(i).ControlExcl = Chkbox
End If
Next Chkbox
End Sub
我有一个用户表单,其中的按钮在列和行中组织得像 table。我只想为每一列和每一行激活一个按钮。 现在它适用于所有按钮都是选项按钮和同一帧中一行的所有选项按钮。 然后对于列,我开始为每个按钮编写一个子类型:
Private Sub Col1Row3_Click()
For i = 1 To 2
Me.Controls("col1Row" & i) = False
Next i
For i = 4 To 14
Me.Controls("col1Row" & i) = False
Next i
End Sub
它有效,但我相信还有更优雅的方法。有什么想法吗 ? 谢谢!
简单子程序
试图通过
演示一种简单的方法来简化与您的方法保持接近的代码- 使用子程序
- 循环将所有选项按钮设置为 False,最后将活动按钮再次设置为 True。
Sub Only(ByVal rowNum As Long, ByVal colName As String, Optional ByVal maxRow As Long = 14)
' Purpose: set all OptionButtons to False except the one for row rowNum
Dim currRow As Long
For currRow = 1 To maxRow
Me.Controls(colName & "Row" & currRow) = False
Next
Me.Controls(colName & "Row" & rowNum) = True
End Sub
避免复杂循环的调用示例[=30=]
Private Sub col1Row3_Click()
Only 3, "col1"
End Sub
进一步提示
与其为每个选项按钮重复过程调用,不如从 class 编程 (~> WithEvents
) 中获益。如需更深入的了解,您可能会感兴趣,例如在 VBA Control arrays 中,如果你想将在 class.
所以,在 T.M 的帮助下回答我的问题,以防它可以帮助其他人(或者以防万一有人提出更清洁的建议)。
我发现了两种可能性:
如果控件是选项按钮,则每列和每行只允许一个选择:
- 每一行或每一列都在一个框架中,让我们说这个例子的行
- 有一个 class 控件作为 属性 和一个 control_click 作为方法。该方法检查列的所有控件(如果 controls.name 的类型为 "Name" & 变量 & numcolumn,或者由于 属性 列的数量,则按名称找到列)。
所有类型的控件的一般情况,他妈的,我没想到会在单击即可进行任何更改的复选框上遇到那么多麻烦。
- 有一个 class 控件作为 属性 和 control_click 作为方法。该方法检查所有行和列,这要归功于 属性 的 class Arr(控制行,控制列)的数组,或者仅感谢名称为 [=39= 的控件] & 行 & 列
名为 CheckBoxRxCy 的复选框示例(即 CheckBoxR01C01)
在模块中(我使用定义来声明所有内容)
Public ClickCtrl As Boolean 'the boolean which prevents the checkbox from going crazy
在 class ClassForExclusives 中(classe 在修改复选框时处理事件)
Public WithEvents ControlExcl As MSForms.CheckBox 'the control with events enabled
Private Sub ControlExcl_Click()
If ClickCtrl = False Then 'inhibits reaction to value change
GoTo line1
Else
For Each control2 In UserForm1.Controls
If control2.Name <> ControlExcl.Name Then 'avoid setting the tickbox xhanged to false
If Right(control2.Name, 2) = Right(ControlExcl.Name, 2) Or Mid(control2.Name, 10, 2) _
= Mid(ControlExcl.Name, 10, 2) Then 'same row/col
ClickCtrl = False
control2.Value = False
End If
End If
ClickCtrl = True 'allows the clicks to trigger the code again
Next control2
End If
line1:
End Sub
在用户表单中
Dim ArrControls() As New ClassForExclusives 'Set the array with the controls as ClassForExclusives
Private Sub UserForm_Initialize()
ClickCtrl = True
For Each Chkbox In Me.Controls
If TypeOf Chkbox Is MSForms.CheckBox Then
i = i + 1
ReDim Preserve ArrControls(1 To i)
Set ArrControls(i).ControlExcl = Chkbox
End If
Next Chkbox
End Sub