Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 783
Greg Lovern Avatar asked Apr 21 '17 17:04

Greg Lovern


People also ask

How do you check if Excel is refreshed?

Go to the Data tab on the Excel ribbon > Queries & Connections. This will open a pane on the right-hand side that shows the queries and any with errors will have a caution sign. Thank you Treacy!

How do I refresh a connection only query?

A connection only query will not refresh unless there is another query that is dependent on it. If you want to refresh it, you must change it to output to the workbook or to the power pivot data model. Select an appropriate destination for your query results.

How do I get power query to refresh automatically?

Automatically refresh data at regular intervalsSelect Data > Queries & Connections > Connections tab, right click a query in the list, and then select Properties. Click the Usage tab. Select the Refresh every check box, and then enter the number of minutes between each refresh operation.

How do you refresh a connection in VBA?

You can also press Ctrl+Alt+F5 anywhere in the workbook. This command not only refreshes data connections, it also refreshes all pivot tables (which are a form of data connection).


2 Answers

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.

like image 52
Mathieu Guindon Avatar answered Sep 28 '22 09:09

Mathieu Guindon


Just found this solution at Execute code after a data connection is refreshed

The bottom line is: Excel refreshes data connection in the background and thus the rest of the code is executed without interruption.

Solution: set BackgroundQuery property to False

Example:

For Each cnct In ThisWorkbook.Connections
   cnct.ODBCConnection.BackgroundQuery = False
Next cnct

Possible problem: don't know which connection it is...

Remedy: case... when...

Dim cnct as WorkbookConnection ' if option explicit
' ODBC and OLE DB
For Each cnct In ThisWorkbook.Connections
   Select case cnct.type
      case xlconnectiontypeodbc
   cnct.ODBCConnection.BackgroundQuery = False
      case xlconnectiontypeoledb
    cnct.OledbConnection.BackgroundQuery = False
   end select
Next cnct

As you can see, code above only deals with ODBC and OLE DB. Depending on what types of data connection you are using, you can expand the select case clause. Unless changed, once run, connection's BackgroundQuery will remain off.

like image 24
Donald Li Avatar answered Sep 28 '22 09:09

Donald Li