Unable to add CubeField/PivotField as a Data Field in VBA

0

I'm working on a very long Macro for my job and I am just about finished, but this is the last part and no matter what I do, I can't seem to figure out the fix. In this PivotTable, I need to have "Managers" as the columns and everything else (i.e. all of the months) in the Values section, with "Values" as the rows. After tinkering around, it seems as though all of the fields registered as CubeFields instead of PivotFields. When I run this, as soon as it gets to .Orientation = xlDataField, it throws a "Run-Time error 5...Invalid procedure call or argument." I also need to make sure that those DataFields are averaged and in a specific number format. Nothing I do works, and any guidance/fixes/workarounds would be greatly appreciated! Below are the macro and a download link to the file for tinkering.

Dim pvtTable As PivotTable
Dim cubField As CubeField
Dim i As Long
Dim cubName As String

Set pvtTable = ActiveSheet.PivotTables(1)
For Each cubField In pvtTable.CubeFields
    For i = 1 To pvtTable.CubeFields.Count
        With pvtTable.CubeFields(i)
            If .Name = "[effRent_perBed].[Manager]" Then
                .Orientation = xlColumnField
           Else:
                .Orientation = xlDataField
                'has to be averaged
                'has to have number format of ##0.00
            End If

        End With
    Next
Next

This is an edit that I tried making based on the macro recorder. It puts the field in the values field, but there's no way to change it to an average. It simply lists all of the values as "1 (Check image for a visual). When I get to .Function = xlAverage, it says Error 1004: Unable to set the Function property of the PivotField class.

                If Name = "[effRent_perBed].[Manager]" Then
                    .Orientation = xlColumnField
                Else:
                    With ActiveSheet.PivotTables(1)
                        .AddDataField ActiveSheet.PivotTables(1) _
                        CubeFields(cubName), _
                        "Average of " & cubName
                    End With

                    With ActiveSheet.PivotTables(1).PivotFields(cubName)
                        .Caption = "Average of " & cubName
                        .Function = xlAverage
                    End With

When I use the Macro recorder to add something to the datafield, I get this:

ActiveSheet.PivotTables("effRent_perBed_Pivot").CubeFields.GetMeasure _
    "[effRent_perBed].[Jan-16]", xlSum, "Sum of Jan-16"
ActiveSheet.PivotTables("effRent_perBed_Pivot").AddDataField ActiveSheet. _
    PivotTables("effRent_perBed_Pivot").CubeFields("[Measures].[Sum of Jan-16]"), _
    "Sum of Jan-16"
With ActiveSheet.PivotTables("effRent_perBed_Pivot").PivotFields( _
    "[Measures].[Sum of Jan-16]")
    .Caption = "Average of Jan-16"
    .Function = xlAverage
End With

This is a copy of the file I'm working on. It shows the raw pivot table, and then the finished product. I have to do this for 3 sheets, so I have to cycle through each one. https://drive.google.com/uc?export=download&id=1NLGg8DVEMHnB2Ad7NAKWySevq8naqFjr

This is also posted on other forums (I need to get as many eyes on this as soon as possible) https://www.excelforum.com/excel-programming-vba-macros/1222588-unable-to-add-cubefield-pivotfield-as-a-data-field-in-vba.html#post4856940

https://www.mrexcel.com/forum/excel-questions/1046038-unable-add-cubefield-pivotfield-data-field-vba.html

https://www.ozgrid.com/forum/node/1200403

Andrew Stahl

Posted 2018-03-04T16:45:34.800

Reputation: 11

I downvoted you because you have posted this in multiple forums. Yes, you have pointed this out, but it's still not really acceptable to the point that most people won't bother to answer your question. Why? Because while you may want to get as many eyes on this as soon as possible, if it gets answered in multiple places by multiple people you will have wasted the time of some of those eyes. Please choose one forum only. Please read https://www.excelguru.ca/content.php?184 for why this is an issue.

– jeffreyweir – 2018-03-07T06:44:48.657

As for your question, the easiest way to troubleshoot things like this is to fire up the macro recorder, change the orientation of one code manually, stop the recorder, and see what code the macro recorder spat out. It will probably give you the proper syntax that you need. If you're still lost, post that code in your original question. – jeffreyweir – 2018-03-07T06:47:47.957

@jeffreyweir This is my first time posting, I wasn't aware that cross-posting was a big taboo. I've tried using the recorder and multiple times and when trying to replicate and scale that code, it never works properly. – Andrew Stahl – 2018-03-07T21:37:10.383

