Excel VBA – RefreshAll not updating pivot tables

excelms-accessvba

I have a template workbook, which has several data tables connected to sql connections, as well as some pivot tables who's sources are the data brought through.

I was under the impression that ActiveWorkbook.RefreshAll would update all connections, then update the pivots. That in fact is what happens when I run the refresh all manually. However, when I run the VBA (which is actually in Access, but is correctly referenced etc) it updates the connections but NOT the pivot tables?

I've tried DoEvents after the RefreshAll which had no effect.

Is my only option now to run a For each through all the worksheets, data sources, pivot caches and refresh them that way?

Best Answer

ActiveWorkbook.RefreshAll does as in matter of fact RefreshAll connections and pivots. However, in your scenario the pivots are probably based on the data you have to refresh first. The pivot will refresh while the data is not loaded yet, hence the unexpected behavior.

There are multiple solutions for this:

  • Either have the data returned through the connection as a pivotcache so the pivot table will automatically refresh when the data is returned. This way you will not have the data itself stored in a seperate sheet in your workbook either.

  • Set the "Refresh in Background" property to false for all connections, either in the code or through the UI, then execute as normally. Twice. The second time the pivotcaches will have the updated data and thus refresh as expected. - Edit: I do not recommend this, since you will open the db connection twice, load the data twice, etc. Highly inefficient!

  • Set the "Refresh in Background"- property to false as mentioned above. After refreshing using Refresh all, loop through your worksheets' pivottable collection to refresh those manually after the data has been loaded as shown below.

Code:

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

Or simply refresh only the pivotcaches (more efficient, especially if multiple tables use the same cache):

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