AutoFilter PivotTable source data rather than ShowDetails?

lcluff2000

New Member
Joined
Feb 10, 2012
Messages
10
On a pivotchart mouse event, I use the underlying pivottable showdetail to bring up the filtered source data (I have the row=arg1 and column=arg2 of the pivot table data from the mouse event):

ActiveChart.PivotLayout.PivotTable.DataBodyRange. _
Cells(Arg2, Arg1).ShowDetail = True

This command opens a new sheet with the filtered source data.

Rather than have a new sheet open, I would like to AutoFilter the pivottable source data that already exists on it's own sheet.

Any ideas of how I could do this based on knowing the row/col of the pivottable??
</pre>
 
I did a little more research into why the MouseUp Event is not working. I found the following forum post that states "the mouseup event seems to only work when anything but the data series is selected"

http://www.mrexcel.com/forum/showthread.php?t=553994

I found that this is essentially true. When I click on the chart title, axis title, or chart background, it will fire the event. When I click on the series or axis labels, it does not fire.

By using the MouseDown event, I am able to get this code to work.

Code:
Private Sub EvtChart_MouseDown(ByVal Button As Long, ByVal Shift As Long, ByVal x As Long, ByVal y As Long)
    MsgBox ("in mouse down")
    Dim ElementID As Long, Arg1 As Long, Arg2 As Long
    On Error GoTo ErrHandler
    ActiveChart.GetChartElement x, y, ElementID, Arg1, Arg2

    If ElementID <> xlSeries Then Exit Sub
    With ActiveChart.PivotLayout
        If .PivotTable.PivotCache.SourceType <> xlDatabase Then Exit Sub
        Call GoTo_Filtered_SourceData(PT:=.PivotTable, _
        lDataRow:=Arg2, lDataCol:=Arg1)
    End With
    Exit Sub
ErrHandler:
    If Err.Number <> 0 Then MsgBox _
        "Chart_MouseUp - Error#" & Err.Number & vbCrLf & _
        Err.Description, vbCritical, "Error", Err.HelpFile, Err.HelpContext
End Sub

I'm still not sure why the following code didn't seem to work with the Select Event
Code:
ActiveChart.GetChartElement x, y, ElementID, Arg1, Arg2
 
Upvote 0

Excel Facts

Copy a format multiple times
Select a formatted range. Double-click the Format Painter (left side of Home tab). You can paste formatting multiple times. Esc to stop
I'm really fascinated to see if this is possible. Any luck with the code for filtering the RowFields/ ColumnField?
 
Upvote 0
I'm really fascinated to see if this is possible. Any luck with the code for filtering the RowFields/ ColumnField?

Sorry that I lost track of this as an open thread.

I'll add that part tonight. It shouldn't be difficult for a given report layout like Compact. The complexity arises if the code tries to account for a different layouts applied to different fields within the same PivotTable. (I'll defer that for now). ;)

Were you able to overcome the other issue that you had regarding the MouseUp event not triggering when selecting a Data Series?

Using the code in the link you referenced, that worked fine for me.
 
Upvote 0
Thanks for taking The time to look at this.

I wasn't able to get the mouseup event working, but the mouse down event works fine.
 
Upvote 0
Below is a revised version of the GoTo_Filtered_SourceData Function.

I took the easy way out and put in the constraint that there not be multiple RowFields or ColumnFields. This eliminates the complexity of handling different Report Layouts for the fields.

I'm hoping that will be okay for you. While it's common to have mulitple RowFields in PivotTables without PivotCharts, I believe it's not typical for PivotCharts. Filtering is typically done through Report/PageFields.

Please give it a try and let me know if this does what you wanted.
Rich (BB code):
Public Function GoTo_Filtered_SourceData(pt As PivotTable, lDataRow As Long, _
        lDataCol As Long)
        
    Dim sSourceDataA1 As String
    Dim pvtField As PivotField
    Dim vVisible As Variant
    Dim lFieldNo As Long
    
    '---Get source data range and goto it
    sSourceDataA1 = Application.ConvertFormula(pt.SourceData, _
            xlR1C1, xlA1)
    Application.Goto Range(sSourceDataA1)
    
    '---Apply filters
    With Range(sSourceDataA1)
        '---Clear any existing autofilters
        .Parent.AutoFilterMode = False
        
        '---Filter for PageField VisibleItems
        For Each pvtField In pt.PageFields
            vVisible = Store_FilterItems(pvtField)
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=pvtField.SourceName, vItems:=vVisible)
        Next
        '---Filter for RowField(s) of data item at lDataRow
        If pt.RowFields.Count > 1 Then
            MsgBox "Multiple RowFields-will not be filtered"
        Else
            vVisible = pt.RowRange(lDataRow + 1).Value
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=pt.RowFields(1).SourceName, _
                vItems:=Array(vVisible))
        End If
        
        '---Filter for ColumnField(s) of data item at lDataCol
        If pt.ColumnFields.Count > 1 Then
            MsgBox "Multiple ColumnFields-will not be filtered"
        Else
            vVisible = pt.ColumnRange(2, lDataCol).Value
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=pt.ColumnFields(1).SourceName, _
                vItems:=Array(vVisible))
        End If
    End With
        
End Function
 
Last edited:
Upvote 0
With one RowField and one ColumnField this is working great.

In one instance, I use two RowFields and no ColumnFields. I can figure out how to handle not having a ColumnField, but I'm unsure how to handle multiple RowFields.

