如标题所述:我发现单击功能区上的“全部刷新”按钮不会触发QueryTable的BeforeRefresh事件。为什么会这样?有没有办法改变这种行为?
奇怪的是,完全触发了同一个QueryTable的AfterRefresh事件!
为了分析这种行为,我在两个工作表中创建了两个表:
Source
Destination
表关联的名为Source
的表。使用Microsoft Query和Excel Files作为数据源创建连接。然后,我按如下方式创建了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 one。
我准备了一个可以重现所描述行为的最小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
是包含(Name)
表的工作表的Destination
属性的值。
可以看出,Destination
是一个私有字段,但似乎垃圾收集器并不关心:我可以右键单击刷新Destination
表我想要的时间以及之前和之后的MsgBoxes 总是弹出。然而,刷新所有从不(甚至一次)触发BeforeRefresh事件,但总是触发AfterRefresh一个。
答案 0 :(得分:1)
Option Explicit
Public tc as TestClass
Sub Test()
Set tc = New TestClass
tc.Init Worksheets("SomeSheet").ListObjects(1).QueryTable
End Sub
原因是QueryTable 不在使用查询刷新选项时触发了此BeforeRefresh事件,原因是您实际上并未刷新QueryTable本身,而是基础查询。
当你这样做时:
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实际上刷新了工作簿中的查询,而不是查询表。同样的答案也适用。
简而言之:它的表现与预期一致。