有没有办法以编程方式清除 EXCEL VBA 事件队列?
在 EXCEL VBA 中,当更改工作表单元格然后用户按 ENTER 提交单元格编辑时,工作表级别会发生两个事件。他们是 :
• 私有子工作表_更改(ByVal 目标作为范围)
• 私有子工作表_SelectionChange(ByVal 目标作为范围)
不可避免地,这两个事件会被记录在一个队列中,并优先考虑Worksheet_Change,然后执行Worksheet_SelectionChange。由于单元格内容已更改,因此会触发 Change 事件。然后,由于用户按下 ENTER 键,将选择更改为已编辑单元格下的单元格,因此会触发 SelectionChange 事件。这两个步骤生成两个事件。
我编写了这段代码来捕获特定单元格中的更改,并且我需要完全避免以下事件 Worksheet_SelectionChange 在 Worksheet_Change 子终止后运行。这是因为在我的 SelectionChange sub 中还完成了其他重要工作,并且在修改单元格内容时它们不得进行干预。
当然,必须有一种方法来阻止 SelectionChange 的发生。我试图找到某种 VBA 函数来清空 Worksheet_Change 子项中的 EXCEL 事件队列列表。目前这似乎不存在。我还尝试使用 Application.EnableEvents = False,但这仅在两个事件都添加到队列后才会生效,这不会阻止等待的 SelectionChange 事件在 Change 事件之后执行。
问题:有没有办法以编程方式清除 EXCEL VBA 事件队列?
某种类似于 Application.ClearEventQueue 的函数,以防止执行任何后续未实现的事件。该函数可以在 Change 子函数中调用,并阻止执行任何进一步的等待事件。我们如何在VBA中实现这样的功能呢?
Dim NewLocation As Range
Private Sub Worksheet_Change(ByVal Target As Range)
Application.EnableEvents = False
Set NewLocation = Target.Offset(0, 1) ' At this location a work is written in the cell
NewLocation.Select ' Here the selection is changed and EXCEL trigger a third event, SelectionChange
Debug.Print "still in change event", NewLocation.Row, Target.Value
Application.EnableEvents = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Debug.Print "selectionchange event", Target.Row, Target.Value
End Sub
此代码将显示当用户在单元格中输入新值时,将发生 3 个事件。
- 首先是由以下行引起的 SelectionChange 事件:NewLocation.Select
- 第二个 Change 事件是因为用户更改了单元格并按了 ENTER
- 第三个由用户按 ENTER 键引起的 SelectionChange,因此焦点转到下面的单元格(只是暂时的,直到代码命令 NewLocation.Select。
我试图避免执行第三个 SelectionChange 。这是不可避免的,因为使用 Application.EnableEvents = False 只能在 EXCEL 捕获第一个 ENTER 步骤后生效。因此,当 EnagleEvents 设置为 OFF 时,只会发生两个事件。理想情况下,我会要求取消之前的 SelectionChange 事件。