Macro Buttons to Add Fields to Pivot Tables

Bottom Line: Learn how to create simple macro buttons that users can click to instantly add or remove fields to Excel pivot tables.

Skill Level: Intermediate

Download the Excel File

Download the Excel file I use in the video to follow along. The file contains the VBA macros.

Adding Macro Buttons to a Pivot Table

Lauren, a member of The Pro VBA Course, had a great question on making her pivot tables easier for other users to customize.  What she needed were buttons on her spreadsheet that the users could click to add or remove fields in the pivot table.

Macro Buttons to Add Remove Fields to Pivot Tables

This allows the user to quickly change the view of what is included in the report.  It's a great solution if you don't want to have multiple sheet tabs with different pivot tables, or you're creating a dashboard.

It also makes it easier for users or consumers of your files that aren't familiar with modifying pivot tables.

It's important to note the the fields in the Values area are staying the same.  The macro only changes the fields in the Rows area.  We could modify this to change the other fields though.

The Replace and Toggle Macros

I'm going to share two macros.  The first will replace all the fields in the Rows area with the field name in the button's text.

The second macro is a toggle that will add the field if it's not currently in the rows area, and vice versa.

1. Macro to Replace Fields in the Rows Area

The first macro will remove all existing fields from the Rows area, and then add the single field based on the button the user clicked.

Macro Button to Replace All Pivot Table Fields in Rows Area

The nice part about this macro is that we only need to use one macro for all the different buttons.  Here is an image that explains more about how the macro workers.  I also explain this in detail in the video above.

Macro code to create macro buttons for pivot table

Note: To access the VB Editor just press Alt+F11 or click on the Visual Basic button on the Developer tab.

Application.Caller Property

The macro is assigned to the shapes on the sheet.  The Application.Caller property returns the name of the shape that was clicked by the user to run the macro.

Hovering over Application.Caller reveals the name of the shape

This is similar to caller ID on your phone.  Application.Caller tells us who (which object) is calling the macro from the Excel application.

It's a very powerful feature because we use the text in the button to reference the field name that is added to the pivot table.

Hovering over sField Variable reveals name of field we want to add

The TextFrame.Characters.Text property of the Shape object returns the text within the shape.  This is set to a variable (sField), and reused in the references for the PivotFields property.

It's important to note that each shape must have a unique name in order for the macro to work.

The VBA Code to Replace the Pivot Table Fields

Here is the VBA code for the macro to replace the pivot fields.  You can copy/paste it to your VB Editor.  The code is also included in the example Excel file in the downloads section above.

Sub Add_Row_Field()
'Remove all Row fields and add the Row field to the pivot table.
'The field is determined by the button text that calls the macro.

Dim pt As PivotTable
Dim pf As PivotField
Dim sField As String

  'Set variables
  Set pt = ActiveSheet.PivotTables(1)
  sField = ActiveSheet.Shapes(Application.Caller).TextFrame.Characters.Text
  
  'Remove existing fields
  For Each pf In pt.RowFields
    If pf.Name <> "Values" Then
      pf.Orientation = xlHidden
    End If
  Next pf
  
  'Add field that button was clicked for
  pt.PivotFields(sField).Orientation = xlRowField

End Sub

Adding More Macro Buttons

The nice part about using Application.Caller is that you can use it for as many buttons as you need.  All we have to do is set the text in the shape to match any of the fields in the pivot table.  We can quickly make a duplicate copy of the shape and change the text to add more options to our report.

Here are the instructions to add more macro buttons:

  1. Hold the Ctrl key while clicking on any of the existing buttons.  Using the Ctrl key will select the shape, instead of running the macro.
    Press Ctrl while clicking on the button you want to duplicate
  2. Hover the mouse over the edge of the shape.  Left-click and hold, then press Ctrl+Shift while dragging the button to a new area.    Release the mouse button, then the keyboard keys.  This duplicates the button and keeps it aligned with the other shape.
    Press Ctrl and Shift while dragging the button to duplicate
  3. Left-click the shape and change the text to match one of the other pivot table fields.
    Macro Button Shape Text Must Match Field in Pivot Table Fields List

The button is already assigned to the macro.  When you press the button it will add that field to the pivot table.

