我遇到了一个竞争条件问题,我有两个QueryTables,每个QueryTables都有自己的AfterRefresh事件。每个AfterRefresh事件都会进行一些copy'n'pasting以及进行一些计算。
现在,当用户单击Excel中的全部刷新(Ctrl+Alt+F5)
时,我希望每个AfterRefresh处理程序都能执行,但只有在所有QueryTable刷新完全完成后才能执行。
我在StackOverFlow和someone suggested
上进行了搜索Activeworkbook.RefreshAll
DoEvents
但是,假设我们以编程方式触发RereshAll。就我而言,全部刷新是通过Excel中内置的全部刷新(Ctrl+Alt+F5)
按钮完成的。因此,我没有看到我可以在我的情况下插入DoEvents
(除非我创建自己的全部刷新按钮,但我想避免这样做)。
我试图搜索“Excel VBA互斥锁”,但我没有找到任何特别的东西。那么在每个AfterRefresh处理程序发生之前,如何确保完成所有刷新?
感谢阅读!
更新:为了帮助调试..这是我的VBA代码。
我有一个名为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
我还有一个名为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
由于竞争条件,只有一个AfterRefresh处理程序在copy'n'pasting中成功..另一个在我再次单击Refresh All按钮(Ctrl+Alt+F5)
之后不起作用。