I understand that you can't get the macro recorder to work. But posting the macro generated code in your question is a big help to answerers like me, because we can usually work out what's going wrong just by eyeballing that code and comparing it to what you have done. Otherwise we have to create a sample PivotTable and perform this step ourselves, which is a real PITA. – jeffreyweir – 2018-03-07T21:39:41.203

Just made the update! – Andrew Stahl – 2018-03-08T23:15:22.317

Please post the code the macro recorder spits out in its entirety without making changes...not code that you have amended. In question you say that trying to change a field's orientation to a datafield is causing the error. Can you firstly check the name of the field it is failing on, and secondly then fire up the macro recorder, change the layout for that one field manually, then post the entire code that the macro recorder spits out here. An image of the PivotTable Fields list might also help. Note that your link to the sample file doesn't work for me. – jeffreyweir – 2018-03-10T00:07:12.370

Everything's posted. Unfortunately I really don't know where to go from here. Any guidance would be incredibly appreciated, I'm getting a little burnt out with this project – Andrew Stahl – 2018-03-12T12:53:38.780

Cool. I'm having dinner now but will take a look shortly. Before then, take a look at what the macro recorder spat out on the .AddDataField bit, and contrast that with your code. What can you see is different? How might you need to amend your original code so that it does whatever the macro recorder is spitting out without error? – jeffreyweir – 2018-03-13T05:49:16.377

Answers

0

Your question could still do with fleshing out further. For instance, you don't say if you are creating a PivotTable from scratch and then adding fields, or whether this gets run on an existing PivotTable that might already have fields in it.

Somebody just pointed me to the Rubber Duck Problem Solving/ blog post, and I'm going to point you to it too, because it helps people to answer if they know everything relevant.

At https://msdn.microsoft.com/en-us/vba/excel-vba/articles/pivottable-adddatafield-method-excel it says the syntax for .adddatafield is AddDataField( Field , Caption , Function ) with the function being optional.

So what happens if you try this?

If Name = "[effRent_perBed].[Manager]" Then
    .Orientation = xlColumnField
 Else:
    With ActiveSheet.PivotTables(1)
        .AddDataField ActiveSheet.PivotTables(1) _
            CubeFields(cubName), _
            "Average of " & cubName, _
            xlAverage
    End With
End if

There's some issues with your original code block. I don't understand why you are both iterating through the CubeFields collection and also iterating through a count of cubefields. i.e. this bit:

For Each cubField In pvtTable.CubeFields
    For i = 1 To pvtTable.CubeFields.Count

Isn't that just going to iterate through everything by the square of Cubefields.count? You should be able to ditch that For i = 1 To pvtTable.CubeFields.Count bit and simply use the cubField reference directly.

I think the reason your code failed to set the summarisation to XLAverage is because once you add a field to the Data area, the name effectively changes. You can see this if you leave the DataField in place, and run this code:

Sub Macro1()
'
' Macro1 Macro
'
Dim pvtTable As PivotTable
Dim cubField As CubeField
Dim i As Long
Dim cubName As String

Set pvtTable = ActiveSheet.PivotTables(1)
For Each cubField In pvtTable.CubeFields
    Debug.Print cubField.Name
Next

End Sub

That will print the names of all the fields to the immediate window (assuming you have it open) at which point you will see that while you will have a result for [effRent_perBed].[Manager], this is NOT the datafield. The DataField will be something like [Measures].[Average of effRent_perBed]

And that's why your code failed: you were still referring to the field of interest as if it was still a CubeField. But as soon as you try it add it to the DataFields area, a new DataField gets created, and that's the one you needed to change the aggregation for.

Like I said above though, you can do this at the time you create the DataField.

jeffreyweir

Posted 2018-03-04T16:45:34.800

Reputation: 426

That last part makes a lot of sense. At some point I was checking the names in the local window and noticed that after all of the fields it did say "[Measures].[xlAverage...]" Now I see after checking out the macro recorder that we add the measure field. At this point I have to figure out how to make this dynamic to work in a loop so I can add multiple fields.Unfortunately my computer's hard drive died so I'm trying to salvage what I can. Thank you again for all of your help @jeffreyweir! – Andrew Stahl – 2018-03-13T20:27:37.047

No problem...this stuff is confusing to the initiated, let alone the uninitiated :-) Don't forget to mark my answer as accepted if it solves the issue for you. – jeffreyweir – 2018-03-13T21:01:49.917