2. Macro to Toggle Pivot Table Fields

This macro allows the user to add (or remove) multiple fields to the pivot table.  It can also change the order (position) of the fields.

Toggle Pivot Table Fields with Macro Buttons - Add Remove from Rows Area

The macro is similar to the first one.  The main difference is that we use an If statement to determine if the field is already in the pivot table.  If not, the macro adds it.  If it is in the pivot table then the macro removes it.

The macro also changes the fill color of the shape to make it look enabled/disabled using the Brightness property.

Here is a screenshot with an explanation of the macro.

code to create toggle fields for macro buttons

With this macro, users can add more than one field into their pivot tables by just clicking on the buttons they want.  The order (position) of the fields is determined by the order the buttons are clicked.

The VBA Code for the Toggle Pivot Fields Macro

Here is the VBA code for the macro to toggle the pivot fields.  You can copy/paste it to your VB Editor.  The code is also included in the example Excel file in the downloads section above.

Sub Toggle_Row_Field()
'Add/Remove the field to the pivot table.
'The field is determined by the button text that calls the macro.

Dim pt As PivotTable
Dim pf As PivotField
Dim sField As String
Dim shp As Shape

  'Set variables
  Set pt = ActiveSheet.PivotTables(1)
  Set shp = ActiveSheet.Shapes(Application.Caller)
  sField = shp.TextFrame.Characters.Text
  
  'Toggle field
  'If visible then hide it
  If pt.PivotFields(sField).Orientation = xlRowField Then
    pt.PivotFields(sField).Orientation = xlHidden
    shp.Fill.ForeColor.Brightness = 0.5
  Else 'Add to Rows area
    pt.PivotFields(sField).Orientation = xlRowField
    shp.Fill.ForeColor.Brightness = 0
  End If

End Sub

Arranging Reports in an Instant

At the push of a button, you can rearrange the data in your pivot tables in a multitude of different ways.

In this first example, we pressed the Region button first, and then the Salesperson button.  This shows the Sum of Revenue for the Salesperson in each Region.

Pivot Chart Region then Salesperson

In this next image, we first selected Salesperson and then Customer Name.  This shows us the Sum of Revenue for the Customers for each Salesperson.

Pivot Chart Salesperson then Customer name

You can create buttons for all of the fields that might be relevant to the metric or calculation in the Values area.

The  Macros Work with Slicers and Pivot Charts

The macros also work when slicers or charts are connected to your pivot table.

Macro Buttons for Pivot Fields still work with Slicers and Pivot Charts

Only the fields included in the pivot table are being modified by the macro.  Slicers can still be used to filter the pivot tables and any Pivot Charts connected to the pivot table.

Make Your Reports Easier to Use

These macros simplify the user experience and allow your users to explore the data.  It's a great feature if you plan to share your workbooks with others who may not be as Excel savvy as you are. 😉

We can also modify the macros to change the fields in the Columns, Filters, or Values area.  Leave a comment below if you are interested in those variations.

Please leave a comment below with any questions or suggestions.  Thank you! 🙂

Additional Resources

72 comments

