Excel VBA复选框单击并更改事件



我有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

为了解决这个问题,

  1. 在您的主用户表单(在本例中称为Mainform)中添加以下代码:

    私有子主窗体初始化()stateCheckbox=真结束子

  2. 创建一个模块来存储全局变量(例如globalVariables),并添加以下内容,这些内容将保存复选框的状态:

    公共状态复选框为布尔

  3. 在复选框的_click事件中,将代码包装如下:

    如果stateCheckbox=false,则{无论您的代码是什么}其他:stateCheckbox=false如果结束

我遇到了与上述相同的问题。我认识到,每次更改复选框,无论是通过单击还是通过更改Checkbox.Value,每次都会首先触发Checkbox_Change事件,然后再触发Checkbox_Click事件,前提是声明了这些事件中的任何一个。因此,我建议每个复选框只使用一个事件,例如Checkbox_Change事件,并检查复选框是否已通过单击或在Sub开头声明进行了更改。这可以通过比较ActiveControl.NameCheckbox.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事件结束时调用此子。

最新更新