I have a spreadsheet with multiple tables, where the data is pulled from an external data source (SQL database). The connections/tables refresh by changing an option in a drop down box and then pressing a button to run a VBA.
Attached to each of these tables is a pivot table. The pivot tables don't refresh with the tables. If I try pressing refresh all I get the error;
'Data Source name not found and no default driver specified'
However if I go through the spreadsheet and hit refresh on each individual pivot table they update without the error.
So either I need some way to get the pivot tables to refresh with the tables or have a button that refreshes only the pivot tables and not the external data connections.
Any ideas appreciated, I don't know where to begin with this one!
You can refresh a given PivotTable on Sheet1 like this:
Sheet1.PivotTables(1).RefreshTable
That will refresh the first PivotTable on Sheet1. Change the index number for a different one.
Or...
You can refresh all of the PivotTables on a give sheet by calling this routine:
Sub RefreshPivotTables(ws As Worksheet)
Dim pt As PivotTable
For Each pt In ws.PivotTables
pt.RefreshTable
Next
End Sub
You would call the above routine from the same code associated with the button mentioned in your question that updates the tables.
Or...
If you'd like to update all of the PivotTables in a workbook, you can use this version of the routine:
Sub RefreshPivotTables(wb As Workbook)
Dim ws As Worksheet
Dim pt As PivotTable
For Each ws In wb.Worksheets
For Each pt In ws.PivotTables
pt.RefreshTable
Next
Next
End Sub
You would call this version like so:
RefreshPivotTables ThisWorkbook
Becky: Any reason you don't populate those PivotTables directly from the SQL query? Unless you need those tables there for some reason I'd suggest just ditch 'em, and simply turn the data directly into PivotTables. Otherwise you're effectively saving the same data in the file twice. (Or three times, if you haven't unchecked "Save source data with file" under PivotTable>Data>Options.
If you do need to refresh them - and if there are multiple PivotTables connected to each Table - then it is more efficient to iterate through the underlying PivotCaches and refresh any where the sourcetype is an Excel Range. In VBA speak that's where pc.SourceType = xlDatabase
Sub Refresh_PivotCaches()
Dim pc As PivotCache
For Each pc In ActiveWorkbook.PivotCaches
If pc.SourceType = xlDatabase Then pc.Refresh
Next pc
End Sub
If you instead iterate through each and every PivotTable, then if multiple PivotTables are connected to one PivotCache you end up doing more refreshes than you need. For instance, if you have 10 PivotTables that all point to the same table, you do not need to refresh those 10 PivotTables individually. Rather, you just need to refresh the one PivotCache that they all share. If you were to refresh those 10 PivotTables individually, then in effect you are refreshing each of those 10 PivotTables 10 times.
Granted, if your PivotTables are small you won't notice any difference between my code and Excel Heros.
I added the following at the end of my code which seemed to work fine.
Dim PT As PivotTable
Dim WSH As Worksheet
For Each WSH In ThisWorkbook.Worksheets
For Each PT In WSH.PivotTables
PT.RefreshTable
Next PT
Next WSH
I know this is an old post, but sharing in case this helps anyone researching this like I was -- This may be new to Excel 2016 (I don't have access to older versions currently to test), however I found that you can disable the "Refresh with Refresh All" setting on your external data sources. This will then allow you to use the "Refresh All" from the Data Tab to update all your pivot tables at once, without updating the external data source query again:
Data Tab > Connections Section > Open Connections
Select a connection in the Workbook Connections window and click Properties...
In the properties window, uncheck the box for "Refresh this connection on Refresh All"
Repeat for any additional External Connections you don't want to update automatically
I use this in a reporting macro by calling the manual query updates once:
(selecting a cell in each table created by a query)
ActiveWorkbook.Sheets("Completed").Select
Range("A2").Select
Selection.ListObject.QueryTable.Refresh BackgroundQuery:=False
And then calling refresh all as needed to update my pivot tables:
ActiveWorkbook.RefreshAll
Related
I have an Excel document with 4 Worksheets.
On Sheet1 I set my start & end dates for my data.
On Sheet2 is the data itself (provided by an external SQL database).
On Sheet3 & Sheet4 are PivotTables that use the second sheets data as their source.
I have created a VBA macro button on Sheet1 to refresh all.
I'll change my date range on Sheet1 then click the button but it only refreshes the data on Sheet2 and not the PivotTables on Sheet3 & Sheet4. I have to click the button a second time to refresh the PivotTables with the new data.
Here is the VBA code:
Sub Button2_Click()
Application.ScreenUpdating = False
ActiveWorkbook.RefreshAll
Application.ScreenUpdating = True
End Sub
Even manually using the Refresh All button has the same outcome.
It seems when you do a refresh all it is trying to refresh everything in parallel, probably to save time. However, I think since you have pivot tables which are dependent on data which needs to refresh from the DB, you have to ensure that your external data is refreshed prior to attempting to refresh the pivot tables.
I was able to reproduce the issue and doing the below resolved it for me. Just have to replace "Query1" with the name of your query.
ActiveSheet.ListObjects("Query1").QueryTable.Refresh BackgroundQuery:=False
For Each pc In ActiveWorkbook.PivotCaches
pc.Refresh
Next
Edit:
To get the query name, you can go to the "Data" tab on your ribbon you should see a button that says "Queries & Connections" clicking on that will expand a pane on the right side of the excel screen. In that pane clicking on the Queries tab on the top will give you a list of your queries that are set up
Screenshot of my QueryTable name
I have a macro that copies two sheets from my workbook to their own workbook. One sheet has some data defined with a named range, the second has multiple pivot tables, all with the data source as said named range candData.
Once the sheets have copied my slicers lose some of their Report Connections.
In order to reconnect them, I have to manually select each pivot table and set the data source again, even though the data source is already set. (I simply click Change Data Source and immediately click OK, without actually changing anything.)
Once I have done this for each pivot table all report connections are showing again.
I have the following macro to loop through each pivot table and re apply the data source, then reconnect each slicer connection, however even after the data source has been applied, I still have to manually select each pivot table in order to reconnect the slicers.
I am getting no errors, it steps through each pivot table as expected and resets the data source. Any clues why the report connections only work when I set the data source manually instead of through the following?
Sub setSlicerSource()
Dim MyPivot As PivotTable
Dim slCaches As SlicerCaches
Dim slCache As SlicerCache
Set slCaches = ActiveWorkbook.SlicerCaches
With ActiveWorkbook
For Each MyPivot In .Sheets("Pivots").PivotTables
MyPivot.ChangePivotCache .PivotCaches.Create(SourceType:=xlDatabase, SourceData:="candData")
Next MyPivot
For Each slCache In slCaches
For Each MyPivot In .Sheets("Pivots").PivotTables
slCache.PivotTables.AddPivotTable MyPivot
Next MyPivot
Next slCache
End With
End Sub
I'm not sure if this will actually solve your problem, but it's the first thing I'd try fixing regardless:
This line currently creates a new PivotCache for each PivotTable:
MyPivot.ChangePivotCache .PivotCaches.Create(SourceType:=xlDatabase, SourceData:="candData")
Instead, create a PivotCache for PivotTables(1) first before the loop:
.Sheets("Pivots").PivotTables(1).ChangePivotCache .PivotCaches.Create(SourceType:=xlDatabase, SourceData:="candData")
Then in the loop, set all PivotTables to use the cache of PivotTables(1)
MyPivot.ChangePivotCache .Sheets("Pivots").PivotTables(1)
I am working on a project, where I dump data on a monthly basis in Sheet1. In my sheet analysis, I have three pivot tables summarizing this data using certain filter, which should remain unchanged even if the raw data changes.
I use the following VBA code to update the pivot tables after the data dump.
Private Sub CommandButton1_Click()
With ThisWorkbook.Worksheets("Analysis")
.PivotTables("PivotTable1").RefreshTable
.PivotTables("PivotTable2").RefreshTable
End With
Sheets("Output").Activate
End Sub
The problem is, whenever I have a new data dump in Sheet 1 and then run the code, I get the following message: There is already data in [Dokument1]Analysis. Do you want to replace it? After this the output from the pivot tables is wrong and the supposedly static pivot filters are no longer there.
I made sure that there is more than enough space between the pivot tables and there cannot be any overlaps. I have had this problem for a long time and do not know how to solve it, so any help is appreciated.
Do not use ActiveSheet. In my opinion is better to use create a with statement refers to the sheet you want and use refresh all instead of one by one.
Option Explicit
Sub test()
With ThisWorkbook.Worksheets("Sheet1")
.RefreshAll
End With
End Sub
This is a nice way to loop through all worksheets and refresh all pivot tables:
Dim ws As Worksheet
Dim pt As PivotTable
For Each ws In wb.Sheets
For Each pt In ws.PivotTables
pt.PivotCache.Refresh
Next pt
Next ws
Of course, you can easily impose limits if you want to exclude any worksheets or pivot tables. The nice thing about this is not only does it do all tables in blocks (by sheet), but if tables are added, removed or renamed, it doesn't crash when looking for specific tables.
as of excel 2016 (i think, certainly 2019)
ThisWorkbook.RefreshAll
I have a workbook, where there is a RawData sheet and there are 8-9 other sheets that have pivot tables that read a table from RawData. The RawData changes daily, i.e. there can be more or less number of rows in the RawData sheet's table.
Right now, I manually update DataSource property of each pivot table one each sheet using ChangeDataSource feature of Excel. However, this is painful. Crawling on web I found vba code to update all Pivot tables at once. I am not pasting the whole code, but it looks something like this.
ActiveSheet.PivotTables("PivotTable1").ChangePivotCache ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=<RawData-AddressRange>)
But what this code does is, it creates new pivot caches for each pivot table and increases the size of the file. However, I do not want the file size or number of pivot cache's to increase, but just change the dataSource of existing PivotTables/PivotCaches and refresh them.
To set a single PivotCache for all the PivotTable:
Sub UpdatePivots()
Dim ws As Worksheet, pivot As PivotTable, cache As PivotCache
' create a new pivot cache '
Set cache = ThisWorkbook.PivotCaches.Create( _
XlPivotTableSourceType.xlDatabase, _
ThisWorkbook.Sheets("Sheet1").UsedRange)
' set the pivot cache for each pivot table
For Each ws In ThisWorkbook.Worksheets
For Each pivot In ws.PivotTables
If cache.Index Then
pivot.CacheIndex = cache.Index
Else
pivot.ChangePivotCache cache
End If
Next
Next
' refresh the cache
cache.Refresh
End Sub
Just turn RawData into an Excel Table (Ctrl + T is the keyboard shortcut) and then point your PivotTables at that Table. (You'll have to use the 'Change Data Source' button one more time, to get it to change from using a hard-coded reference like $A$1:$Z$1000 to a Table reference like Table1).
From then on, any time you put new data into RawData, the Table will automatically expand (or contract) to accomodate it, and whenever you click refresh, the PivotTables will automatically reference those Tables instead of a hard-coded range.
Also note that if the PivotTables are all based on the exact same data source, refreshing one of them refreshes all of them.
You should consider using dynamic named range to define your RawData. Set the data source of all of your pivot tables to be your dynamic named range and then all you will need to do is click data>refresh all to update all pivot tables
here is a tutorial on dynamic named ranges
http://www.excel-easy.com/examples/dynamic-named-range.html
Okay so I have the following code to refresh all the pivot tables in the active workbook:
For Each oSht In Active Workbook.Worksheets
For Each oTab In oSht.PivotTables
oTab.RefreshTable
Next oTab
Next oSht
However, I feel that this is inefficient because, when you refresh a pivot, it automatically refreshes all other pivots connected to the same data table.
I would therefore like to refresh only one pivot table for each external data table i have in the active workbook but cant work out a way of implementing this...
You can use the ThisWorkbook.PivotCaches collection and refresh the cache instead of each table.