Your email address will not be published. Required fields are marked *

  • Nice Jon. I’m building a dashboard at work and your awesome macro solution appeared out of nowhere. I’m definitely going to implement it. Thanks Jon.

  • I like the free video so much I would be happy to pay especailly for the info below
    The way you explain the subject is outstanding. What do you have available on pivots and also using tables with 800,000 rows that does not freeze

    We can also modify the macros to change the fields in the Columns, Filters, or Values area. Leave a comment below if you are interested in those variations.

  • Jon, briefly explain how you created the “buttons”. I tried using Insert/Controls/Form Controls/Button, but that doesn’t allow you to change the colors, etc. If I right click on the “Buttons” in the sample file, I can tell these aren’t Active X controls either as the pop up menu options for ActiveX controls aren’t there when you right click on the Button.

  • Mr Jon,

    The way you explain the subject is outstanding & very useful in daily office works.

    Thanks for your dedication.

  • Hi Jon, thanks a ton for sharing the knowledge and ideas. Its making my job very interesting 🙂
    In reference to 1st macro, whenever i click on macro its adding the Data values on the next column instead of replacing the values, for eg: Sum of Revenue is getting added onto next column.
    not sure if others are facing similar issue.
    Your help would be much appreciated.
    Regards, Karthick

    • I am having the same issue. When I edit the “RowField” to be “DataField” and toggle the button the report adds another column every time I click the button, instead of toggling like expected. Please help! Thank you!

    • Hi Karthik, Can you please help me understand how did you do for columns/values? It would be very helpful if you could share your VB here or to my email. Thanks!

    • I struggled for hours trying to work out why it wasn’t working for my power pivot model. In the end I recorded a macro that added in a field. When I looked at this macro it used CubeField instead of PivotField and the field name was in a [Table].[Field] format. When I changed PivotField to CubeField in Jon’s macro and changed the button text it worked!

      Hope this helps
      Chris

      • Chris,

        I tried this change in my power pivot model, but it did not work. Can you post your specific code that worked in your power pivot model.

        thanks,
        Chris W

        • I’ve tried to modify to accommodate the power pivot model. This is how I adjusted the code, but I can’t the button name to pass correct “[Table].[Filed]”

          Sub Toggle_Row_Field()
          ‘Add/Remove the field to the pivot table.
          ‘The field is determined by the button text that calls the macro.

          Dim pt As PivotTable
          Dim pf As CubeField
          Dim sField As String
          Dim shp As Shape

          ‘Set variables
          Set pt = ActiveSheet.PivotTables(1)
          Set shp = ActiveSheet.Shapes(Application.Caller)
          sField = shp.TextFrame.Characters.Text

          MsgBox (sField)
          MsgBox (pt)

          ‘Toggle field
          ‘If visible then hide it
          If pt.CubeFields(sField).Orientation = xlRowField Then
          pt.CubeFields(sField).Orientation = xlHidden
          shp.Fill.ForeColor.Brightness = 0.5
          Else ‘Add to Rows area
          pt.CubeFields(sField).Orientation = xlRowField
          shp.Fill.ForeColor.Brightness = 0
          End If

          End Sub

          • Chris Collinson is correct. You just need to 1) change the rowField to CubeField and 2) change the actual button text to read [Table].[Field].

            [Table] should be the name of your pivot table query in the field list, and [Field] the text of your button.

            The reason being with power pivot tables, you can link multiple tables, and it needs to know which table to reference.

            In my case, I didn’t want the button text to say [Table].[Field], so I modified my code to have the sfield set to a cell on my worksheet that contains a formula =[Table].[” & a cell that contains the sfield &”]”.

            I also have multiple pivot tables, so I select the desired pivot table first.

            I also modified the portion to remove existing row fields otherwise it would remove both row and column fields.

            Sub Add_Row_Field()

            Dim pt As PivotTable
            Dim cf As CubeField
            Dim sField As String

            ‘Select the pivot table
            ActiveSheet.Range(“B15”).Select

            ‘Set cells to button name
            ActiveSheet.Range(“B13”) = ActiveSheet.Shapes(Application.Caller).TextFrame.Characters.Text

            ‘Set variables
            Set pt = ActiveCell.PivotTable
            sField = ActiveSheet.Range(“A6”)

            ‘Remove existing fields
            For Each cf In pt.CubeFields
            If cf.Orientation = xlRowField Then cf.Orientation = xlHidden
            Next cf

            ‘Add field that button was clicked for
            pt.CubeFields(sField).Orientation = xlRowField

            End Sub

            Hope this helps

          • Hey Guys!

            I am working on a power pivot model and used Brent’s Code and all went well until the last line:

            pt.CubeFields(sField).Orientation = xlRowField

            where I got the error: runtime error 9 subscript out of range. Do you know how I could fix this?

  • Dear Jon,

    Thanks for sharing and it was very useful. It has saved lot of time and the way we present.

    I need one more help. Guess not asking for too much.
    Just in case, we can a macro to change two different pivot tables ( on the same sheet or active sheet) using single button, where we have the same fields.

    Thanks in advance..

    Rgds

  • Great example, thanks.

    What change is necessary so that instead of having a specific text field tied to a button, the button is tied to a drop-down list?

  • Hi Jon –

    Great work on the macro. Can you please show how to modify the code for use with multiple pivot tables on the same sheet? I have 2 pivot tables and two sets of buttons on the same sheet and would like for them to work independently of each other, even though the buttons have the same names.

    Thanks,

    Brent

    • I’ve figured out the answer to my question.

      Replace the line
      Set pt = ActiveSheet.PivotTables(1)

      With this instead
      Set pt = Activecell.PivotTable

      Then include a line to select a cell in the pivot table first before running the macro

      Then it will work with multiple pivot tables on the same sheet

        • Dim pt As PivotTable
          Dim cf As CubeField
          Dim sField As String

          ‘Select the pivot table
          ActiveSheet.Range(“B15”).Select

          ‘Set cells to button name
          ActiveSheet.Range(“B13”) = ActiveSheet.Shapes(Application.Caller).TextFrame.Characters.Text

          ‘Set variables
          Set pt = ActiveCell.PivotTable
          sField = ActiveSheet.Range(“A6”)

          ‘Remove existing fields
          For Each cf In pt.CubeFields
          If cf.Orientation = xlRowField Then cf.Orientation = xlHidden
          Next cf

          ‘Add back the Grand Total row field
          With pt.CubeFields(“[Monthly Reporting_Final_RMA].[Total]”)
          .Orientation = xlRowField
          .Position = 1
          End With

          ‘Add field that button was clicked for
          pt.CubeFields(sField).Orientation = xlRowField

          End Sub

    • All,
      This is pretty simple. Just create a different module (I called mine “Toggle_Column_Field”), then copy and past the VBA code you have for the row toggle into this new “column” module. Then replace the word “Row” with “Column” every place in the new column module VBA code (there is only a couple of places to do so). Then link the shape buttons you create for your column variables to the column module by right clicking on the shape, selecting “Assign Macro”, then pick the column module you created. Note that this does not change the “Values” the pivot table calculates, but rather it toggles on-off column variables. I’ve got a file with 5 row buttons, two column buttons and three slicers. It works fine.

  • <<>>
    Can you please help in accomplishing the same for the columns values?
    I am trying to have a region as row and sales number on the values/column. and toggle between sales, revenue, profit etc.
    Your help is much appreciated!
    Thank you!

  • Hi Jon, thank you for this!

    I am currently using this solution, however i have encountered one issue. I have used these buttons, to create a dashboard on my excel. There are 3 charts, and each has its own pivot table and macro button assigned to it. I have edited the code very slightly, to reflect the PT that i am referring to as there are multiple PT that sits on the same sheet which is hidden by my dashboard.

    However each time i assign the macros to the correct pivot table and save, when i reopen the file the buttons are not longer assigned to the right pivot table and when i click the button, another chart is updated instead. May i know how i can rectify this?

  • My question/comment is similar to Rakesh. I have a pivot table I’m using as a sales managers dashboard. The pivot has slicers to allow the user to parse through each sales territory but I want to create a macro button to allow the user to toggle between showing revenue dollars which are calculated as the sum of the gross revenue field values and margin dollars using the sum of the gross margin field values. Thanks in advance for any advice you can offer.

    • In case anyone read my question and is waiting for a reply for their own project, I was able to figure this out so thought I’d post for others! It was actually pretty simple.

      I first created a toggle button using the ActiveX controls. I then wrote two subs, one that first removes the sum of revenue field in my Pivot Table using the xlHidden command then adds the sum (xlSum) of the gross margin field and a second that does the reverse; removes the gross margin field (xlHidden), then adds the sum of the revenue field (xlSum).

      Within the toggle button code, I call the “replace_revenue” sub when the toggle button is toggled from “true” to “false” and the “replace_margin” sub to switch back. Works great!

      One nice touch was to change the caption of the toggle button within the toggle button macro so that when the toggle is set to “True” it reads “Change to Gross Margin” or “Change to Revenue” if the status of the toggle button is “False”.

      Hope this helps someone.

  • struggling to get this to work with power pivot data models. I tried modifying the PivotFields(sField) to CubeFields(sField) where sField = “[Table].[Field]”… it is the second part I can’t figure out. Keep getting Run-Time error 9… subscript out of range.

    Following is what I’m trying without success:

    Sub Toggle_Row_Field()
    ‘Add/Remove the field to the pivot table.
    ‘The field is determined by the button text that calls the macro.

    Dim pt As PivotTable
    Dim pf As CubeField
    Dim sField As String
    Dim shp As Shape

    ‘Set variables
    Set pt = ActiveSheet.PivotTables(1)
    Set shp = ActiveSheet.Shapes(Application.Caller)
    sField = shp.TextFrame.Characters.Text

    MsgBox (sField)
    MsgBox (pt)

    ‘Toggle field
    ‘If visible then hide it
    If pt.CubeFields(sField).Orientation = xlRowField Then
    pt.CubeFields(sField).Orientation = xlHidden
    shp.Fill.ForeColor.Brightness = 0.5
    Else ‘Add to Rows area
    pt.CubeFields(sField).Orientation = xlRowField
    shp.Fill.ForeColor.Brightness = 0
    End If

    End Sub

    Anyone have success to make this work. I would really appreciate any assistance because this will be a great feature.

  • How can i restructure the code to suit my requirement as my Pivot table has got xlDataField, xlColumnField also.
    My code it it is giving error “Unable to get pivotfields property of Pivot Table class” when it reaches if condition. Below is my code for your reference
    Dim pt As PivotTable
    Dim pf As PivotField
    Dim sField As String
    Dim shp As Shape

    ‘Set variables
    Set pt = ActiveSheet.PivotTables(“PivotTable13”)

    ‘Set pt = ActiveSheet.PivotTables(1)
    Set shp = ActiveSheet.Shapes(Application.Caller)
    sField = shp.TextFrame.Characters.Text

    ‘Toggle field
    ‘If visible then hide it

    If pt.PivotFields(sField).orientation = xlRowField Or pt.PivotFields(sField).orientation = xlSum _
    Or pt.PivotFields(sField).orientation = xlCount Or pt.PivotFields(sField).orientation = xlColumnField _
    Or pt.PivotFields(sField).orientation = xlPageField Or pt.PivotFields(sField).orientation = xlDataField Then

    pt.PivotFields(sField).orientation = xlHidden
    shp.Fill.ForeColor.Brightness = 0.5
    ‘If already hidden than Add to Rows area
    Else
    Select Case pt.PivotFields(sField).orientation

    Case xlRowField
    pt.PivotFields(sField).orientation = xlRowField
    shp.Fill.ForeColor.Brightness = 0

    Case xlColumnField
    pt.PivotFields(sField).orientation = xlColumnField
    shp.Fill.ForeColor.Brightness = 0

    Case xlPageField
    pt.PivotFields(sField).orientation = xlPageField
    shp.Fill.ForeColor.Brightness = 0

    Case xlDataField
    pt.PivotFields(sField).orientation = xlDataField
    shp.Fill.ForeColor.Brightness = 0

    End Select

    End If

    • I had the same issue, check if:

      1. if you are using macro to create a pivot – the sheet name should be the same
      2. Set pt = ActiveSheet.PivotTables(“PivotTable13”) – I think it should not be in ” ” and only accepts a number – refer to section 1 image 2 on this page

  • Hi, I am trying to add a similar button but for a value in a pivot. Please can you help with the code below as I keep getting an error.

    Sub TextBox4_Click()

    ‘ TextBox4_Click Macro

    if

    ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Sum of Mar”).Orientation = xlDataField

    Then

    ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Sum of Mar”).Orientation = _
    xlHidden

    Else


    ActiveSheet.PivotTables(“PivotTable1”).AddDataField ActiveSheet.PivotTables( _
    “PivotTable1”).PivotFields(“Mar”), “Sum of Mar”, xlSum

    End Sub

  • Hello: Thanks for the code, Jon. It works great on my windows machine! But on my bosses Mac, it fails here:

    Set shp = ActiveSheet.Shapes(Application.Caller)

    I don’t have a Mac so I’m kind of just working in the dark.

    Thanks to anyone for any help!

  • Thank you for your post!

    I am having a hard time getting the toggle code to work. When I try to run it I get the following message: ‘Compile error: Sub or Function not defined’.

    Thank you for your help!

  • Jon
    Awesome video. I understand how you can copy additional buttons as needed, but what code are you writing for the original button?

  • struggling to get this to work when adding the data models with the unique count option, do i need to adjast the code? if yes pls send it

    thank you

  • HI was wondering if i could get code for Data.fields using the buttons. So if i click on the button it inserts the right data.field?

    Cheers

  • Hi Jon,

    Thanks for this video. It work well with my pivot table 🙂
    Currently I work on 2 Pivot table with the same data sources and would like to link both Pivot table with 1 button. Are you able to share the code?

  • Jon – thanks for this tip. Do you know if there is a way to query the fields available to a pivot table that are not used. I’m connected to an analysis services cube and would like to generate a list of all fields in the cube even those not shown on the current pivot table.
    I’ve found several code samples that list the fields in the pivot table but none that reference unused fields.
    Thanks

  • Hi,
    Thanks alot for this, it works great!
    I have a quick question – in the example above – we can add “fields”, is there any way to add “values” as well?
    example –
    Suppose I have a data set of students with marks in different subjects:

    Name | College | Course| marks 1 |marks 2 | marks 3 |

    So, using your code, I can add fields – Name, College, course etc., is there any way I can add or remove marks 1,2,3 from value?

    Thanks,
    Manish

    • I have the same issue! Did you manage to find a solution? Could you please send me your code? Would greatly appreciate your help!

  • Hi John, thank you for your passion to share Excel knowledge!
    I have about a year’s worth of experience in Excel, and I’m loving it, but I have very little time to slowly learn the tools I need for my work project. I am trying to create a student database for my school in Korea, one that teachers can input monthly scores and print auto populated report cards. I think my greatest challenge has been how to organize the data, because the students have 2-3 teachers, and there are several classes with the same level. (if you have any advice about this, I’d love to hear it. I have yet to find any videos that address this kind of issue.)
    But to my question related to this video:
    There are multiple pivot charts on my final report, but I don’t want the teachers to have to select every field. I want it automated with a macro button. I’ve used a VBA code, and it worked temporarily, but now I keep getting bugs. I am very new to VBA, so I don’t know how to fix them, or if I’m using the right commands (I’m just using what other people have shared).
    I would love to get some help, please point me in the right direction!

  • With ActiveSheet.PivotTables(“PivotTable”).PivotFields(“*Engagement name”)
    .Orientation = xlDataField
    .Position = 132
    .NumberFormat = “#,##0”
    .Name = “Grand Total”
    .PivotFields (“Grand Total”), “Grand Total”, xlSum

    *Engagement name *Resource name *Office location *Current grade 25-Jan-21 01-Feb-21 08-Feb-21 15-Feb-21 22-Feb-21 Grand Total

  • Hi
    Thanks for you knowledge and code is working superbly in single table linked Pivot table , but i have a data model with multiple table linked together and i am getting error as “Unable to get Pivot Filed property of the Pivot table class”

  • Great solution!

    I tried the same for value fields, what worked quite well except that the Pivot table outputs the ‘count’ instead of the ‘sum’ function for the values. Do you know how to include the sum function into the macro?

  • Thank you Jon! This is so helpful! By the way how do we find which macro Module number goes with a Macro we named. The names of my Macros don’t show in VBA.

  • this is great!

    I want to add the data fields into the values from the pivot which is stored in data model.

    How would I do that?

  • Hi, what if i add another pivot table on the same sheet. How ca
    n I assign the buttons to change only the previous pivot table?

  • Hi Jon
    Thank you so much for posting this video, this is amazing! I’m trying to apply it to a Power Pivot and think I may need to adapt the code. I tried downloading your files but I don’t seem to be able to download them as macro enabled? Can you help? 🙂

  • Hi, This is awesome. but I am getting an error when I use “Add this data to the Data Model.

    Run-time error ‘10040’:
    unable to set the Orientation property of the PivotField class

    can you please suggest the changes.

Generic filters
Exact matches only

Excel Shortcuts List

keyboard shortcuts list banner

Learn over 270 Excel keyboard & mouse shortcuts for Windows & Mac.

Excel Shortcuts List

Join Our Weekly Newsletter

The Excel Pro Tips Newsletter is packed with tips & techniques to help you master Excel.

Join Our Free Newsletter