Excel VBA复选框单击和更改事件相同吗?

Posted

技术标签:

【中文标题】Excel VBA复选框单击和更改事件相同吗?【英文标题】:Excel VBA checkbox click and change events the same? 【发布时间】:2013-08-10 02:19:18 【问题描述】:

我有 5 个复选框来设置宏的一些选项,其中一个是全选/取消全选复选框。当您选择要删除或标记为已读等的邮件时,我想创建类似于您在基于 Web 的邮箱中所拥有的内容。 当我选中 Select/Unselect All 复选框时,我将其余复选框的值设置为 true,反之亦然。没关系。

当我还想验证是否所有内容都未选中并且我一个一个地选中其他复选框时,问题就出现了,如果最后我选中了所有复选框,那么 Select/Unselect All 复选框将变为选中状态。反之亦然,这意味着如果所有内容都被选中,然后我取消选中其他四个中的一个,那么我将“全部”复选框设置为 false(未选中)。

但似乎即使我只是设置了值,例如 Option1Checkbox.value = True,在 SelectAllCheckbox_Click 事件中,它也会触发 Option1Checkbox_Click 和 Option1Checkbox_Change 事件。

难道不应该只是触发 Change 事件,因为我实际上并没有点击该复选框吗?

发生的情况是我选中了 SelectAll,因此它会将 Option1 变为选中,但是通过这样做,Option1 也会触发 click 事件,因此它取消选中它会再次触发 click 事件,然后再次取消选中 All 复选框中的end 不检查一切,就像在开始时一样。希望这部分足够清楚。

如何避免这种行为?如何确保只触发 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

这很简单,我看到的最大问题是当复选框没有实际点击时对点击事件的调用。

感谢您的帮助。

【问题讨论】:

+1 我刚刚在 Excel 中设计用户表单时遇到了同样的问题。 在更改复选框值之前,我尝试使用 Application.EnableEvents = False 禁用事件,但它仍然触发了 Click 事件。不知道为什么....? 【参考方案1】:

如果 Option1 到 Option4 都在 If 语句中检查,我会编写一个子检查。在第二个 if 语句中,我会检查它们是否都是错误的:

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 事件结束时为复选框调用这个子。

【讨论】:

【参考方案2】:

我会定义一个局部变量(在 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

【讨论】:

谢谢大家的建议。即使您自己不单击它,问题仍然是 Click 事件的触发。所以 ImChangingStuff 似乎没有解决问题,因为在 Option1Checkbox_Click 事件中,假设 ImChangingStuff 为假(因为您没有单击 SelectAll,所以它继续,当行 SelectAll.Value = True 或 false 时,评估,然后即使我没有实际点击它也会触发 SelectAll_Click 事件。 我不明白为什么总是同时触发 Click 和 Change 事件。我认为更改复选框值时会触发 Change 事件,但不会触发 Click 事件。如果我真的点击了复选框,那么我知道两者都被触发了。【参考方案3】:

为了解决这个问题,

    在您的主用户窗体(在本例中称为 Mainform)中添加以下代码:

    私有子 Mainform_Initialize() stateCheckbox = 真 结束子

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

    公共状态复选框为布尔值

    在复选框的 _click 事件中,将代码包装成这样:

    如果 stateCheckbox = false 那么 无论你的代码是什么 别的: 状态复选框 = 假 结束如果

【讨论】:

【参考方案4】:

我遇到了与上述相同的问题。我认识到,复选框的每次更改,无论是通过单击还是通过更改 Checkbox.Value,每次首先触发 Checkbox_Change 事件,然后触发 Checkbox_Click 事件,前提是声明了这些事件中的任何一个。 因此,我建议为每个复选框只使用一个事件,p.e. 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    

【讨论】:

以上是关于Excel VBA复选框单击和更改事件相同吗?的主要内容,如果未能解决你的问题,请参考以下文章

在excel VBA中单击listbox_click()后如何检索复选框的复选框

如何使用 VBA 从 Excel 用户窗体中读取复选框的值

jQuery复选框的更改和单击事件之间的区别

更改 Excel 表单复选框名称

是否可以在 Excel VBA 中返回复选框的名称?

Excel VBA用户表单使用复选框将数据输入多行