I have an Excel workbook that fires three queries to a database to populate three tables on hidden sheets, and then runs three \'refresh\' scripts to pull this data through
I can give you an answer that will help you some of the time, but not all the time.
Sometimes your Recordset.Open or your Command.Execute ignores the AdAsynchFetch parameter.
That is to say: the problem manifests immediately, when you are requesting, and it's not an issue with the application in an unresponsive state when ADODB calls back with a populated recordset.
Fortunately, this is something you can trap in the code; and there are three things that occur when AdFetchAsynch is ignored:
ExecuteComplete event is never raised. You can see where I'm going with this...
If your recordset-requesting code detects an open recordset before it exits, pass the open recordset straight into your existing _FetchComplete event procedure:
Set m_rst = New ADODB.Recordset ' declared at module level With Events
With m_rst
Set .ActiveConnection = ThisWorkbook.MyDBConnection
.CursorType = adOpenForwardOnly
Err.Clear
.Open SQL, , , , adCmdText + adAsyncFetch
End With
If m_rst.State = adStateOpen Then
' This block will only run if the adAsyncFetch flag is ignored
If m_rst.EOF And m_rst.BOF Then
MsgPopup "No matching data for " & DATASET_NAME, vbExclamation + vbOKOnly, "Empty data set", 90
ElseIf m_rst.EOF Then
m_rst.MoveFirst
m_rst_FetchComplete Nothing, GetStatus(m_rst), m_rst
Else
m_rst_FetchComplete Nothing, GetStatus(m_rst), m_rst
End If
Set m_rst = Nothing
ElseIf m_rst.ActiveConnection.Errors.Count > 0 Then
m_rst_FetchComplete m_rst.ActiveConnection.Errors(0), adStatusErrorsOccurred, m_rst
Set m_rst = Nothing
ElseIf Err.Number <> 0 Then
MsgPopup "Microsoft Excel returned error &H" & Hex(Err.Number) & ": " & Err.Description, vbCritical + vbOKOnly, "Error requesting " & DATASET_NAME, 60
Set m_rst = Nothing
ElseIf m_rst.State < adStateOpen Then
MsgPopup "Microsoft Excel was unable to request data for " & DATASET_NAME & ": no error information is available", vbCritical + vbOKOnly, "Error requesting " & DATASET_NAME, 60
Set m_rst = Nothing
Else
' Fetch progess is not available with the OLEDB driver I am using
' m_rst_FetchProgress 0, 100, GetStatus(m_rst), m_rst
End If
Obviously this is going to be useless if the _FetchComplete event is never raised: 'open' runs asynchronously and the method exits with a recordset in state adStateConnecting or adStateFetching and you're totally reliant on the m_rst_FetchComplete event procedure.
But this fixes the issue some of the time.
Next: you need to check that Application.EnableEvents is never set to false when you might have a recordset request out in the ether. I'm guessing that you've thought of that, but it's the only other thing that I can think of.
Also:
A tip for readers who are new to ADODB coding: consider using adCmdStoredProc and calling your saved query or your recordset-returning function by name instead of using 'SELECT * FROM' and adCmdText.
A late answer here, but other people will encounter the same problem.