Also, it is possible for the report user to change the pivot and add RowFields and ColumnFields.

Do you have a suggestion?
 
Upvote 0
With one RowField and one ColumnField this is working great.

In one instance, I use two RowFields and no ColumnFields. I can figure out how to handle not having a ColumnField, but I'm unsure how to handle multiple RowFields.

Adding the ability to handle multiple RowFields led to an unexpected finding.

It turns out that Arg2 that is set by ActiveChart.GetChartElement doesn't directly correspond to the Row Index of the Pivot Table's DataRange.

Arg2 is an Index of the DataPoints in the PivotChart. So if there are Rows in the PivotTable that don't have associated DataPoints in the Chart, those Rows need to be added to Arg2 to find the Row Index of the Pivot Table's DataRange.

That scenario can only happen if there are multiple fields in the RowFields or ColumnFields areas- so we hadn't seen that effect in the earlier tries.

Below is a revised version of GoTo_Filtered_SourceData plus two new Functions to help the process.

Rich (BB code):
Public Function GoTo_Filtered_SourceData(PT As PivotTable, lDataRow As Long, _
        lDataCol As Long)
        
    Dim sSourceDataA1 As String
    Dim pvtField As PivotField
    Dim vVisible As Variant
    Dim lFieldNo As Long

    '---Get source data range and goto it
    sSourceDataA1 = Application.ConvertFormula(PT.SourceData, _
            xlR1C1, xlA1)
    Application.Goto Range(sSourceDataA1)
    
    '---Apply filters
    With Range(sSourceDataA1)
        '---Clear any existing autofilters
        .Parent.AutoFilterMode = False
        
        '---Filter for PageField VisibleItems
        For Each pvtField In PT.PageFields
            vVisible = Store_FilterItems(pvtField)
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=pvtField.SourceName, vItems:=vVisible)
        Next
        
'---Filter for RowField(s) of data item at lDataRow
        If PT.RowFields.Count > 1 Then
            If Has_All_Compact_RowFields(PT) Then
                 Call Filter_Multiple_RowFields(PT:=PT, _
                    lArg2:=lDataRow, rData:=.Cells)
            Else
                MsgBox "Multiple RowFields (not Compact)-will not be filtered"
            End If
        ElseIf PT.ColumnFields.Count = 1 Then
            vVisible = PT.RowRange(lDataRow + 1).Value
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=PT.RowFields(1).SourceName, _
                vItems:=Array(vVisible))
        End If
        
'---Filter for ColumnField of data item at lDataCol
        If PT.ColumnFields.Count > 1 Then
            MsgBox "Multiple ColumnFields-will not be filtered"
        ElseIf PT.ColumnFields.Count = 1 Then
            vVisible = PT.ColumnRange(2, lDataCol).Value
            Call Filter_AutoFilterField(rData:=.Cells, _
                sHeader:=PT.ColumnFields(1).SourceName, _
                vItems:=Array(vVisible))
        End If
    End With
        
End Function

Private Function Filter_Multiple_RowFields(PT As PivotTable, _
        lArg2 As Long, rData As Range)
        
    Dim rLabels As Range, sField As String, sChildField As String
    Dim vFields As Variant, vVisible As Variant
    Dim lPosition As Long, lIdx As Long, i As Long

    '---Make array of rowfields by position to trace each row in hierarchy
     With PT.RowFields
        ReDim vFields(1 To .Count)
        For lIdx = 1 To .Count
            vFields(PT.RowFields(lIdx).Position) = PT.RowFields(lIdx).Name
        Next lIdx
    End With

    '---Set rLabels as subset of RowRange: bottom row is associated with lArg2
    With PT.RowRange
        sChildField = vFields(UBound(vFields))
        Set rLabels = .Cells(2)
        While lArg2 > 0
            i = i + 1
            If rLabels(i).PivotField.Name >= sChildField Then _
                lArg2 = lArg2 - 1
        Wend
        Set rLabels = .Offset(1).Resize(i)
    End With
    
    '---Find Field-PivotItem pairs and Apply to AutoFilter
    lIdx = lIdx + 1
    For i = rLabels.Rows.Count To 1 Step -1
        sField = rLabels(i).PivotField.Name
        lPosition = Application.Match(sField, vFields, 0)
        If lPosition < lIdx Then
            vVisible = rLabels(i).PivotItem.Name
            Call Filter_AutoFilterField(rData:=rData, _
                sHeader:=sField, vItems:=Array(vVisible))
            lIdx = lPosition
            If lIdx = 1 Then Exit For
        End If
    Next i
End Function

Private Function Has_All_Compact_RowFields(PT As PivotTable) As Boolean
'---Returns True if all PivotFields are Compact Layout
    Dim pvtField As PivotField
    
    For Each pvtField In PT.RowFields
        If Not pvtField.LayoutCompactRow Then
            Has_All_Compact_RowFields = False
            Exit Function
        End If
    Next pvtField
    Has_All_Compact_RowFields = True
End Function

Also, it is possible for the report user to change the pivot and add RowFields and ColumnFields.

Do you have a suggestion?

I'm not sure that I understand your question. If the fields are already part of the DataSource, then there are several ways the user could add RowFields and ColumnFields including through Showing the Field List Pane.
 
Last edited:
Upvote 0

Forum statistics

Threads
1,224,846
Messages
6,181,307
Members
453,031
Latest member
Chris_1

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