Updating Pivotfields from a Data Validation list across multiple Pivot Tables on Multiple sheets

Carpenter447

New Member
Joined
Mar 5, 2012
Messages
10
Hello I have an issue that i have been playing around with my self for quite sometime now. I found a code that should work but for some reason it is not working and I haven't a clue why. Any help would be appreciated.

Goal : Code that will take a drop list and modify the pivot filters on multiple pivot tables on multiple sheets simultaneously. I.e. Drop list selection is Brown; Brown is part of the Filter Colors; All subsequent pivot tables with the same Filter for colors would then switch to brown and update the data within it.

Issue : The coding works on a sample set that I ripped from contexures.com but not for my data as it stands now.

Additional Info : I am running Excel 2007, I import that data within my pivots from an OLAP cube, & even though I work with macros quite often my actual verbatim writing skills are limited.

So the code below is an adapted version of what you can find on contextures website. I want to be able change three unique Pivot Fields simultaneously. The code string is simply triplicated below with the different fields inputted. When I use the initial code from contexture.com it works but then when i change the Pivotfield nothing happens.

Code:
Sub UpdatePivotFields()
Dim ws As Worksheet
Dim pt As PivotTable
Dim pi As PivotItem
Dim strField1 As String
Dim strField2 As String
Dim strField3 As String

On Error Resume Next
Application.ScreenUpdating = False
Application.EnableEvents = False

'This sector changes strField1 or "Top Customer Name US"
strField1 = "Top Customer Name US"
    If Target.Address = Range("D2").Address Then
        For Each ws In ThisWorkbook.Worksheets
            For Each pt In ws.PivotTables
                With pt.PageFields(strField1)
                    For Each pi In .PivotItems
                        If pi.Value = Target.Value Then
                            .CurrentPage = Target.Value
                            Exit For
                        Else
                            .CurrentPage = "(All)"
                        End If
                    Next pi
                End With
            Next pt
        Next ws
    End If

'This sector changes strField2 or "_Plant"
strField2 = "_Plant"
    If Target.Address = Range("M2").Address Then
        For Each ws In ThisWorkbook.Worksheets
            For Each pt In ws.PivotTables
                With pt.PageFields(strField1)
                    For Each pi In .PivotItems
                        If pi.Value = Target.Value Then
                            .CurrentPage = Target.Value
                            Exit For
                        Else
                            .CurrentPage = "(All)"
                        End If
                    Next pi
                End With
            Next pt
        Next ws
    End If

'This sector changes strField3 or "Month"
strField3 = "Month"
    If Target.Address = Range("U2").Address Then
        For Each ws In ThisWorkbook.Worksheets
            For Each pt In ws.PivotTables
                With pt.PageFields(strField1)
                    For Each pi In .PivotItems
                        If pi.Value = Target.Value Then
                            .CurrentPage = Target.Value
                            Exit For
                        Else
                            .CurrentPage = "(All)"
                        End If
                    Next pi
                End With
            Next pt
        Next ws
    End If
End Sub
 

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes
Jerry,

Thanks for the reply I have read through the thread you linked to in your last post and the method used should work for my data sets. I'm struggle is understanding the code below that sbmaurer posted in the thread.

I think I may need a little help modifying it to work with my data sets.

Code:
Private Function Filter_Cube_PivotField(pvtField As PivotField, _
        varArrIn As Variant)
    Dim varExists() As Variant
    Dim i As Long, lCount As Long
    On Error Resume Next
    Application.ScreenUpdating = False
    With pvtField
        For i = LBound(varArrIn) To UBound(varArrIn)
            .VisibleItemsList = Array(varArrIn(i))
            If (varArrIn(i) = .VisibleItemsList(1)) Then
                lCount = lCount + 1
                ReDim Preserve varExists(lCount)
                varExists(lCount) = varArrIn(i)
            End If
        Next
        If lCount > 0 Then .VisibleItemsList = varExists
    End With
End Function
Sub Filter_Cube_ItemListInCode(Worksht As String, TableName As String)
    Dim sItems As String
    sItems = OLAP_Format_Date(dtIn:=Worksheets("UpdatingInstructions").Range("O9").Value)
    
    Filter_Cube_PivotField _
        pvtField:=Worksheets(Worksht).PivotTables(TableName) _
        .PivotFields("[Date].[Month Filter].[Month Filter]"), _
            varArrIn:=Array(sItems)
End Sub
Function OLAP_Format_Date(dtIn As Date) As String
'---builds string to reference OLAP item
'---example: "[Date].[Month Filter].&[2011]&[9]&[Sep 2011]"
    OLAP_Format_Date = "[Date].[Month Filter].&[" & _
        Year(dtIn) & "]&[" & Month(dtIn) & "]&[" & _
        Format(dtIn, "Mmm YYYY") & "]"
