我在 Excel Power Query (PQ) 中有 3 个查询,其中 1 个是外部查询,另外 2 个是从中派生的。我希望首先运行外部查询,然后依次运行其他查询。我遇到的困难是在查询完成后应用 VBA 代码,每个查询都同步完成并作为后台查询以防止 Excel 冻结。 VBA 的原因(如下所述)可能可以通过其他方式解决,因此我很乐意考虑替代方案。
查询有一些返回文本 =(公式) 的列(通过 PQ 中的 M)。我发现没有办法自动将文本作为公式返回,并且 PQ 在使用公式定义自定义列方面存在限制(例如,不允许使用 Excel 函数)。 VBA 代码用于控制查询的顺序(例如查询 1 完成后,触发事件以触发查询 2 等)并执行 .Formula = .Formula 来解决公式问题。
尝试过的解决方案以及失败原因:
Do Until OLEDBConnection.Refreshing = False
DoEvents
Loop
控制一个查询何时在下一个查询启动之前完成,有一个 Excel 错误,可能与 DoEvents 相关,该错误会阻止循环退出,除非我中断执行并单步执行/再次关闭它
Option Explicit
Dim sheetsToWatch as Collection
Dim delay as Double
'A button to kick it all off should call this subroutine
Sub ButtonRefresh_Click()
Application.DisplayAlerts = False
ActiveWorkbook.queries.FastCombine = True
ActiveWorkbook.RefreshAll
DoStuffWhenRefreshCompletes
End Sub
'Set sheetsToWatch and starts watching them
Sub DoStuffWhenRefreshCompletes()
Dim sht as Worksheet
Set sheetsToWatch = New Collection
For Each sht In ActiveWorkbook.Sheets
If (code to determine if this is a sheet to watch) Then
sheetsToWatch.Add Sgt
End If
Next sht
delay = TimeValue("00:00:03")
DoStuffWhenSheetsToWatchComplete
End Sub
Sub DoStuffWhenSheetsToWatchComplete()
For i = sheetsToWatch.Count To 1 Step -1
Set sht = sheetsToWatch.Item(i)
If not fAnyQueryTablesRefreshing(sht) Then
DoStuffNowThatSheetQueriesDone sht
sheetsToWatch.Remove i
End If
Next I
If sheetsToWatch.Count <> 0 Then
Call Application.OnTime(Now + delay, "DoStuffWhenSheetsToWatchComplete")
Else
AllDone
End If
End Sub
Function fAnyQueryTablesRefreshing(sht as Worksheet) As Boolean
Dim lo as ListObject
Dim qt as QueryTable
'queries directly within the sheet
For Each qt In sht.QryTables
If qt.Refreshing Then
fAnyQueryTablesRefreshing = True
Exit Function
End If
Next qt
'queries within ListObjects contained in the sheet
For Each lo in sht.ListObjects
Set qt = lo.QueryTable
If qt.Refreshing Then
fAnyQueryTablesRefreshing = True
Exit Function
End If
Next lo
fAnyQueryTablesRefreshing = False
End Function
Sub AllDone()
Application.ScreenUpdating = True
Set sheetsToWatch = Nothing
End Sub
Sub DoStuffNowThatSheetQueriesDone(sht As Worksheet)
'code to execute when all queries on a sheet have completed
End Sub
显然,我的需求(查询完成后通过 VBA 对每张工作表应用特殊格式)与您的需求不同,因为您不必观看多个查询或按工作表采取后续步骤,但上面的逻辑对我有用。 您可能想要修改它,以便它只监视单个查询或 ListObject,而不是监视加载到的每个表的所有查询。您可能也不想执行 RefreshAll,而是执行特定的第一个查询。