Excel工作表事件(3)- Change事件连锁反应

161 篇文章 16 订阅
20 篇文章 2 订阅

Excel工作表Change事件是最常用的事件代码之一,通俗的讲工作表内容发生变化时,此事件将被激活。这个事件代码貌似很简单,事件被激活后,使用代码想干啥就干啥,然后呢 … 就没有然后了。

先了看一个很常见的需求,在第一行任意单元格输入任意内容后,在该单元格之下记录当前的日期,这个就是典型的Change事件应用,3行代码将搞定。

Private Sub Worksheet_Change(ByVal Target As Range)
    Target.Offset(1, 0) = Date
End Sub

在A1单元格随便输入一个字母,按回车结束输入,启动着B1单元格自动写入当前的日期,结果如何呢?
在这里插入图片描述
理想很丰满,现实很骨感。A2单元格确实记录了我们需要的当前日期,可是之下的几十个单元格在搞什么鬼,为什么也都被填充了同样的内容。
我们来分析一下事件代码的执行过程:

  • A1输入完成后,Change事件(第一次被激活,记作Change_1)被激活,执行第2行代码时修改A2单元格的值
  • 此时将Change事件将再次被激活(Change_2),此时Change_1的第3行代码尚未被执行,执行第2行代码时修改A3单元格的值
  • 此时将Change事件将再次被激活(Change_3)

如此继续下去,如果没有任何资源限制,理论上可以将第1列填满,但是实际上只填充到A79之后就结束了,并未给出任何错误(如果哪位高手知道原因,欢迎留言赐教),估计和递归调用的堆栈空间有关。

无论如何,在使用事件代码时,我们肯定不希望这样发生这样的连锁反应,解决方案也很简单,使用如下EnableEvents可以禁用系统事件的激活,注意不影响控件事件的激活,例如工作表中的按钮仍然可以正常响应Click事件。

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    Target.Offset(1, 0) = Date
    Application.EnableEvents = True
End Sub

需要注意在结束事件代码之前一定要恢复系统的事件激活机制,否者工作表内容的变化,将无法再激活事件代码。例如如下代码,只有用户输入的内容是数字,并且大于10的时候,才在其下一行单元格记录日期。

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If VBA.IsNumeric(Target.Value) And Target.Value > 10 Then
        Target.Offset(1, 0) = Date
        Application.EnableEvents = True
    End If
End Sub

如果输入内容不满足条件,那么第5行代码将不会执行,在此之后系统事件将被禁用。正确的事件代码如下:

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If VBA.IsNumeric(Target.Value) And Target.Value > 10 Then
        Target.Offset(1, 0) = Date
    End If
    Application.EnableEvents = True
End Sub
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值