我有5个复选框来设置宏的一些选项,其中一个是"全选/取消全选"复选框。当你选择要删除或标记为已读的邮件时,我想创建一些类似于你在基于网络的邮箱中所拥有的东西。当我选中Select/Unselect All复选框时,我会将复选框的其余值设置为true,反之亦然。没关系。
当我还想验证如果所有内容都未选中,并且我逐一选中其他复选框,如果最后我全部选中,那么"全选/取消全选"复选框将变为选中时,问题就来了。反之亦然,这意味着如果选中了每一项,然后我取消选中其他四项中的一项,那么我会将"全部"复选框设置为false(未选中)。
但似乎即使我只是在SelectAllCheckbox_Click事件中设置了值,例如Option1Checkbox.value=True,它也会触发Option1Checkbox_Click和Option1Checkbox _Change事件。
因为我实际上并没有点击那个复选框,所以它不应该触发Change事件吗?
发生的情况是,我选中了SelectAll,因此它将Option1变为选中,但通过这样做,Option1也会触发点击事件,因此它会取消选中它,再次触发点击事件。然后再次取消选中All复选框,最后会像开始时一样,取消选中所有复选框。希望这部分足够清楚。
如何避免这种行为?如何确保只触发Change事件而不触发Click事件?
有没有人有过这样的复选框安排,也遇到过类似的问题?或者,如果没有我现在的行为,你是如何做到这一点的?
复选框不在表单上,而只是在工作表上。它们是ActiveX控件。我所拥有的并不复杂:
Private Sub SelectAll_Click()
Option1Checkbox.Value = SelectAll.Value
Option2Checkbox.Value = SelectAll.Value
Option3Checkbox.Value = SelectAll.Value
Option4Checkbox.Value = SelectAll.Value
End Sub
然后选项复选框单击事件如下所示:
Private Sub Option1Checkbox_Click()
If Option1Checkbox.Value = True And Option2Checkbox.Value = True And Option3Checkbox.Value = True And Option4Checkbox.Value = True Then
SelectAll.Value = True
Else
SelectAll.Value = False
End If
End Sub
这很简单,我看到的最大问题是当复选框实际上没有被点击时,对点击事件的调用。
谢谢你的帮助。
我会定义一个局部变量(在subs之外定义的变量),并设置/检查
Option Explicit
Dim ImChangingStuff As Boolean
Private Sub SelectAll_Click()
ImChangingStuff = True
Option1Checkbox.Value = SelectAll.Value
Option2Checkbox.Value = SelectAll.Value
Option3Checkbox.Value = SelectAll.Value
Option4Checkbox.Value = SelectAll.Value
ImChangingStuff = False
End Sub
那么你的点击程序会是这样的:
Private Sub Option1Checkbox_Click()
If ImChangingStuff Then Exit Sub
If Option1Checkbox.Value = True And Option2Checkbox.Value = True And Option3Checkbox.Value = True And Option4Checkbox.Value = True Then
SelectAll.Value = True
Else
SelectAll.Value = False
End If
End Sub
为了解决这个问题,
-
在您的主用户表单(在本例中称为Mainform)中添加以下代码:
私有子主窗体初始化()stateCheckbox=真结束子
-
创建一个模块来存储全局变量(例如
globalVariables
),并添加以下内容,这些内容将保存复选框的状态:公共状态复选框为布尔
-
在复选框的_click事件中,将代码包装如下:
如果stateCheckbox=false,则{无论您的代码是什么}其他:stateCheckbox=false如果结束
我遇到了与上述相同的问题。我认识到,每次更改复选框,无论是通过单击还是通过更改Checkbox.Value
,每次都会首先触发Checkbox_Change
事件,然后再触发Checkbox_Click
事件,前提是声明了这些事件中的任何一个。因此,我建议每个复选框只使用一个事件,例如Checkbox_Change
事件,并检查复选框是否已通过单击或在Sub
开头声明进行了更改。这可以通过比较ActiveControl.Name
和Checkbox.Name
:来实现
Private Sub CheckBox1_Change()
On Error Goto Err:
If ActiveControl.Name = CheckBox1.Name Then
On Error Goto 0
'Commands for click
Exit Sub
Else
On Error Goto 0
'Commands for change from within the Userform
Exit Sub
Err:On Error Goto 0
'Commands for change from outside the Userform
End Sub
如果在if语句中检查了Option1到Option4,我会写一个子检查。如果是statemement,我会在一秒钟内检查它们是否都是假的:
Sub Are_O1_to_O4_All_Checked ()
If Option1Checkbox.Value = True And _
Option2Checkbox.Value = True And _
Option3Checkbox.Value = True And _
Option4Checkbox.Value = True Then
Option5Checkbox.Value = True ' select/unselect checkbox
End If
If Option1Checkbox.Value = False And _
Option2Checkbox.Value = False And _
Option3Checkbox.Value = False And _
Option4Checkbox.Value = False Then
Option5Checkbox.Value = False ' select/unselect checkbox
End If
结束子
然后,我会在每个复选框的OnClick事件结束时调用此子。