I am trying to create the pivot table in VBA( Excel 2013) using the following code
Dim pt As PivotTable
Dim cache As PivotCache
Sheets("data").Select
Set cache=ActiveWorkbook.PivotCaches.Create(xlDatabase,Cells(1,1).CurrentRegion)
Sheets("pivot").Select
Set pt = cache.CreatePivotTable("R4C")
I am getting error in the line set pt. please help in identifying the error.
You are right "RC"-string is valid... but you need full ref!
To make it work, use this:
Dim pt As PivotTable
Dim cache As PivotCache
Set cache = ActiveWorkbook.PivotCaches.Create(xlDatabase, Sheets("data").Cells(1, 1).CurrentRegion)
Set pt = cache.CreatePivotTable("'pivot'!R4C")
Pls check if there is another object at the destination (that may cause the error).
Related
I have some VBA code which needs to select Prod. Code, Lims#, SampleID, Log Date, District Name, Region, Machine ID, Ash, cNDF, CP, Ca, Cl from a pivot table.
When I use Entire row, I can select all the data that I need to make a clean paste into column A. However, now I'd like to paste into column
.PivotItems(PivotFieldName.Caption).DataRange.EntireRow.Select
I've attempted to do just data range, however it won't pull Prod.Code, Lims#, etc columns. It will only grab the analyte columns.
.PivotItems(PivotFieldName.Caption).DataRange.Select
I also tried to do a range off of the EntireRow, however then I can't figure out how to get last column or last row for that selected Prod. Code.
.PivotItems(PivotFieldName.Caption).DataRange.EntireRow.Range("A1:BB1").Select
How can I got about getting all columns for a Prod. code selected like the Entire Row method excluding the extra rows?
The Prod.Code Columns & Rows can shift in size depending on the data so I need to make it capable of grabbing the right range.
Further code structure:
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
Set PvtTbl = Sheets("NEP Pivot").PivotTables("NEP_Pivot")
Set PvtFld = PvtTbl.PivotFields("Prod. Code")
For Each PivotFieldName In PvtFld.PivotItems
'PivotFieldName.Caption represents "EHB"
If IsError(Application.Match(PivotFieldName.Caption, rngList, 0)) Then
With PvtFld
On Error Resume Next
.PivotItems(PivotFieldName.Caption).ShowDetail = True 'Show pivot item
.PivotItems(PivotFieldName.Caption).DataRange.EntireRow.Copy
Destination:=Sheets(PivotFieldName.Caption).Range("A3")
...
..
.
Use the .DataBodyRange property instead to get all the data within the pivot
PivotTable.DataBodyRange Property (Excel)
Returns a Range object that represents the range of values in a
PivotTable. Read-only.
Syntax
expression . DataBodyRange
expression A variable that represents a PivotTable object.
As you also want the row element you can do the following you can resize the data body range according to the difference in column count between the larger TableRange2 property and that inside pivot area. Be aware that grand totals etc may affect this but this shows you how to start thinking about it. There is also a TableRange1 property available with pivots.
Example pivot:
Code:
Option Explicit
Sub test()
Dim ws As Worksheet
Dim pvt As PivotTable
Dim columnsDifference As Long
Set ws = ActiveSheet
Set pvt = ws.PivotTables("PivotTable4")
columnsDifference = pvt.TableRange2.Columns.Count - pvt.DataBodyRange.Columns.Count
With pvt.DataBodyRange
Debug.Print .Offset(, -columnsDifference).Resize(.Rows.Count, .Columns.Count + columnsDifference).Address
End With
End Sub
I would recommend reading up on referencing pivottable ranges in VBA.
There are a variety of properties that you can use to determine ranges e.g. LabelRange and DataRange for fieldItems. You seems to have explored some of these. My experience has been that these are influenced by your pivottable layout and you will need to determine the current combination of methods to get your data.
For example, I used the following to get all the data for EHB with data laid out as follows:
Option Explicit
Sub test()
Dim ws As Worksheet
Dim pvt As PivotTable
Dim columnsDifference As Long
Dim wb As Workbook
Set wb = ThisWorkbook
Set ws = wb.Worksheets("mySheetName")
Set pvt = ws.PivotTables("NEP_Pivot")
columnsDifference = pvt.TableRange2.Columns.Count - pvt.DataBodyRange.Columns.Count
With pvt.DataBodyRange
Debug.Print pvt.PivotFields("Prod. Code").PivotItems("EHB").LabelRange.Offset(-1, 0).Resize(pvt.PivotFields("Prod. Code").PivotItems("EHB").LabelRange.Rows.Count, .Columns.Count + columnsDifference).Address
End With
End Sub
This produced the result
$C$11:$N$13
Notice how I have had to combine functions to get this result and if the pivottable layout gets changed this falls apart.
I was also able to write using:
With pvt.TableRange1
Debug.Print pvt.PivotFields("Prod. Code").PivotItems("EHB").LabelRange.Resize(pvt.PivotFields("Prod. Code").PivotItems("EHB").LabelRange.Rows.Count, .Columns.Count).Offset(-1, 0).Address
End With
I have a pivot table and a slicer and I need a code that will update the width of each column to fit the value every single time I update the slicer (which updates the pivot). I know that if I got to Pivot table > options, I cant select a box that says "autofit column widths on update", but it doesn't work. So instead I'm trying to make a code that automatically does that.
I tried this:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim pt As PivotTable
For Each pt In ActiveSheet.PivotTables
columns.autofit
Next pt
End Sub
Something doesn't work though and I'm not sure what it is. Can anybody see an issue with the code? Thank you!
In order to modify the columns width in a PivotTable, you need to address the pt.TableRange1.Columns property.
Try the code below:
Dim pt As PivotTable
For Each pt In ActiveSheet.PivotTables
pt.TableRange1.Columns.AutoFit
Next pt
Got another Excel VBA Macro button issue.
I am trying to make a button to refresh all pivots on a worksheet (there are four). I have been to StackOverflow before and received a solution that worked well. I took the code I was provided before and updated it for the new workbook but it fails below with the function .ChangePivotCache PvtCache:
Sub Button1_Click()
Dim PvtTbl As PivotTable
Dim PvtCache As PivotCache
Dim PvtDataRng As Range
Set PvtDataRng = Worksheets("OTR_Promo_List_ADV_2017").Range("B2:AU500")
Set PvtCache = ActiveWorkbook.PivotCaches.Add(xlDatabase, PvtDataRng)
Set PvtTbl = Worksheets("Desired_Distribution").PivotTables("PivotTable1")
For Each PvtTbl In Worksheets("Desired_Distribution").PivotTables
Set PvtCache = ActiveWorkbook.PivotCaches.Add(xlDatabase, PvtDataRng)
With PvtTbl
.ChangePivotCache PvtCache
.RefreshTable
End With
Set PvtCache = Nothing
Next PvtTbl
End Sub
The only differences are that the workbook changed and now I want to refresh 4 pivots instead of 2 - could that be the issue?
Below a screenshot so you can see the worksheets. "OTR_Promo_List_ADV-2017" is the database. The Pivot tables have the default naming, I did not change the names (i.e. PivotTable1, PivotTable2...)
Thanks!
The code you use to refresh all pivot tables on the one sheet seems overly complex. I don't quite understand why you would want to use .ChangePivotCache at all. It changes the data source of the specified pivot table. If you just want to refresh a pivot table, that is completely unwarranted.
You can use Excel Table objects as the data source for your pivot tables, then a simple refresh will suffice. Or, if you don't want to use Tables (though you may really want to look into that, for obvious reasons), you can use dynamic range names to define the pivot source. With both techniques, you only need to refresh the pivot table and don't have to manipulate the pivot cache with VBA.
With Tables or dynamic range names as the source of pivot tables, you can refresh all pivot tables on a sheet by cycling through them and refresh them with codes along these lines:
Sub RefreshPivotsOnSheet()
Dim ws As Worksheet
Dim pt As PivotTable
Set ws = Worksheets("MySheet")
For Each pt In ws.PivotTables
pt.RefreshTable
Next pt
End Sub
Edit: How to set Excel Tables as the data source for a pivot: Turn the source data into a table with Ctrl + T or Insert > Table. Then edit the Pivot Table data source and point it to the Excel table you just created.
I was able to close this topic. I found somewhere else a simple macro that says only:
Sub REFRESH()
'
' REFRESH Macro
'
'
ActiveWorkbook.RefreshAll
End Sub
seemed to do the trick.
Thank you for all your inputs!
I found this code on Spreadsheetguru and I have an issue with editing the code.
Sub CreatePivotTable()
'PURPOSE: Creates a brand new Pivot table on a new worksheet from data in the ActiveSheet
'Source: www.TheSpreadsheetGuru.com
Dim sht As Worksheet
Dim pvtCache As PivotCache
Dim pvt As PivotTable
Dim StartPvt As String
Dim SrcData As String
'Determine the data range you want to pivot
SrcData = ActiveSheet.Name & "!" & Range("A1:R100").Address(ReferenceStyle:=xlR1C1)
'Create a new worksheet
Set sht = Sheets.Add
'Where do you want Pivot Table to start?
StartPvt = sht.Name & "!" & sht.Range("A3").Address(ReferenceStyle:=xlR1C1)
'Create Pivot Cache from Source Data
Set pvtCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=SrcData)
'Create Pivot table from Pivot Cache
Set pvt = pvtCache.CreatePivotTable( _
TableDestination:=StartPvt, _
TableName:="PivotTable1")
End Sub
Why is it not possible for me to Define SrcData as Worksheets("SHEETNAME").Range("A1:A100")? It returns a type 13 error: mismatch. I tried finding answers online and most examples referred the SrcData for ActiveSheet.Range instead of a defined sheet.
Thank you!
It would also greatly help if you could show me how an example pivot would work for the Sheet("PivotExp") on this sheet.http://imgur.com/TShQ1ls
Thank you so much!
Why is it not possible for me to Define SrcData as
Worksheets("SHEETNAME").Range("A1:A100")?
Pivot table works on 2 dimensional data (tabular form), i.e rows and columns, but with A1:A100 your are supplying only 1 dimensional data (list form). Also you need to assign source data as per syntax rules.
It returns a type 13 error: mismatch.
Mismatch error due to above reason.
It would also greatly help if you could show me how an example pivot
would work for the Sheet("PivotExp") on this
sheet.http://imgur.com/TShQ1ls
Due to some reason, image was not visible, but instead you can visit following example link : http://analysistabs.com/excel-vba/pivot-tables-examples/ which show how to create Pivot Tables with VBA code.
Since, your given code is missing lot of Pivot related information, a Pivot wont' get formed but by visiting above link you can have idea, what things are missing in it.
I'm trying to dynamically refresh some pivot tables in Excel. The pivot tables (and connected slicers - each slicer connects to multiple pivots) already exist, the underlying source data table does not. The process is as follows:
Create new sheet to hold the 'raw' data
Populate sheet, wrap data into a ListObject (table)
Create a new pivot cache from the new data
Unlink the slicers from the pivot tables
Change the pivot tables' cache to the new cache
Refresh the pivot tables
Link the slicers back up
Delete the data sheet
To clarify the structure:
One data source table. Multiple pivot tables pointing to the source. Multiple slicers, each connected to all the pivot tables (eg Week Ending slicer chages Week Ending on all the pivots)
I'm running into a problem however with step 4. The following code works:
'dataTable is a ListObject that was created on a sheet earlier in the function. Can confirm 100% that it exists and is populated.
Dim pt As PivotTable
For Each pt in PivotSheet.PivotTables
pt.ChangePivotCache ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=dataTable)
Next pt
However, it means one pivot cache per pivot table, which means I run into problems when trying to set up slicers that manipulate multiple pivots - it assumes that each pivot table has a different data source, and so will only let me link the slicer to a single pivot.
I decided the way to go would be to create a single pivot cache, and then link each pivot table to it. This code however does not work, throwing error 5 at me the first time it is reached:
'dataTable is a ListObject that was created on a sheet earlier in the function. Can confirm 100% that it exists and is populated.
Dim pc As PivotCache
Set pc = ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=dataTable)
Dim pt As PivotTable
For Each pt in PivotSheet.PivotTables
pt.ChangePivotCache pc 'Invalid Procedure Call Or Argument
Next pt
What am I doing wrong here?
Combine the two approaches:
Dim bCreated As Boolean
Dim lngMasterIndex As Long
Dim pt As PivotTable
For Each pt In PivotSheet.PivotTables
If Not bCreated Then
pt.ChangePivotCache ThisWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=DataTable)
bCreated = True
lngMasterIndex = pt.CacheIndex
Else
pt.CacheIndex = lngMasterIndex
End If
Next pt
If you hate snorkeling the code, to make it work, this is the short and dirty way to do it:
For Each pt in PivotSheet.PivotTables
On Error Resume Next
pt.ChangePivotCache pc 'works for the first entry
pt.CacheIndex = pc.Index 'works for all the others
On Error GoTo 0
Next PT