vba - Refresh All 没有触发 QueryTable 的 BeforeRefresh 事件 - 为什么?

标签 vba excel events triggers

如标题所述:我发现单击功能区上的“全部刷新”按钮不会触发 QueryTable 的 BeforeRefresh 事件。为什么会这样呢?有没有办法改变这种行为?

奇怪的是,同一个 QueryTable 的 AfterRefresh 事件被完美触发!

为了分析此行为,我在两个工作表中创建了两个表:

  1. 简单的、未链接的表,称为Source
  2. 名为Destination的表链接到Source表。连接是使用 Microsoft Query 和 Excel 文件作为数据源创建的。

然后,我创建了 TestClass,如下所示:

Option Explicit

Private WithEvents qt As QueryTable

Public Sub Init(pQt As QueryTable)
    Set qt = pQt
End Sub

Private Sub qt_BeforeRefresh(Cancel As Boolean)
    MsgBox "BeforeRefresh"
End Sub

Private Sub qt_AfterRefresh(ByVal Success As Boolean)
    MsgBox "AfterRefresh"
End Sub

最后,我创建、初始化并存储了 TestClass 的实例。

右键单击Destination 表并选择“刷新”可得到预期结果:MsgBox 显示两次,确认触发了刷新前和刷新后事件。

但是,单击功能区上的“全部刷新”会导致仅显示一个 MsgBox:AfterRefresh 一个。

我准备了一个最小的 Excel 文件来重现所描述的行为。可以在这里下载:RefreshAllNotTriggeringBeforeRefresh.xlsm

编辑 1:响应 Rik Sportel's question关于如何创建和初始化 TestClass 实例。

这是 ThisWorkbook 对象的相关部分:

Option Explicit

Private Destination As New TestClass

Private Sub Workbook_Open()
    Destination.Init WS_Destination.ListObjects("Destination").QueryTable
End Sub

其中 WS_Destination 是包含 Destination 表的工作表的 (Name) 属性的值。

正如人们所看到的,Destination 是一个私有(private)字段,但垃圾收集器似乎并不关心:我可以右键单击刷新Destination 表多次,并且 Before- 和 After- MsgBoxes 总是弹出。然而,“Refresh All”从不(甚至一次)不会触发 BeforeRefresh 事件,但总是触发 AfterRefresh 事件。

最佳答案

Option Explicit
Public tc as TestClass
Sub Test()
    Set tc = New TestClass
    tc.Init Worksheets("SomeSheet").ListObjects(1).QueryTable
End Sub
  • BeforeRefresh 仅在您使用表格选项卡 Excel GUI 中的刷新选项时才会触发。当您使用此事件时,两个事件都会适当触发。
  • 当您使用 Excel GUI 的查询选项卡中的刷新选项时,只会触发第二个事件。

原因是,在使用查询刷新选项时,QueryTable没有触发此 BeforeRefresh 事件,因为您实际上并未刷新 QueryTable 本身,而是刷新基础查询。

  • BeforeRefresh 事件在查询表刷新之前发生。 Here
  • AfterRefresh 事件在查询完成或取消后发生。 Here

当你这样做时:

Option Explicit
Public tc as TestClass
Sub Test()
    Set tc = New TestClass
    tc.Init Worksheets("SomeSheet").ListObjects(1).QueryTable
    Worksheets("SomeSheet").ListObjects(1).QueryTable.Refresh
End Sub

您将看到这两个事件都正确触发。

编辑: RefreshAll 实际上刷新工作簿中的查询,而不是查询表。同样的答案也适用。

简而言之:它的行为符合预期。

关于vba - Refresh All 没有触发 QueryTable 的 BeforeRefresh 事件 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44531126/

相关文章:

ios - 如何拦截obj-c中的应用程序更新事件?

events - 如何从 Java EE 应用程序发送事件(推送通知)?

vba - 使用 VBA 的离线人员的 Lync 通知

excel - 如果其他单元格包含特定文本,则将特定单元格的总和放入单元格中

vba - ByRef 参数类型不匹配 VBA 讨论

excel - 使用10 ^创建函数的UDF问题

vba - Worksheet_BeforeDoubleClick 进行选择

excel - "For"循环不删除工作表中的所有图表

当任务计划程序设置为 "Run whether user logged on or not"时 VBA 失败

excel - 向 Excel 调查提交(响应)的电子邮件通知