Use VBA to capture the fields in pivot table - vba

We can use below code to build a Pivot Table (This is a pivot table created by Power Pivot).
With ActiveSheet.PivotTables("PivotTable1").CubeFields(FieldName)
.Orientation = Orientation
.Position = Position
Is there some way to reverse the process? Suppose user has built a pivot table. We use VBA to capture the fields used on the table (find out corresponding FieldName(s), Orientation(s), and Position(s)) and save them, so next time, user can just run the macro and create the same pivot table again.
Thanks

Thanks to #OpiesDad. Below will work.
Sub Func1()
Dim objCubeFld As PivotField
Dim pvt As PivotTable
Set pvt = ActiveSheet.PivotTables("PivotTable1")
For Each objCubeFld In pvt.PivotFields
MsgBox objCubeFld & "-" & objCubeFld.Orientation
Next objCubeFld
End Sub

Related

How to link cell value as a filter in PowerPivot Pivot Table in Excel?

I have two Pivot Table (PivotTable1 and PivotTable2) in Sheet PivotTables_Sheetand a cell that shows the year in Sheet YearInput. I tried to link the cell year (J4) in YearInput as a filter to all pivot tables in PivotTables Sheet.
But somehow my code doesn't work as expected. Anybody knows how to correct this code?
This is the code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Target.Address = Range("J4").Address Then Exit Sub
Dim pt As PivotTable
Dim ptItem As PivotItem
On Error Resume Next
For Each pt In Worksheets("PivotTables_Sheet").PivotTables
With pt.PivotFields("Year for Sales")
If .EnableMultiplePageItems = True Then
.ClearAllFilters
End If
Set ptItem = .PivotItems(Target.Value)
If Not ptItem Is Nothing Then
.CurrentPage = Target.Value
End If
End With
Next
End Sub
Note: I use Excel 2010 and built the pivot tables using PowerPivot.
One way to do this without VBA is to use a slicer which is common between all the pivots. Then one year is changed on one, it will also update the other pivot tables.
This is by first clicking on the pivot, which will then show on the ribbon an Analyze option. Under that there is an insert slicer, which you would do for year.
Afterwards you would go to your other pivots and instead do filter connection, and select your year slicer.
Note that the year slicer can then just be moved to a hidden sheet if you do not want the end user to see it, it will still do its job of propagating the year across all the pivots that are referencing it.

Run time error -2147024809 (80070057) - Pivot Table field name is not valid

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!

Invalid Procedure Call Or Argument - attempting to dynamically change pivot cache

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

deleting pivot field from pivot table field list in VBA

Is it possible to delete pivot field from pivot table field list in VBA code?
I am using Excel 2007.
I haven't worked for a long time with Excel + VBA, but have you tried something like:
Dim pvtField As Excel.PivotField
Dim pvtItem As Excel.PivotItem
For Each pvtField In pvtTable.PivotFields
For Each pvtItem In pvtField.PivotItems
pvtItem.Delete
Next
Next
This code should work to delete a field from the pivot table.
ActiveSheet.PivotTables("Name of Table").PivotFields( _
"Name of Field").Orientation = xlHidden

Excel VBA: Output Distinct Values and Subtotals

I have data of this form:
Category Source Amount
Dues FTW $100
Donations ODP $20
Donations IOI $33
Dues MMK $124
There is no sort order. The categories are unknown at compile time. I want a VBA macro to cycle through the range, output a list of distinct values, with the subtotals for each. For the above data, it would look like this:
Category Total Amount
Dues $224
Donations $55
How can I do this? Also, is there a way to make the macro run every time the table above is updated, or is it necessary for the user to click a button?
You may want to use a built in Excel feature to do this. Looping can take a long time and be problematic if you have a lot of values to loop through.
Something like the following might get you started on creating a pivot table (from http://www.ozgrid.com/News/pivot-tables.htm)
Sub MakeTable()
Dim Pt As PivotTable
Dim strField As String
'Pass heading to a String variable
strField = Selection.Cells(1, 1).Text
'Name the list range
Range(Selection, Selection.End(xlDown)).Name = "Items"
'Create the Pivot Table based off our named list range.
'TableDestination:="" will force it onto a new sheet
ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _
SourceData:="=Items").CreatePivotTable TableDestination:="", _
TableName:="ItemList"
'Set a Pivot Table variable to our new Pivot Table
Set Pt = ActiveSheet.PivotTables("ItemList")
'Place the Pivot Table to Start from A3 on the new sheet
ActiveSheet.PivotTableWizard TableDestination:=Cells(3, 1)
'Move the list heading to the Row Field
Pt.AddFields RowFields:=strField
'Move the list heading to the Data Field
Pt.PivotFields(strField).Orientation = xlDataField
End Sub
This is for subtotals (though I much prefer pivot tables)
http://msdn.microsoft.com/en-us/library/aa213577(office.11).aspx
EDIT:
I reread and have the following thoughts. Set up the pivot table on a separate sheet (without using any code) then put the following code on the sheet that has the pivot table so that the table will update everytime the sheet is selected.
Private Sub Worksheet_Activate()
Dim pt As PivotTable
'change "MiPivot" to the name of your pivot table
Set pt = ActiveSheet.PivotTables("MyPivot")
pt.RefreshTable
End Sub
Edit #2
Refresh all pivot tables on sheet
http://www.ozgrid.com/VBA/pivot-table-refresh.htm
Private Sub Worksheet_Activate()
Dim pt As PivotTable
For Each pt In ActiveSheet.PivotTables
pt.RefreshTable
Next pt
End Sub
The link has multiple options on how to refresh pivot tables in the sheet/workbook.