Multiple Pivot Charts SetSourceData Error - excel

I have multiple pivot charts each with their own pivot table on separate worksheets in Excel 2002.
When I try to generate these charts with VBA with the following code:
Set cht = Charts.Add(After:=Worksheets("Setup"))
With cht
' we use named ranges here
.SetSourceData Source:=range(tblName)
.Name = chtName
....
where tblName is a named range just created a few lines before, the code runs fine if there is only one table and chart generate but gives me a run time error 1004: "The source data of a PivotChart report cannot be changed..." if I try to generate pivot table and chart set one after another.
Going to Insert -> Name -> Define, the list of named ranges created seems to be correct.
What is the correct way of setting the source data for a pivot chart with a dynamic range?

I think you might be trying to do too many things at once.
If the Data Source is going to change, I wouldn't use a Pivot Chart.
Use a pivot table, create the chart at runtime (like your example). Build your chart of the results of the pivot table.

This piece of code assumes that you have only one pivot table per sheet and the pivot table starts on Cell A1:
Sheets(wsName).Select
Range("A1").Select
Set cht = Charts.Add(after:=Worksheets(Worksheets.Count))
With cht
.SetSourceData Sheets(wsName).Range("A1")
.Name = chtName
...
Also changing "Worksheets.Count" to a specific worksheet name seems to trigger that error as well.

Related

How to extract pivot table data source range using VBA

I have created a pivot table using the data in another sheet. My pivot table is working fine. When ever there is a data change when I refresh the table its captured correctly.
I tried to access the source data details for this pivot table using vba. By using the following code
Set PT = Worksheets("PivotTable").PivotTables("PivotTable1")
Debug.Print PT.SourceData
It gave me the result
Data!C1:C6
It gave the sheet name properly but not the data range. Where am I going wrong.
Is there any other alternative available to get the source data details.
Thanks in advance.
You're pulling the R1C1 reference. That can be changed with application.convertformula. Note that because you're using the entire column, it would make sense to reduce the scope of range within the sheet's usedrange area.See below how it would work.
Set PT = Worksheets("PivotTable").PivotTables("PivotTable1")
Set rngSourse = Range(Application.ConvertFormula(pt.SourceData, xlR1C1, xlA1))
debug.print rngSourse.address
Set WSsource = rngSourse.Worksheet
Set rngSourse = Intersect(WSsource.UsedRange, rngSourse) 'now it's only the used
debug.print rngSourse.address

VBA copy paste runs different in debug mode

I have a spreadsheet in Excel with three pivot charts. I wrote a VBA code that does the following:
' Copies sheets 1-4
ThisWorkbook.Worksheets(Array("1", "2", "3", "4")).Copy
'Transforms each new sheet data in values only.
For Each iSheet In ActiveWorkbook.Sheets
iSheet.Activate
iSheet.UsedRange.Copy
iSheet.UsedRange.PasteSpecial xlPasteValuesAndNumberFormats
iSheet.Range("A1").Select
Next iSheet
' After pasting, deletes the contents of the cells but keeps the graphs
' in spread sheet 4
ActiveWorkbook.Sheets("4").Columns("J:AB").Clear
This code runs differently in debug mode (F8) compared to when it is run by pressing F5 or running with a button in Excel. In debug mode, it keeps all the series information in the Pivot Charts when the Pivot Tables are pasted as values. When it runs nonstop, it loses the pivot charts information, so that for instance the series names change to defaults 'Series 1', the x values go from specific date values to jan-00, format of x axis labels change to text, etc. I have no idea why. In other very similar question, someone pointed out that PasteSpecial behaves differently when the target worksheet is not activated, which is why I added iSheet.Activate. This difference in action may also be a result of the Clear method of the Pivot Tables.
I tried to add Activate in different steps in the code to no avail.
I'm assuming you want to leave only values on every sheet on the active workbook so this is it:
' Copies sheets 1-4
ThisWorkbook.Worksheets(Array("1", "2", "3", "4")).Copy
'Transforms each new sheet data in values only.
For Each iSheet In ActiveWorkbook.Sheets
iSheet.UsedRange.Values = iSheet.UsedRange.Values
Next iSheet
Thought the first line copying the sheets has no sense.
Looks like you don't care if you really keep the values of the pivot table. In an example I just ran, I have a pivot table in G2:L19. I executed this line of code, which deleted the columns containing the pivot table, and the pivot chart remained, plotting the same data, but the data was now hard-coded into the chart.
ActiveSheet.Range("G:L").Delete
If you do want to retain the values and number formats but not the pivot table itself, this code, run in F5 or F8 mode, keeps the data where the pivot table was, and it keeps the data in the chart, hard-coded (unlinked from the pivot table).
Sub UnpivotTable()
With ActiveSheet.Range("G2:L19")
.Copy
.PasteSpecial xlPasteValuesAndNumberFormats
End With
End Sub
Do you want to keep the links from the chart to the data? Store the series formulas, undo the pivot table, and reapply the series formulas:
Sub UnpivotTableKeepChartLinks()
Dim MyChart As Chart
Set MyChart = ActiveSheet.ChartObjects("Chart 1").Chart
Dim vSrsFmlas As Variant
ReDim vSrsFmlas(1 To MyChart.SeriesCollection.Count)
Dim iSrs As Long
For iSrs = 1 To MyChart.SeriesCollection.Count
vSrsFmlas(iSrs) = MyChart.SeriesCollection(iSrs).Formula
Next
With ActiveSheet.Range("G2:L19")
.Copy
.PasteSpecial xlPasteValuesAndNumberFormats
End With
For iSrs = 1 To MyChart.SeriesCollection.Count
MyChart.SeriesCollection(iSrs).Formula = vSrsFmlas(iSrs)
Next
End Sub

