Excel vba 刷新等待

Posted

技术标签:

【中文标题】Excel vba 刷新等待【英文标题】:Excel vba refresh wait 【发布时间】:2012-02-14 01:46:03 【问题描述】:

我正在创建一些代码,我可以在其中单击一个按钮,它会刷新我在该工作表上的查询表。

现在,我的问题是,我在更新后有更多代码复制了一些信息,但这段代码在刷新开始后立即运行并且信息尚未被替换。

我想为刷新完成创建一个等待期,然后其余代码可以继续。

我不想只等待 5 秒,而是等待刷新时间,这样我就不会等待太久或太短,具体取决于互联网速度等。

我该怎么做?

编辑:

简单代码:

ActiveWorkbook.RefreshAll

这里我需要延迟或等待代码,直到所有刷新完成...然后

MsgBox("The Refreshing is Completed!")

那个方向的东西。但它不能说 msgbox 在它实际完成之前......有时取决于互联网速度,刷新需要更短或更长时间,所以我希望它是实际刷新时间的变量。

【问题讨论】:

您是否使用querytable.refresh false 指定非后台刷新? 到目前为止只有 ActiveWorkbook.RefreshAll 但我需要一个循环来检查何时完成刷新。这就是我的想象 您可以通过单独刷新它们来做到这一点'for i=1 to ActiveWorkbook.querytables.count : ActiveWorkbook.querytables(i).refresh false : next 遗憾的是它不允许在刷新时等待一段时间 啊,查看文档似乎仅适用于基于 sql 源的查询表,您是否使用 Web 查询代替? 【参考方案1】:

在您的 Web 查询的外部数据范围属性中,您有一个复选框,上面写着“启用后台刷新”之类的内容,您应该取消选中它以达到所需的效果。

看看这个页面的底部:http://www.mrexcel.com/tip103.shtml图片

编辑:

这里有两个宏显示了想要的效果:

Sub AddWebquery()
    With ActiveSheet.QueryTables.Add(Connection:= _
        "URL;http://de.selfhtml.org/html/tabellen/anzeige/table_tr_th_td.htm", _
        Destination:=Range("$A$1"))
        .Name = "table_tr_th_td"
        .BackgroundQuery = False
        .RefreshStyle = xlInsertDeleteCells
        .WebSelectionType = xlSpecifiedTables
        .WebFormatting = xlWebFormattingNone
        .WebTables = "1"
        .Refresh BackgroundQuery:=False
    End With
End Sub

Sub TestRefreshing()
    Range("A1").Clear
    ActiveWorkbook.RefreshAll
    Debug.Print "Test: " & Range("A1").Value
End Sub

执行AddWebquery添加Query,然后执行TestRefreshing测试效果。您可以将行 .BackgroundQuery = False 更改为 True 以得到错误的结果。

具有 10 秒睡眠的测试页:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>SO-Test</title>
    </head>
    <body>
        <?php
        sleep(10);
        ?>
        <table border="1">
            <thead>
                <tr><th>1</th></tr>
            </thead>
            <tbody>
                <tr><td>2</td></tr>
            </tbody>
        </table>
    </body>
</html>

【讨论】:

这不允许我用 VBA 刷新并等待它完成刷新 是的。刚刚测试过了。在属性中进行了更改,并在其后立即使用 Debug.Print 调用 RefreshAll。它总是返回想要的值,绝不是空值 这仍然不允许在下一个代码运行之前等待一段时间。如果我在 Debug.Print... 之后添加 MsgBox("finished refresh") 则 MsgBox 在刷新完成之前出现。 你用的是哪个excel版本?我刚刚创建了一个休眠 10 秒的页面,然后输出一个表格。不出所料,我的 makro 停了 10 秒,并在直接控制台中打印了调整后的值 它看起来很有效,但是如果您使用一个包含更多信息的更大的网站。并且您运行 TestRefresh 宏它仍然无法正常工作。有没有办法让excel知道它令人耳目一新,你可以创建一个循环。像 While refresh=true 循环直到刷新 =False.... 【参考方案2】:

我刚刚遇到了类似的问题,我们通过以下方式解决了它:

For i = 1 To ActiveWorkbook.Connections.Count
    ActiveWorkbook.Connections(i).OLEDBConnection.BackgroundQuery = False
    'MsgBox ActiveWorkbook.Connections(i).OLEDBConnection.BackgroundQuery
