刷新所有不触发QueryTable的BeforeRefresh事件 – 为什么?

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

奇怪的是,完全相同的QueryTable的AfterRefresh事件触发完成!

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

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

然后,我创build了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 

最后,我创build,初始化并存储了一个TestClass的实例。

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

但是,单击function区上的“全部刷新”将只显示一个MsgBox:AfterRefresh一个。

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

编辑1 :回应Rik Sportel关于如何创build和初始化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是一个私有字段,但似乎垃圾收集器并不在意:我可以右键单击刷新Destination表多次,并且总是popupBefore和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只有在使用Table选项卡Excel GUI中的刷新选项时才会触发。 当你使用这个事件时,两个事件都会适当地触发。
  • 在Excel GUI的“ 查询”选项卡中使用刷新选项时,只会触发第二个事件。

原因是QueryTable 没有使用Query刷新选项时触发的这个BeforeRefresh事件,是因为你实际上没有刷新QueryTable本身,而是底层的Query。

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

当你这样做时:

 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实际刷新工作簿中的查询,而不是查询表。 同样的答案适用。

总之:它的行为如预期。