I am running into a race condition issue where I have two QueryTables, each is hooked with its own AfterRefresh event. Each AfterRefresh event does some copy'n'pasting as well as doing some calculations.
Now, when the user click Refresh All (Ctrl+Alt+F5) in Excel, I would love to have each AfterRefresh handler to execute, but ONLY after all QueryTable refreshes are entirely completed.
I did a search on StackOverFlow, and someone suggested
Activeworkbook.RefreshAll
DoEvents
However, that's assuming that we are programmatically triggering the RereshAll. In my case, Refresh All is done by the built-in Refresh All (Ctrl+Alt+F5) button within Excel. Thus, I don't see where I can insert DoEvents in my case (unless I create my own Refresh All button, but I would like to avoid doing so).
I tried to search for "Excel VBA mutex", but I did not find anything in particular. So how do I make sure that all the refreshes are done, before each AfterRefresh handler takes place?
Thanks for reading!
Update: To help out with debugging.. here are my VBA codes.
I have a module named AutoOpen
Dim S As New DataCopy
Dim U As New DataCopy
Sub Auto_Open()
    Set S.qt = ThisWorkbook.Sheets(1).QueryTables(2)
    S.myWorkbookName = ThisWorkbook.Name
    S.sWorksheetProcessName = "ProcessS"
    S.sWorksheetDataColumnStart = 1
    S.sWorksheetDataColumnEnd = 5
    Set U.qt = ThisWorkbook.Sheets(1).QueryTables(1)
    U.myWorkbookName = ThisWorkbook.Name
    U.sWorksheetProcessName = "ProcessU"
    U.sWorksheetDataColumnStart = 6
    U.sWorksheetDataColumnEnd = 10
End Sub
I also have a Class module named DataCopy
Public WithEvents qt As QueryTable
Public myWorkbookName As String
Public sWorksheetProcessName As String
Public sWorksheetDataColumnStart As Integer
Public sWorksheetDataColumnEnd As Integer
Private Sub qt_AfterRefresh(ByVal Success As Boolean)
    DataCopier
End Sub
Private Sub DataCopier()
    'Debug.Print sWorksheetProcessName & "," & Application.CalculationState
    Dim LastNRows As Integer
    Dim sWorksheetDataName As String
    ' How many rows to copy
    LastNRows = 297
    sWorksheetDataName = "Data"
    Application.ScreenUpdating = False
    ' Clear content in process tab
    With Workbooks(myWorkbookName).Worksheets(sWorksheetProcessName)
        .Range(.Cells(4, 1), .Cells(.Cells(Rows.Count, 1).End(xlUp).Row, 6)).ClearContents
    End With
    ' Copy to process Tab
    With Workbooks(myWorkbookName).Worksheets(sWorksheetDataName)
        LastRow = .Cells(Rows.Count, 1).End(xlUp).Row
        FirstRow = LastRow - LastNRows
        If FirstRow < 2 Then
            FirstRow = 2
        End If
        .Range(.Cells(FirstRow, sWorksheetDataColumnStart), .Cells(LastRow, sWorksheetDataColumnEnd)).Copy _
             Destination:=Workbooks(myWorkbookName).Worksheets(sWorksheetProcessName).Range("A4")
    End With
    Debug.Print (sWorksheetProcessName & "," & sWorksheetDataColumnStart & "," & sWorksheetDataColumnEnd)
    Application.ScreenUpdating = True
End Sub
Because of the race condition, only one AfterRefresh handler succeeds in copy'n'pasting.. the other one doesn't work until I click Refresh All button (Ctrl+Alt+F5) again.  