Next

ActiveWorkbook.RefreshAll

像这样,我们能够在调用刷新之前确保所有连接backgroundQuery 属性肯定是false

【讨论】:

这对于多个查询来说非常糟糕,因为通过后台刷新这些查询可以并行运行。如果没有后台刷新,每个查询只会在前一个查询完成后开始。 @GSerg 这取决于您的用例。在这种情况下,重要的不是速度而是可靠性,并确保在生成任何报告或执行分析之前加载所有数据。【参考方案3】:

如果你想让你的脚本在 vba 中等待,你必须使用 sleep。但是在 Excel vba 中 sleep 有时不起作用。

http://99students.com/macro-sleep-vba/

而不是尝试

Application.Wait (Now + TimeValue("0:01:00"))

示例代码

Sub Setting_Sleep_Without_Sleep_Function()
 MsgBox Now
 Application.Wait DateAdd("s", 10, Now)
 MsgBox Now
End Sub

【讨论】:

【参考方案4】:

'来自 A.G.Johnson@Live.com 2014-08-11 '这是一个简单的版本,可以让你完全控制。 '不使用 RefreshAll,而是创建以下子例程: '从你的 Excl VBA 调用例程,无论你想在哪里执行它, '在完成之前不会发生任何其他事情。 '另一个好处是它不会刷新任何数据透视表,因此它们不会干扰, ' 并且如果您有依赖于刷新数据的枢轴,则可以运行类似的刷新 ' 用于查询刷新完成后的数据透视表。

sub RefreshQueries()
    dim ws as worksheet
    dim qt as QueryTable
    For each ws in thisworkbook.worksheets
        For each qt in ws.querytables
            qt.refresh
        next qt
    next ws
end sub

【讨论】:

【参考方案5】:

我正在使用 PowerPivot 模型,我想在保存和关闭模型之前刷新数据。但是,excel只是在刷新完成之前关闭了模型,模型在打开时恢复刷新。

在 RefreshAll 方法之后添加以下行,成功了:

ThisWorkbook.RefreshAll
Application.CalculateUntilAsyncQueriesDone

我希望它也对你有用。

确保您禁用事件以加快速度。

请注意,我使用的是 Excel 2010,我不确定此方法是否适用于旧版本。

【讨论】:

【参考方案6】:

另一种方法是使用 Workbooks.Open 命令将 URL 作为单独的工作簿加载。

这使您可以在通话结束后立即完全访问来自 Web 请求的数据。此外,Excel 在加载时会显示一个进度条,而不是像 Web Query 那样冻结。

查看我对这个问题的回答:How can I post-process the data from an Excel web query when the query is complete?

这种方法的权衡是您必须自己管理处理取回的数据 - Excel 不会为您将其放入给定的目的地。

在尝试了与您似乎一直在做的非常相似的事情后,我们最终选择了这条路线。

【讨论】:

【参考方案7】:
ActiveWorkbook.RefreshAll
        Do While Application.CalculationState <> xlDone
            DoEvents
        Loop

我知道这是一个老问题,但这对我有用。 也适用于等待公式计算。

【讨论】:

您是否先激活了工作簿? (我知道这是一个愚蠢的问题,但是因为我忘记做一些简单的事情而导致我的代码不起作用的次数是不真实的)。 MyWorkbook.Activate Then .RefreshAll 是的,当然。 Application.CalculateUntilAsyncQueriesDone终于解决了问题。【参考方案8】:

取消选中“启用后台刷新” 数据 -> 连接 -> 属性

这将禁用后台刷新并等待刷新完成。

【讨论】:

【参考方案9】:

试试这个方法:

With Selection.ListObject.QueryTable
  .BackgroundQuery = False
  .Refresh
End With

当您这样说时,BackgroundQuery = False 似乎不会将 BackgroundQuery 属性更改为 False。

Selection.ListObject.QueryTable.Refresh BackgroundQuery = False  ' doesn't work

【讨论】:

以上是关于Excel vba 刷新等待的主要内容,如果未能解决你的问题,请参考以下文章

Excel 正在等待另一个应用程序完成 OLE 操作

如何等待 Power Query 刷新完成?

如何让 Excel RefreshAll 等待关闭直到完成?

Excel VBA循环

在excel中如何用vba来实现查找特定的字符串?

通过 VBA 将 XML 导入 EXCEL 不会刷新