End Function
Sub Test_OLAP_Format()
    MsgBox OLAP_Format_Date(dtIn:=Worksheets("UpdatingInstructions").Range("O9").Value)
End Sub
Sub UpdateAll()
Call Filter_Cube_ItemListInCode("Top15PL", "15PolymerSales")
Call Filter_Cube_ItemListInCode("Top15PL", "15PolymerRM")
Call Filter_Cube_ItemListInCode("Top15PL", "15PolymerCust")
Call Filter_Cube_ItemListInCode("Top15PL", "15IndustrialSales")
Call Filter_Cube_ItemListInCode("Top15PL", "15IndustrialRM")
Call Filter_Cube_ItemListInCode("Top15PL", "15IndustrialCust")
Call Filter_Cube_ItemListInCode("Top15PL", "15ConsumerSales")
Call Filter_Cube_ItemListInCode("Top15PL", "15ConsumerRM")
Call Filter_Cube_ItemListInCode("Top15PL", "15ConsumerCust")
Call Filter_Cube_ItemListInCode("RMTrends", "PolymerTrendRM")
Call Filter_Cube_ItemListInCode("RMTrends", "IndustrialTrendRM")
Call Filter_Cube_ItemListInCode("RMTrends", "ConsumerTrendRM")
End Sub

Do you think you could explain or help me modify the code above for three filters that will have explicit values as follows:

Syntax of PivotFields and PivotItems within them:
"Top Customer Name US"
- String Name such as "CUSTOMER"
"_Plant"
- String Name such as "9999-Plant"
"Month"
- String Name such as "Mar-12"

Each of these PivotFields are set-up as validation lists that have all possible PivotItems for each filter within them. Goal is for user to select from the drop down one item for each filter and on selection all filters on all pivottable on all worksheets will simultaneously update.

Right now I actually update on an ad hoc basis by going into each filter on each pivot on every sheet and updating the fields needed for the report.

Let me know what you think, and thanks for your help in advance it is much appreciated!
 
Upvote 0
Sure, I can help, but I probably won't be able to get to this until later today.

It would be helpful if you could use the Macro-Recorder to record syntax needed to filter one pivot table for an example like the one you show above.
 
Upvote 0
Jerry,

Thanks for being so on top of this you are really blowing my expectations for the responses out of the water!

Here is the code from recording my filter changes:

Code:
Sub Recorded_ChangingFilters_Manual()
    ActiveSheet.PivotTables("PivotTable7").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array( _
        "[TopCustomersUS].[Top Customer Name US].&[GIANT EAGLE]")
    ActiveSheet.PivotTables("PivotTable7").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("")
    ActiveSheet.PivotTables("PivotTable7").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("[TopCustomersUS].[Top Customer Name US].&[MEIJER]")
        
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Plant].[_Plant].[_Plant]") _
        .CurrentPageName = "[Plant].[_Plant].&[1331]"
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Plant].[_Plant].[_Plant]") _
        .ClearAllFilters
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Plant].[_Plant].[_Plant]") _
        .CurrentPageName = "[Plant].[_Plant].&[1330]"
        
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[201299]"
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Time].[Month].[Month]"). _
        ClearAllFilters
    ActiveSheet.PivotTables("PivotTable7").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[201298]"
End Sub

Let me know what you think. Again this was for only on Pivot table above so for good measure below is a set of code changing a few different pivots.

Code:
Sub Recorded_ChangingMultiplePivots()

    ActiveSheet.PivotTables("PivotTable1").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("")
    ActiveSheet.PivotTables("PivotTable1").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("[TopCustomersUS].[Top Customer Name US].&[MEIJER]")
    ActiveSheet.PivotTables("PivotTable1").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("")
    ActiveSheet.PivotTables("PivotTable1").PivotFields( _
        "[TopCustomersUS].[Top Customer Name US].[Top Customer Name US]"). _
        VisibleItemsList = Array("[TopCustomersUS].[Top Customer Name US].&[MEIJER]")
        
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .ClearAllFilters
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .CurrentPageName = "[Plant].[_Plant].&[2306]"
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .ClearAllFilters
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .CurrentPageName = "[Plant].[_Plant].&[2600]"
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .ClearAllFilters
    ActiveSheet.PivotTables("PivotTable2").PivotFields("[Plant].[_Plant].[_Plant]") _
        .CurrentPageName = "[Plant].[_Plant].&[1330]"
    
    ActiveSheet.PivotTables("PivotTable1").PivotFields("[Time].[Month].[Month]"). _
        ClearAllFilters
    ActiveSheet.PivotTables("PivotTable1").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[2012105]"
        
    ActiveSheet.PivotTables("PivotTable3").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[2012100]"
    ActiveSheet.PivotTables("PivotTable3").PivotFields("[Time].[Month].[Month]"). _
        ClearAllFilters
    ActiveSheet.PivotTables("PivotTable3").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[201299]"
        
    ActiveSheet.PivotTables("PivotTable1").PivotFields("[Time].[Month].[Month]"). _
        ClearAllFilters
    ActiveSheet.PivotTables("PivotTable1").PivotFields("[Time].[Month].[Month]"). _
        CurrentPageName = "[Time].[Month].&[201298]"
