title: Excel VBA QueryTable callback function after table refresh
body: <p>I am writing/maintaining an Excel VBA application where there are multiple QueryTables linked to MS sql server databases. Users of the application can alter the SQL query to each table by manipulating various UI controls on the Excel document. </p>
  
  <p>One of the issues I have come across with QueryTables is there use of multi threading. Each QueryTable on the document has an original state that must be restored after a query is ran. For instance, if QueryTable1 had a base query of</p>
  
  <pre><code>Select * from example_table
  </code></pre>
  
  <p>and the user selected certain inputs on the controls to create</p>
  
  <pre><code>Select * from example_table Where object_oid = '10'
  </code></pre>
  
  <p>I would need the original state to be restored. The code below is a snapshot of how I am currently accomplishing this</p>
  
  <pre><code>Sub RefreshDataQuery()
  'Dependencies: Microsoft Scripting Runtime (Tools-&gt;References) for Dictionary (HashTable) object
  
  Dim querySheet As Worksheet
  Dim interface As Worksheet
  
  Set querySheet = Worksheets("QTable")
  Set interface = Worksheets("Interface")
  
  Dim sh As Worksheet
  Dim qt As QueryTable
  Dim qtDict As New Scripting.Dictionary
  
  Set qtDict = UtilFunctions.CollectAllQueryTablesToDict
  
  Set qt = qtDict.Item("Query from fred2")
  
  ''' Building SQL Query String '''
  Dim sqlQueryString As String
  Dim originalQueryCache As String
  originalQueryCache = qt.CommandText
  sqlQueryString = qt.CommandText
  
  QueryBuilder.BuildSQLQueryStringFromInterface interface, sqlQueryString
  
  MsgBox sqlQueryString
  
  qt.CommandText = sqlQueryString
  
  If Not qt Is Nothing Then
      qt.Refresh
  Else
      'Error Messages and handling here
      ' Cut out to keep code short
  End If
  
  
  ''' CLEAN UP '''
  
  'Restore the original base SQL query
  ' Problem is here
  ' This, or any other altering statement, will error out if the query is still refreshing
  qt.CommandText = originalQueryCache
  ' Other original state restoring code below...
  
  ' Free the dictionary
  Set qtDict = Nothing
  
  
  End Sub
  </code></pre>
  
  <p>Ideally, if I was writing this in another modern language, I would create a callback function or run the refresh in my own thread with a completion notifier. I spent a good chunk of time researching how to get a callback function for the qt.Refresh call, but am having no luck. I realize I could 'hack' around this a bit but I would prefer to not engage in bad practices as many people will have to maintain this in the future. </p>
  
  <p>This application must support Excel 2010 versions and upward</p>
  
  <p>So how can I create a callback function for VBA functions that are run in separate threads? Or, should I be looking at another approach?</p>