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.
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
Select * from example_table
and the user selected certain inputs on the controls to create
Select * from example_table Where object_oid = '10'
I would need the original state to be restored. The code below is a snapshot of how I am currently accomplishing this
Sub RefreshDataQuery()
'Dependencies: Microsoft Scripting Runtime (Tools->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
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.
This application must support Excel 2010 versions and upward
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?