Multiple Pivot Table Using Same Data Source & Cache

I'm working on automating data analysis & creation of pivots and charts for which I have Raw Data (441379 Rows, 40 columns).
1) Raw Data changes monthly, so I need a dynamic range.
2) I have to create around 20 Pivot Tables with the same data.
3) I'm defining range and pivot cache for every single pivot. A lot of time is consumed in reading data and executing every single time.
4) I need the flexibility of choosing a range for placing the pivot table as one sheet may have more than one pivot table.
5) I need the flexibility of creating a sheet and naming them for pivot as I will have around 20 sheets.
How can I define pivot source and pivot cache once in the workbook so I can use the same for all the pivot tables?
Below is the code which I'm using
' For Dynamic data range named "PvtData"
ActiveWorkbook.Names.Add Name:="PvtData", RefersToR1C1:= _
"=OFFSET('Data'!R1C1,0,0,COUNTA('Data'!C1),COUNTA('Data'!R1))"
' For creating Pivot using Dynamic data range named "PvtData"
ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, SourceData:= _
"PvtData").CreatePivotTable TableDestination:="", TableName:="PivotTable_UBD"
ActiveSheet.PivotTableWizard TableDestination:=ActiveSheet.Cells(7, 1)
ActiveSheet.Cells(7, 1).Select
ActiveSheet.PivotTables("PivotTable_UBD").SmallGrid = False
ActiveSheet.Name = "Utilization By Day"
Or
' For Dynamic data range named "PvtData"
ActiveWorkbook.Names.Add Name:="PvtData", RefersToR1C1:= _
"=OFFSET('Data'!R1C1,0,0,COUNTA('Data'!C1),COUNTA('Data'!R1))"
' For creating Pivot using Dynamic data range named "PvtData"
Set PivotCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, _
SourceData:="PvtData")
Worksheets.Add
ActiveSheet.Name = "Utilization By Day"
ActiveWindow.DisplayGridlines = True
Set PivotTable = ActiveSheet.PivotTables.Add(PivotCache:=PivotCache, _
TableDestination:=Range("A1"), TableName:="PivotTable_UBD")
I know this has been here a while and not sure you still need it answered.
Take your Raw data and turn it into a table.
Create a Pivot Table from the data source that is in table format. Once created from the table your pivot source becomes a dynamic source. As the table size changes the pivot source changes since it is referencing the table.
Copy the pivot table and paste the pivot table 19 times. Since they are all copies, they work from one cache. Once one pivot is refreshed all 20 are refreshed regardless of how many sheets they are on.

Pivot/Table filter activated through link from other table's cell value

I have a list of items to work through and some items require deeper analysis. Essentially I have two tables. The first shows production results and through filtering column U, I get a list of outliers as in the following image.
Table of outliers
The values displayed in column S then require further analysis for which a pivot chart has been set up. In this chart I filter the particular VRTY number to take a closer look.
Pivot Chart for analysis
Both sheets are contained in the same workbook and I essentially work with two windows open, but to go through the list I have to manually enter every single VRTY value in the pivot filter.
The table of the Pivot chart and the outlier table are not related and data sources are different.
In column S of the outlier table (VRTY) I would ideally turn the values into links that automatically set the pivot filter to this value when clicked.
I am a novice at VBA but from the research I've done this will be the only option - I just haven't come by an instructions how to achieve this particular function.
Instructions/ advice would be highly appreciated.
Sambo: Make sure the orientation of the 'Number' field in the PivotChart's underlying PivotTable is a PageField, and then put the below code in the Sheet code module that corresponds to the sheet where the Outliers PivotTable is:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim pf As PivotField
Dim pf_Slave As PivotField
Set pf = ActiveSheet.PivotTables("PivotTable1").PivotFields("VRTY")
Set pf_Slave = ActiveSheet.PivotTables("PivotTable2").PivotFields("number")
If Not Intersect(Target, pf.DataRange) Is Nothing Then
On Error Resume Next
pf_Slave.CurrentPage = CStr(Target)
On Error GoTo 0
End If
End Sub
Change "PivotTable1" and "PivotTable2" as appropriate.
By "Sheet code module" I mean this type of thing:

Get pivotTable handle from cell in vba

For instance I have a pivot table on every third worksheet that needs to be edited, on the worksheet is 3 pivot tables, I don't actually know the name of the table but I know it lies on $N$2, is there anyway to get the name or handle of the pivot table from the cell?
The Range object has a PivotTable property that returns the object you want
Set pt = MySheet.Range("N2").PivotTable

Resources