0
votes

Hi please can someone help, Excel 2016 VBA PivotTable objects. I rarely develop in Excel VBA.

Overall goal: Compare a single column [P_ID] value list from PivotTable2 against PivotTable1 if they exist or not to enable filtering on those valid values in PivotTable1.

I have some Excel 2016 VBA code which I have adapted from a previous answer from a different internet source.

Logic is: gather data from PivotTable2 from the ComparisonTable dataset (in PowerPivot model), field [P_ID] list of values. Generate a test line as input into function to test for existence of field and value in PivotTable1 against the Mastertable dataset, if true add the line as valid if not skip the line. Finally filter PivotTable1 with the VALID P_ID values.

It works to a point until it gets to the bFieldItemExists function which generates an error:

Run-time error '1004' Unable to get the PivotItems property of the PivotField class

Can someone please correct the way of this not working?

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)

Dim MyArray As Variant, _
    ar As Variant, _
    x As String, _
    y As String, _
    str As Variant

MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("[ComparisonTable].[P_ID].[P_ID]").DataRange

For Each ar In MyArray
    x = "[MasterTable].[P_ID].&[" & ar & "]"

    If ar <> "" And bFieldItemExists(x) = True Then
        If str = "" Then
            str = "[MasterTable].[P_ID].&[" & ar & "]"
        Else
            str = str & "," & "[MasterTable].[P_ID].&[" & ar & "]"
        End If
    End If
Next ar


Dim str2() As String

    str2 = Split(str, ",")

    Application.EnableEvents = False
    Application.ScreenUpdating = False

        ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").VisibleItemsList = Array(str2)

    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub


Function bFieldItemExists(strName As String) As Boolean
    Dim strTemp As Variant

    ' This line does not work!?
  strTemp = ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").PivotItems(strName)

If Err = 0 Then bFieldItemExists = True Else bFieldItemExists = False

End Function
1
There are several problems I see. First you should declare MyArray As Range as well as ar As Range. In your statement you are attempting to cast ar from a variant, which is a vbObject, to a string. This Microsoft Docs Article will help point you in the right direction. You should also review articles on PivotItem and PivotItems.Jamie Riis
I changed MyArray As Range and ar As Range and the sub failed on the first code line. I've been through the pivot tables class docs and scoured the forums for any answers of which don't work. I'm not a vba developer (SQL Dev) so some solution answers would be appreciated and points awarded. Thanks in advance!Learner74

1 Answers

0
votes

The 1004 error occurred due to the use of square brackets [ ]. Remove those.

You also need to use the key word Set when you set an object equal to something. For example Set MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("ComparisonTable.P_ID.[P_ID").DataRange.

If you don't use Set you will get a VBA run-time error dialog that says Run-time error '91': Object variable or With block variable not set

I cannot guarantee that my edits will completely solve your problem since I don't have your data set and cannot fully test your code. You will need to use the Debug mode in the VBA editor and single step through the code. To this set a breakpoint on the Set mDataRange = Active.... To set a breakpoint go to the Debug menu and choose the "Toggle Breakpoint" sub-menu item or you can press F9 to set the breakpoint.

Now when you make a change to the Pivot table, the Worksheet_PivotTableUpdate event will fire and the code will top execution at that point.

After the code stops executing due to the breakpoint, you can press the F8 key to single step through your code. If you want to resume execution to the next breakpoint you can press F5. Also when you get the VBA error dialog box, you can hit Debug and then use the F8 key to single step or use the debug windows to see what your variables and objects contain. I'm sure there are some good youtube videos on VBA debugging.

As you single step through the code, you can observe what each variable/object contains using the Immediate window, the Watches window and the Locals window. To open these windows, go to the menu item View and click on each of these sub-menu items.

Here's how you need to edit your code before debugging.

Option Explicit

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)

    'Better practice is to not use the underscore character to
    'continue a Dim declaration line
    Dim mDataRange As Range
    Dim ar As Range
    Dim x As String
    Dim y As String
    Dim str As Variant

    'Use Set to assign the object mDataRange a reference to the the right
    'hand side of the equation.  Remove the square brackets
    'MyArray = ActiveSheet.PivotTables("PivotTable2").PivotFields("[ComparisonTable].[P_ID].[P_ID]").DataRange
    Set mDataRange = ActiveSheet.PivotTables("PivotTable2").PivotFields("ComparisonTable.P_ID.P_ID").DataRange

    For Each ar In mDataRange
        'You need to specify what proprerty from ar you
        'want to assign to x.  Assuming the value stored in
        'ar.Value2 is a string, this should work.
        'We use value2 because it is the unformmated value
        'and is slightly quicker to access than the Text or Value
        'properties
        'x = "[MasterTable].[P_ID].&[" & ar & "]"
        x = "MasterTable.P_ID." & ar.Value2

        'Once again specify the Value2 property as containing
        'what value you want to test
        If ar.Value2 <> "" And bFieldItemExists(x) = True Then
            If str = "" Then
                'Remove the square brackets and use the specific property
                'str = "[MasterTable].[P_ID].&[" & ar & "]"
                str = "MasterTable.P_ID." & ar.Value2
            Else
                'Remove the square brackets and use the specific property
                'str = str & "," & "[MasterTable].[P_ID].&[" & ar & "]"
                str = str & "," & "MasterTable.P_ID." & ar.Value2
            End If
        End If
    Next ar


Dim str2() As String

    str2 = Split(str, ",")

    Application.EnableEvents = False
    Application.ScreenUpdating = False
        'Remove square brackets
        'ActiveSheet.PivotTables("PivotTable1").PivotFields("[MasterTable].[P_ID].[P_ID]").VisibleItemsList = Array(str2)
        ActiveSheet.PivotTables("PivotTable1").PivotFields("MasterTable.P_ID.P_ID").VisibleItemsList = Array(str2)

    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub


Function bFieldItemExists(strName As String) As Boolean

    'Declare a PivotItem to accept the return value
    Dim pvItem As PivotItem
    'Since you want to trap for an error, you'll need to let the VBA runtime know
    'The following code is a pseudo Try/Catch.  This tells the VBA runtime to skip
    'the fact an error occured and continue on to the next statement.
    'Your next statement should deal with the error condition
    On Error Resume Next

    'Use Set whenever assigning an object it's "value" or reference in reality
    Set pvItem = ActiveSheet.PivotTables("PivotTable1").PivotFields("MasterTable.P_ID.P_ID").PivotItems(strName)

    'Assuming that an error gets thrown when strName is not found in the pivot
    'Err is the error object.  You should access the property you wish to test
    If Err.Number = 0 Then
        bFieldItemExists = True
    Else
        bFieldItemExists = False
    End If

    'Return to normal error functioning
    On Error GoTo 0
End Function

Finally, I realize that some of this should be in the comments section, but there was too much I needed to explain to help Learner74. BUT most importantly, I hope I helped him. I have used so many suggestions, recommendations and explanations from the VBA Stack Overflow exchange through the years, I just want to pay it back by paying it forward.

Additional USEFUL Links:

Chip Pearson is the go to site and person for all things VBA

Paul Kelly's Excel Macro Mastery is another go to site for Excel and VBA questions.

Microsoft Excel Object Model which is sometimes useful, but needs improvement. Too many of the objects lack examples, but can at least point you in the right direction.