The QueryTable
object exposes two events: BeforeRefresh
and AfterRefresh
.
You need to change your paradigm from procedural/imperative to event-driven.
Say you have this code in ThisWorkbook
(won't work in a standard procedural code module, because WithEvents
can only be in a class):
Option Explicit
Private WithEvents table As Excel.QueryTable
Private currentIndex As Long
Private tables As Variant
Private Sub table_AfterRefresh(ByVal Success As Boolean)
Debug.Print table.WorkbookConnection.Name & " refreshed. (success: " & Success & ")"
currentIndex = currentIndex + 1
If Success And currentIndex <= UBound(tables) Then
Set table = tables(currentIndex)
table.Refresh
End If
End Sub
Public Sub Test()
tables = Array(Sheet1.ListObjects(1).QueryTable, Sheet2.ListObjects(1).QueryTable)
currentIndex = 0
Set table = tables(currentIndex)
table.Refresh
End Sub
The tables
variable contains an array of QueryTable
objects, ordered in the order you wish to refresh them; the currentIndex
variable points to the index in that array, for the QueryTable
you want to act upon.
So when Test
runs, we initialize the tables
array with the QueryTable
objects we want to refresh, in the order we want to refresh them.
The implicit, event-driven loop begins when table.Refresh
is called and the QueryTable
fires its AfterRefresh
event: then we report success, and update the event-provider table
object reference with the next QueryTable
in the array (only if the refresh was successful), and call its Refresh
method, which will fire AfterRefresh
again, until the entire array has been traversed or one of them failed to update.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…