等到ActiveWorkbook.RefreshAll完成 - VBA

时间:2014-02-28 00:20:16

标签: vba excel-vba excel

我有一个sub,它调用 ActiveWorkbook.RefreshAll 从XML源中引入新数据,然后对其进行多次修改。问题是没有足够的时间让RefreshAll命令完成,所以下面的子和函数最终没有正确执行,这导致重复的行没有被正确擦除。

我尝试使用 Application.Wait Sleep 功能,但它们似乎也暂停了刷新过程。我只是希望其余代码等到刷新过程完成后再执行其余的代码。

关于如何实现这一点的任何想法?现在我只能通过不调用RefreshAll来修复它,这让我想到实现后续执行的第二个流程,但这不是一个好的解决方法。

如果有任何不清楚的地方,请告诉我。感谢

修改 所以我从下面的帖子中尝试了一些建议,这就是我能想到的。 执行“记录宏”,然后在表属性中取消选中“启用后台刷新”不会产生任何结果。之后我也做了一次刷新。这是录制的宏的结果:

With ActiveWorkbook.Connections("XMLTable")
        .Name = "XMLTable"
        .Description = ""
End With
ActiveWorkbook.Connections("XMLTable").refresh

ActiveWorkbook.Connections 没有 BackgroundQuery 选项,因此我可以将其设置为False。有什么想法吗?

要清楚。这是一个托管在网站上的XML文件,Excel将其导入并导入到表中。然后我将这些数据称为数据透视和其他内容。这里的目标是允许从网站到表的导入过程在执行任何其他命令之前完成。 感谢

EDIT2: 经过一番研究后,我找到了这个页面:http://www.mrexcel.com/forum/excel-questions/564959-execute-code-after-data-connection-refresh-finished.html 似乎XML类型的连接没有 BackgroundQuery 布尔值。该选项仅适用于ODBC和OLEDB连接,分别是xlConnectionTypeODBC和xlConnectionTypeOLEDB类型。我使用的XML连接是xlConnectionTypeXMLMAP类型,它没有 BackgroundQuery 选项。 有没有人知道从哪里去?我现在想到的唯一解决方案是在Excel工作表上创建两个单独的宏按钮,一个用于刷新,一个用于数据修改,但我宁愿将该选项保留到最后一个。

17 个答案:

答案 0 :(得分:44)

我遇到了同样的问题,但 DoEvents 对我没有帮助,因为我的数据连接启用了后台刷新。相反,使用Wayne G. Dunn的答案作为起点,我创建了以下解决方案,对我来说效果很好;

Sub Refresh_All_Data_Connections()

    For Each objConnection In ThisWorkbook.Connections
        'Get current background-refresh value
        bBackground = objConnection.OLEDBConnection.BackgroundQuery

        'Temporarily disable background-refresh
        objConnection.OLEDBConnection.BackgroundQuery = False

        'Refresh this connection
        objConnection.Refresh

        'Set background-refresh value back to original value
        objConnection.OLEDBConnection.BackgroundQuery = bBackground
    Next

    MsgBox "Finished refreshing all data connections"

End Sub

MsgBox 仅用于测试,一旦您对代码等待感到满意就可以删除。

另外,我更喜欢 ThisWorkbook ActiveWorkbook ,因为我知道它会定位代码所在的工作簿,以防焦点发生变化。十分之九,这无关紧要,但我喜欢谨慎行事。

编辑:刚刚看到您编辑有关使用没有BackgroundQuery选项的xlConnectionTypeXMLMAP连接,抱歉。我会留下上面的任何人(像我一样)寻找一种刷新OLEDBConnection类型的方法。

答案 1 :(得分:20)

评论如下:

'~~> your code here before refresh

Activeworkbook.RefreshAll
DoEvents

'~~> rest of your code here after refresh

DoEvents做什么就像是暂时允许Windows从Macro中休息一下,以便在返回宏之前处理所有待处理事件。
因此,当您刷新工作簿并将DoEvents放在后,它将不会恢复宏,直到刷新完成。

答案 2 :(得分:12)

虽然@Wayne G. Dunn已经提供了代码。这是您不想编码的地方。并取消选中以禁用后台刷新。

enter image description here

答案 3 :(得分:8)

免责声明:据报道,以下代码遭遇了一些崩溃!小心使用。

  

根据Excel 2010及更高版本中的THIS answer CalculateUntilAsyncQueriesDone停止宏,直到刷新完成为止  ThisWorkbook.RefreshAll
 Application.CalculateUntilAsyncQueriesDone

答案 4 :(得分:4)

您必须为所有查询关闭“后台刷新”。如果启用了后台刷新,则在刷新发生时Excel会提前工作,并且您遇到问题。

数据>连接>属性> (取消选中)启用后台刷新

答案 5 :(得分:1)

