Excel VBA-RefreshAll не обновляет сводные таблицы

у меня есть книга шаблонов, в которой есть несколько таблиц данных, подключенных к sql-соединениям, а также некоторые сводные таблицы, источниками которых являются данные.

у меня сложилось впечатление, что ActiveWorkbook.RefreshAll обновит все соединения, а затем обновит оси. Это на самом деле то, что происходит, когда я запускаю обновление вручную. Однако, когда я запускаю VBA (который на самом деле находится в доступе, но правильно ссылается и т. д.), он обновляет соединения, но не сводные таблицы?

Я пробовал DoEvents после RefreshAll который не имел никакого эффекта.

- Это мой единственный вариант, чтобы запустить For each через все рабочие листы, источники данных, сводные кэши и обновить их таким образом?

3 ответов


ActiveWorkbook.RefreshAll делает, как на самом деле RefreshAll соединения и повороты. Однако в вашем сценарии оси, вероятно, основаны на данных, которые необходимо обновить в первую очередь. Pivot будет обновляться, пока данные еще не загружены, следовательно, неожиданное поведение.

для этого есть несколько решений:

  • либо данные возвращаются через соединение как pivotcache, поэтому сводная таблица автоматически обновляется, когда данные возвращенный. Таким образом, сами данные не будут храниться на отдельном листе в книге.

  • установите для свойства "обновить в фоновом режиме" значение false для всех соединений, либо в коде, либо через пользовательский интерфейс, а затем выполните как обычно. два раза. Второй раз pivotcaches будет иметь обновленные данные и обновить так, как ожидалось. - Edit: я не рекомендую это, так как вы откроете соединение с БД дважды, загрузите данные дважды, так далее. Крайне неэффективно!

  • установите для свойства "обновить в фоновом режиме" значение 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

Я решил проблему, используя следующее

    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

Я решил проблему, добавив простой "вычислить" в код.

Calculate
ActiveWorkbook.RefreshAll