I currently have some VBA code that essentially replaces a Filter Field in a PivotTable, but because the current excel spreadsheet has hundreds of PivotTables, I'm reaching to a point where the VBA doesn't work with Procedure too large.
Problem is I don't know how to decrease the repetition - any assistance would be certainly appreciated.
Code below:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("P6:P7")) Is Nothing Then Exit Sub
Dim pt As PivotTable
Dim Field As PivotField
Dim NewCat As String
Set pt = Worksheets("Pivot Booking").PivotTables("PivotTable8")
Set Field = pt.PivotFields("Company Code")
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
With pt
Field.ClearAllFilters
Field.CurrentPage = NewCat
End With
Set pt = Worksheets("Pivot Booking").PivotTables("PivotTable6")
Set Field = pt.PivotFields("Company Code")
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
With pt
Field.ClearAllFilters
Field.CurrentPage = NewCat
End With
Set pt = Worksheets("Pivot Booking").PivotTables("PivotTable20")
Set Field = pt.PivotFields("Company Code")
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
With pt
Field.ClearAllFilters
Field.CurrentPage = NewCat
End With
Set pt = Worksheets("Pivot Booking").PivotTables("PivotTable7")
Set Field = pt.PivotFields("Company Code")
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
With pt
Field.ClearAllFilters
Field.CurrentPage = NewCat
'Keeps on repeating for about 200 more PivotTables in Various Sheets
End With
End Sub
If you want to change all the pivot tables on that sheet:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("P6:P7")) Is Nothing Then Exit Sub
Dim pt As PivotTable, NewCat As String, s
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
For Each s In Array("Pivot Booking", "Pivot Transaction", _
"Pivot Level Segment")
For Each pt In Worksheets(s).PivotTables
With pt.PivotFields("Company Code")
.ClearAllFilters
.CurrentPage = NewCat
End With
Next pt
Next s
End Sub
Thank you all - the complete code that has worked is as per below:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("P6:P7")) Is Nothing Then Exit Sub
Application.EnableEvents = False
On Error GoTo ErrorHandler
Dim pt As PivotTable, NewCat As String, s
NewCat = Worksheets("Trending&Benchmarking").Range("P6").Value
For Each s In Array("Pivot Booking", "Pivot Transaction", "Pivot Level Segment", "Pivot YoY TransactionGraph")
For Each pt In Worksheets(s).PivotTables
With pt.PivotFields("Company Code")
.ClearAllFilters
.CurrentPage = NewCat
End With
Next pt
Next s
ErrorHandler:
Debug.Print Err.Number & vbNewLine & Err.Description
Resume ErrorExit
ErrorExit:
Application.EnableEvents = True
Exit Sub
End Sub
Related
I work with OLAP Cubes and have created code on several occasions for different purposes but now I would like to combine several functions, how do I succeed with that?
This is what I need help putting together. I am a real beginner and have solved most things through google before but now I cant find anything that I understand or that helps me.
1)
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$A$5" Then Exit Sub
On Error Resume Next
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim ws As Worksheet
For Each ws In Worksheets
For Each pt In ws.PivotTables
pt.PivotFields("[Casino].[Casino].[Casino]").CurrentPageName = "[Casino].[Casino].&[" & Format(ActiveSheet.Cells(5, 1).Value, "") & "]"
pt.PivotFields
Next pt
Next ws
GoTo Sluta
Fel:
MsgBox "Något gick fel :("
Sluta:
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$A$3" Then Exit Sub
On Error Resume Next
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim ws As Worksheet
For Each ws In Worksheets
For Each pt In ws.PivotTables
pt.PivotFields("[Date].[Month Number].[Month Number]").CurrentPageName = "[Date].[Month Number].&[" & Format(ActiveSheet.Cells(3, 1).Value, "") & "]"
pt.PivotFields
Next pt
Next ws
GoTo Sluta
Fel:
MsgBox "Något gick fel :("
Sluta:
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address <> "$A$2" Then Exit Sub
On Error Resume Next
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim ws As Worksheet
For Each ws In Worksheets
For Each pt In ws.PivotTables
pt.PivotFields("[Date].[Year].[Year]").CurrentPageName = "[Date].[Year].&[" & Format(ActiveSheet.Cells(2, 1).Value, "") & "]"
pt.PivotFields
Next pt
Next ws
GoTo Sluta
Fel:
MsgBox "Något gick fel :("
Sluta:
Application.ScreenUpdating = True
End Sub
Write everything in one procedure and do not repeat your code.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim PivFld As String
Dim PageName As String
On Error GoTo Fel
Application.ScreenUpdating = False
Select Case Target.Address
Case "$A$5"
PivFld = "[Casino].[Casino].[Casino]"
PageName = "[Casino].[Casino].&[" & Format(ActiveSheet.Cells(5, 1).Value, "") & "]"
Case "$A$3"
PivFld = "[Date].[Month Number].[Month Number]"
PageName = "[Date].[Month Number].&[" & Format(ActiveSheet.Cells(3, 1).Value, "") & "]"
Case "$A$2"
PivFld = "[Date].[Year].[Year]"
PageName = "[Date].[Year].&[" & Format(ActiveSheet.Cells(2, 1).Value, "") & "]"
Case Else
Exit Sub
End Select
Dim ws As Worksheet
For Each ws In Worksheets
Dim pt As PivotTable
For Each pt In ws.PivotTables
pt.PivotFields(PivFld).CurrentPageName = PageName
pt.PivotFields
Next pt
Next ws
GoTo Sluta
Fel:
MsgBox "Något gick fel :("
Sluta:
Application.ScreenUpdating = True
End Sub
Note that On Error Resume Next hides all error messages and you will never know if something goes wrong. Instead use On Error GoTo Fel and at least you get informed that something went wrong.
you can combine all the ones into a single code and use if-statements for the differences:
Private Sub Worksheet_Change(ByVal Target As Range)
Dim fields As String
Dim pageName as String
If Target.Address = "$A$5" Then fields="[Casino].[Casino].[Casino]": pageName = "[Casino].[Casino].&["
If Target.Address = "$A$3" Then fields="[Date].[Month Number].[Month Number]": pageName = "[Date].[Month Number].&["
If Target.Address = "$A$2" Then fields="[Date].[Year].[Year]": pageName = "[Date].[Year].&["
If fields = "" Then Exit Sub
On Error Resume Next
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim ws As Worksheet
For Each ws In Worksheets
For Each pt In ws.PivotTables
pt.PivotFields(fields).CurrentPageName = pageName & Format(Target.Value, "") & "]"
pt.PivotFields
Next pt
Next ws
GoTo Sluta
Fel:
MsgBox "Något gick fel :("
Sluta:
Application.ScreenUpdating = True
End Sub
Also adding variables fields and pageName to simplify.
hope everyone is well.
Ive got this code that makes a slicer selection (first item):
Sub test()
Dim sc As SlicerCache
Set sc = ActiveWorkbook.SlicerCaches("Slicer_book1")
On Error GoTo errHandler
Application.ScreenUpdating = False
Application.EnableEvents = False
For Each pt In sc.PivotTables
pt.ManualUpdate = True
Next pt
With ActiveWorkbook.SlicerCaches("Slicer_book1")
.ClearManualFilter
cnt = .SlicerItems.Count
If cnt > 1 Then
For i = 2 To cnt
.SlicerItems(i).Selected = False
Next
End If
End With
For Each pt In sc.PivotTables
pt.ManualUpdate = False
Next pt
exitHandler:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
errHandler:
MsgBox ("Error in updating slicer filters.")
Resume exitHandler
somehow, this code works, but it is incedibly show. So, I was wondering whether anyone has any advice re how to properly speed this up?
Thanks and regards.
I prefer to use the pivot table name than slicer.
Sub test()
Dim sc As SlicerCache
Dim SIName As String
Dim pt As PivotTable, PTF As PivotField
Set sc = ActiveWorkbook.SlicerCaches("Slicer_book1")
On Error GoTo errHandler
Application.ScreenUpdating = False
Application.EnableEvents = False
For Each pt In sc.PivotTables
pt.ManualUpdate = True
Next pt
With ActiveWorkbook.SlicerCaches("Slicer_book1")
'.ClearManualFilter
cnt = .SlicerItems.Count
If cnt > 1 Then
SIName = .SlicerItems(1).Name
End If
End With
'Pivot is the sheet name where the pivot table is located
ActiveWorkbook.Worksheets("Pivot").Activate
Set pt = ActiveWorkbook.Worksheets("Pivot").PivotTables("NameOfPivotTable")
'Book is pivot field
Set PTF = pt.PivotFields("Book")
PTF.ClearAllFilters
PTF.CurrentPage = SIName
For Each pt In sc.PivotTables
pt.ManualUpdate = False
Next pt
exitHandler:
Application.ScreenUpdating = True
Application.EnableEvents = True
Exit Sub
errHandler:
MsgBox ("Error in updating slicer filters.")
Resume exitHandler
End Sub
Hope this help
My goal is to filter PivotTable3 based on the active cell selected on the project dashboard sheet. The range for NewCat is set to "U10" but I would like any active cell selected to be the driver for the filter.
NewCat = Worksheets("Project Dash").Range("U10").Value
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Intersect(Target, Range("U8:U37")) Is Nothing Then Exit Sub
Dim pt As PivotTable
Dim Field As PivotField
Dim NewCat As String
Set pt = Worksheets("mPIVOTS").PivotTables("PivotTable3")
Set Field = pt.PivotFields("Project")
NewCat = Worksheets("Project Dash").Range("U10").Value
With pt
Field.ClearAllFilters
Field.CurrentPage = NewCat
pt.RefreshTable
End With
End Sub
I'm not sure if I understand it correctly, but how about changing this line:
NewCat = Worksheets("Project Dash").Range("U10").Value
To this:
NewCat = Target.Value
I am trying to show / hide pivot items based on a drop down selection.
If you see the code below, cell S3 is a drop down with options - All, Jan, Feb.. Dec. When I change the drop down, I want to show only the pivot items of the selected month.
What is happening here is, once I set an item visibility to false, I am not able to make it visible again. So, the for each loop below simply ignores those items that have been hidden earlier
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pt As PivotTable, counter
Dim pi As PivotItem, msg, mname
Application.EnableEvents = False
If Target.Address = "$S$3" Then
Application.EnableEvents = False
Set pt = Sheet3.PivotTables(1)
mname = Sheet2.Range("S3").Value
pt.RefreshTable
For Each pi In pt.PivotFields("Values").PivotItems
If InStr(pi, mname) > 0 Or mname = "All" Then
pi.Visible = True
Else
pi.Visible = False
End If
Next pi
End If
Application.EnableEvents = True
End Sub
Screenshot of my Pivot Table
Try the code below (explanation inside the code as commnets):
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim pt As PivotTable
Dim pi As PivotItem
Dim pf As PivotField
Dim msg As String, mname As String
'Dim counter ' <-- not used in this piece of code
If Target.Address = "$S$3" Then
Application.EnableEvents = False
' set the PivotTable object
Set pt = Sheet3.PivotTables(1)
mname = Target.Value ' <-- you can use the Target object
pt.RefreshTable
' set the PivotField object
Set pf = pt.PivotFields("Values")
pf.ClearAllFilters ' clear all previous filters from "Values"
' if value is "All", show all items, (no need to run the loop)
If mname <> "All" Then
For Each pi In pf.PivotItems
If Not pi.Name Like "*" & mname & "*" Then ' only if the value is not like the month >> hide the PivotItem
pi.Visible = False
End If
Next pi
End If
End If
Application.EnableEvents = True
End Sub
everyone.
I was using the Sub ClearColumns to clear all field in the column area from a Pivot Table.
Sub ClearColumns()
Dim PT As PivotTable, PF As PivotField
Set PT = ActiveSheet.PivotTables("Tb1")
With PT
For Each PF In .ColumnFields
PF.Orientation = xlHidden
Next PF
End With
Set PT = Nothing
End Sub
But now that i started using PowerPivot, the code doesnt Work. I think the fields are no longer PivotField, but CubeFields. It Is possible to make the same macro above, but for Cubefields? I tried different things, but i cant make it work.
Sub ClearColumnsPP()
Dim PT As PivotTable, PF As CubeFields
Dim strSource As String
Dim strName As String
Set PT = ActiveSheet.PivotTables("Tb1")
With PT
For Each PF In .ColumnFields
strSource = PF.SourceName
strName = PF.Name
PF(strSource, strName).Orientation = xlHidden
Next PF
End With
Set PT = Nothing
End Sub
Thanks!!
You need to check the orientation of the CubeField, and only set to hidden if it is a Column field:
Sub foo()
Dim pt As PivotTable
Dim cf As CubeField
Set pt = ActiveSheet.PivotTables("Tb1")
For Each cf In pt.CubeFields
If cf.Orientation = xlColumnField Then cf.Orientation = xlHidden
Next cf
End Sub