这可能不太理想,但尝试使用“Application.OnTime”暂停剩余代码的执行,直到经过足够的时间来确保所有刷新过程都已完成。

如果刷新列表中的最后一个表是一个虚假表,只包含一个表示刷新完成的标志,该怎么办?该表将在过程开始时删除,然后,使用“Application.OnTime”,Sub将每15秒左右运行一次,检查是否已填充了虚假表。如果已填充,请停止“Application.OnTime”检查程序并继续执行其余程序。

有点不稳定,但它应该有用。

答案 6 :(得分:1)

以下是在http://www.mrexcel.com/forum/excel-questions/510011-fails-activeworkbook-refreshall-backgroundquery-%3Dfalse.html找到的解决方案:

要么将所有pivotcaches的backgroundquery属性设置为False,要么遍历所有工作簿的pivotcaches:

Code:
    For Each pc In ActiveWorkbook.PivotCaches
       pc.BackgroundQuery = False
       pc.Refresh
    Next 

这会将所有pivotcaches backgroundquery属性保留为false。您可以使用以下方式保留每个设置:

代码:

For Each pc In ActiveWorkbook.PivotCaches
  originalBGStatus = pc.BackgroundQuery
  pc.BackgroundQuery = False
  pc.Refresh
  pc.BackgroundQuery = originalBGStatus
Next

答案 7 :(得分:0)

我遇到了同样的问题,并尝试了上述所有解决方案但没有成功。我终于通过删除整个查询并创建一个新查询来解决问题。

新的设置与不起作用的设置完全相同(字面意思与我简单复制旧设置的查询定义相同)。

我不知道为什么这会解决问题,但确实如此。

答案 8 :(得分:0)

如果您未使用Excel Web Query,则可以尝试将URL作为单独的工作簿打开。通过该路径,您可以在Web请求完成后处理结果数据,就像关闭"启用后台刷新一样。"

不错的是,Excel在请求期间显示进度条,而不是仅冻结/显示目标单元格中​​的加载消息。

请参阅我对此问题的回答:How can I post-process the data from an Excel web query when the query is complete?

这种方法的权衡是你必须管理自己收到的数据 - Excel不会把它放在给定的目的地。

在我们尝试了与你似乎一直非常相似的事情后,我们最终走上了这条路线。

答案 9 :(得分:0)

尝试执行:

ActiveSheet.Calculate

我在工作表中使用它,其中控制按钮更改数据集的值。每次单击时,Excel都会运行此命令,图表会立即更新。

答案 10 :(得分:0)

这对我有用:

ActiveWorkbook.refreshall
ActiveWorkbook.Save

保存工作簿时,有必要完成刷新。

答案 11 :(得分:0)

我尝试了上面的一些建议,对我来说最好的解决方案是为每个连接禁用backgroundquery。

With ActiveWorkbook.Connections("Query - DL_3").OLEDBConnection
    .BackgroundQuery = False
    End With

答案 12 :(得分:0)

对于Microsoft Query,您可以进入连接->属性,然后取消选中“启用后台刷新”。

这将停止刷新过程中发生的任何事情。我需要在输入时刷新数据,然后对刷新后的数据运行用户窗体,该方法对我来说非常有效。

答案 13 :(得分:0)

我也有类似的要求。经过大量测试,我发现了一个简单但不是很好的解决方案(不确定是否适合您吗?)...

在宏刷新Excel所获取的数据之后,我在宏中添加了“计算”行(如果您将计算设置为手动,通常用于重新计算工作簿)。

虽然我不需要执行此操作,但通过添加它来显示它,Excel会在刷新数据之前等待,然后继续执行我的其余宏。

答案 14 :(得分:0)

对我来说,"BackgroundQuery:=False" 不能单独工作 但是添加“DoEvents”解决了问题

.QueryTable.Refresh BackgroundQuery:=False
VBA.Interaction.DoEvents

答案 15 :(得分:0)

我知道,这可能听起来很愚蠢,但也许它是最好和最简单的解决方案。

您必须创建额外的 Excel 文件。它甚至可以是空的。 或者,您可以使用目录中的任何其他现有 Excel 文件。

'开始'

Workbooks.Open("File_where_you_have_to_do_refresh.xlsx")
Workbooks("File_where_you_have_to_do_refresh.xlsx").RefreshAll

Workbooks.Open("Any_file.xlsx)
'Excell is waiting till Refresh on first file will finish'
Workbooks("Any_file.xlsx).Close False

Workbooks("File_where_you_have_to_do_refresh.xlsx").Save

或者使用这个:

Workbooks("File_where_you_have_to_do_refresh.xlsx").Close True

它在我的所有文件上都能正常工作。

答案 16 :(得分:-1)

我为解决此问题所做的工作是保存工作簿。这会迫使它在关闭之前刷新。

相同的方法适用于在执行下一个操作之前复制许多公式。