【问题标题】:Excel VBA - RefreshAll not updating pivot tablesExcel VBA - RefreshAll 不更新数据透视表
【发布时间】:2016-05-10 00:00:03
【问题描述】:

我有一个模板工作簿,其中有几个连接到 sql 连接的数据表,以及一些数据透视表,它们的来源是通过的数据。

我的印象是ActiveWorkbook.RefreshAll 会更新所有连接,然后更新枢轴。事实上,当我手动运行全部刷新时会发生这种情况。但是,当我运行 VBA(实际上在 Access 中,但被正确引用等)时,它会更新连接而不是数据透视表?

我在RefreshAll 之后尝试了DoEvents,但没有效果。

我现在唯一的选择是通过所有工作表、数据源、数据透视缓存运行For each 并以这种方式刷新它们吗?

【问题讨论】:

  • 有时当您刷新数据透视表时,它不会更改“数据源”范围。如果数据范围增加,您可能必须手动更改它,或者让您的 vba 代码知道偏移直到空白。
  • 麻烦的问题是ActiveWorkbook.RefreshAll是在MS Excel GUI中启动“全部刷新”时,宏记录器在代码中写入的内容。

标签: excel ms-access vba


【解决方案1】:

ActiveWorkbook.RefreshAll 实际上是 RefreshAll 连接和枢轴。但是,在您的场景中,数据透视可能基于您必须首先刷新的数据。数据尚未加载时,数据透视将刷新,因此会出现意外行为。

对此有多种解决方案:

  • 要么将通过连接返回的数据作为数据透视缓存,因此数据透视表将在数据返回时自动刷新。 这样,您也不会将数据本身存储在工作簿的单独工作表中。

  • 将所有连接的“后台刷新”属性设置为 false,无论是在代码中还是通过 UI,然后正常执行。 两次。第二次数据透视缓存将具有更新的数据,因此按预期刷新。 - 编辑:我不建议这样做,因为你会打开两次数据库连接,两次加载数据等等。非常低效!

  • 如上所述,将“后台刷新”属性设置为 false。使用 Refresh all 刷新后,循环访问工作表的数据透视表集合以在加载数据后手动刷新它们,如下所示。

代码:

Sub test()

Dim ws as Worksheet
Dim pt as PivotTable

ActiveWorkbook.RefreshAll 'make sure the refresh in bg property is false for all connections

For each ws in ActiveWorkbook.Worksheets
    For each pt in ws.pivottables
        pt.RefreshTable
    Next pt
Next ws

End Sub

或者只刷新pivotcaches(效率更高,特别是如果多个表使用相同的缓存):

Sub test()
Dim pc as PivotCache

ActiveWorkbook.RefreshAll 'make sure the refresh in bg property is false for all connections

For each pc in ActiveWorkbook.PivotCaches
    pc.Refresh
Next pc

End Sub

【讨论】:

  • 非常有趣,谢谢(当我遇到这个问题时,我使用了选项 2……至少它有效)。你能详细说明一下选项1吗?这将如何运作?
  • 亲爱的@Andre,当通过 Excel UI 创建数据连接时,创建连接文件后,Excel 会询问您希望如何在工作簿中显示返回的数据。默认情况下,它会在“现有工作表”上为您提供“表格”,让您指定范围。在这里您还可以选择一个数据透视表;然后数据将存储在 pivotCache 中,而不是工作表中。
  • 嗨@RikSportel。谢谢回复。我不能使用选项 3,因为这是一个自动化过程,在那里进行手动更新有点失去意义。选项 1 可能是可能的,但实际上我已经将数据作为表格引入,因为它有多个枢轴。在工作簿的其他区域,我确实使用了返回作为数据透视表选项。
  • 嗨@GavinP 我不确定我是否理解您的评论。多个枢轴可以基于单个枢轴缓存,因此不应该成为障碍。最简单的方法是将数据放入第一个数据透视表,而不是复制那个数据以创建第二个数据透视表,该数据透视表将共享数据透视缓存。然后一个简单的RefreshAll. 将更新两个枢轴。
  • @RikSportel 这意味着重做我已经完成的所有支点。我在答案中的代码确实解决了这个问题。
【解决方案2】:

我已经通过以下方式解决了这个问题

    For Each sht In .Sheets
        For Each qt In sht.QueryTables
            qt.Refresh
        Next qt
        For Each lo In sht.ListObjects
            lo.QueryTable.Refresh BackgroundQuery:=False
        Next lo
        For Each pvt In sht.PivotTables
            pvt.PivotCache.Refresh
        Next pvt
    Next sht

【讨论】:

  • 非常感谢。这是否仅在没有依赖于后续工作表中数据的数据透视表时才有效?遍历工作表三次是否更好,每个内部循环一次?我的意思是:迭代工作表刷新 QueryTables,然后迭代工作表刷新 ListObjects,然后迭代工作表刷新 PivotCaches?
  • 可能是的,具体取决于您的数据和工作簿的结构。我想我不久前在我的一个上做了同样的事情。
  • 有额外的. 的潜在勘误表,在For Each sht In Sheets 时工作
【解决方案3】:

我通过在代码中添加一个简单的“计算”解决了这个问题。

Calculate
ActiveWorkbook.RefreshAll

【讨论】:

    【解决方案4】:

    我在通过宏复制和保存工作簿时遇到了这个问题,并且在不同的数据透视表/缓存刷新方面没有运气,但在更改每个数据透视表的 SaveData 属性时找到了运气。以防万一有人像我一样读到这篇文章并正在寻找其他东西来尝试。

    For Each pt in ws.PivotTables
       pt.SaveData = True
    Next pt
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-06-16
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      • 2023-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多