End Sub
 
Upvote 0
That helps- thanks.

The code examples I referenced have some checking and features that are probably unecessary for your application and would cause the macro to run slower than it could.

Your answers to a few questions will help in making the code efficient.
1. Is there a possibility that a selection made from the Data Validation (DV) dropdown, won't exist as a PivotItem?

2. Will all 3 fields be PageFields?

3. When one of the 3 DV cells is changed, the code could either update all 3 fields or just the one field associated with that DV cell.

The first approach will ensure your PivotTables are consistent with the values currently displayed in D2, M2 and U2.
The second approach is more efficient (faster), but if someone manually filters the PivotTable, instead of using the 3 dropdowns, you could get a misleading result in which the PivotTable displayed doesn't match all 3 dropdowns.

Which would be better for you (Option 1-Consistency or Option 2-Speed)?
 
Upvote 0
1. Is there a possibility that a selection made from the Data Validation (DV) dropdown, won't exist as a PivotItem?

- No there is no possibility as I used the exact possible choices from the PivotItem to put into the DV Dropdown.

2. Will all 3 fields be PageFields?

- All three should be PageFields, but I am a little shaky in answering that because I'm not complete positive on what you are asking. Maybe explain just a bit more on that.

3. When one of the 3 DV cells is changed, the code could either update all 3 fields or just the one field associated with that DV cell.

The first approach will ensure your PivotTables are consistent with the values currently displayed in D2, M2 and U2.
The second approach is more efficient (faster), but if someone manually filters the PivotTable, instead of using the 3 dropdowns, you could get a misleading result in which the PivotTable displayed doesn't match all 3 dropdowns.

Which would be better for you (Option 1-Consistency or Option 2-Speed)?

- I will have the pivots hidden in the background and locked so that no one has the option to change the pivots manually. What this actually is creating is a pivot chart dashboard that has three dropdowns to slice and dice the various charts (pivots in the background).

If I understand correctly the first option would allow for the items to for sure be modified on a 1:1 basis consistently. i.e DV->Choose "1330"->All pivots for "Plant" Pivot Field change to 1330.

And, the second one will do the same thing but will not feed the item back to the DV if the actual table is change, which from my statement above should never happen.

I think overall I would rather have speed on the assumption that my above comments are correct.

One thing from your 3) point is a little confusing for me. when you say:

...the code could either update all 3 fields or just the one field associated with that DV cell.

Do you mean that the one field as in the Pivot field will be changed so that each time a new selection is made the tables update? or are you saying that each time a selection is made you can only change one thing? The other question is around the same quote. Do you mean that the code from the first option would wait for all fields to be updated before it syncs with the tables?

Thanks again for your help. Any additional clarification would be greatly appreciated.
 
Upvote 0
- All three should be PageFields, but I am a little shaky in answering that because I'm not complete positive on what you are asking. Maybe explain just a bit more on that.

If you Show the PivotTable Field List, it's organized to let you drag and drop fields into different areas of your PivotTable.

In xl2010 the areas are labeled:
* Report Filter
* Row Labels
* Column Labels
* Values

In some earlier versions, the Report Filter Field was called the Page Filter and in VBA that area is still called PageFields.

Your recorded macro uses the .CurrentPageName Property, so it's clearly a PageField.

My question was confirming that the code would not have to allow for the possibility that you reorganize the PivotTable by moving any of the 3 fields being filtered to the Row Labels or Column Labels area of the PT.


One thing from your 3) point is a little confusing for me. when you say:

Do you mean that the one field as in the Pivot field will be changed so that each time a new selection is made the tables update? or are you saying that each time a selection is made you can only change one thing? The other question is around the same quote. Do you mean that the code from the first option would wait for all fields to be updated before it syncs with the tables?

In both options, the code would immediately update the PivotField associated with the changed DV cell in all PivotTables.

For Option 1-Consistency, there would an additional step that would update the other 2 PivotFields whose DV cells were not just changed.

Based on your responses, Option 2- optimize for Speed looks like the better choice.

I'll post some code later today.
 
Upvote 0
Gotcha. Sounds like a plan. I will likely be back on later tonight. I am using XL2007 just for your reference.

My question was confirming that the code would not have to allow for the possibility that you reorganize the PivotTable by moving any of the 3 fields being filtered to the Row Labels or Column Labels area of the PT.

And, yes there will be no moving fields to other field list areas as its solely a static update of what the filter value is.

On another note how did you reference my post directly in your last post?

Look forward to hearing from you!
 
Upvote 0

Forum statistics

Threads
1,223,227
Messages
6,170,848
Members
452,361
Latest member
d3ad3y3

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top