Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
972 views
in Technique[技术] by (71.8m points)

vba - How to check whether Connection Refresh was successful

In Excel 2016 VBA, I'm refreshing several queries like this:

MyWorkbook.Connections(MyConnectionName).Refresh

After the code is done, and no errors are encountered, I see that the hourglass icons for most of the queries are still spinning for several seconds.

Is it possible to check for success AFTER all the refreshes are completed? I'm concerned that my code isn't going to know if an error happens after the code finishes but before the queries are done refreshing.

BTW I don't want to do a RefreshAll, because some of the queries are dependent on others (uses them as a source). I refresh them in a certain sequence so that dependent queries are refreshed after the queries they are dependent on.

UPDATE:

I see that the Connection objects have a read-only RefreshDate property, which at first glance looked like it could be used to do this check:

MyWorkbook.Connections(MyConnectionName).OLEDBConnection.RefreshDate

HOWEVER, it doesn't seem to be getting set. I get an error trying to check it. If I set a Variant variable to that RefreshDate property, the variable shows as "Empty". The source is a SQL server database.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...