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.
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.
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.
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.
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.
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:
- 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.
- 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.
- Left-click the shape and change the text to match one of the other pivot table fields.
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.
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.
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.
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.
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.
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! 🙂
Jon, this is brilliant! I already have a use for this. Thank you!!
Awesome! Thanks Rita. I’m happy to hear you’ll be putting it to good use. 🙂
Hi Jon , can you share the code on how to add a column using this technique?
Thanks
Hello Jon,
thank you for your very interesting and useful posting.
Your Pivot Macros helps me in my daily work.
Dan
Great stuff! Thanks for sharing.
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.
Hi Jon, awesome, just one question, seems it doesn’t work if the pivot table is based on data model, any hint how to deal with such?
Norbert, I found the same problem. Jon, could we help us to handle it?
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.
Can you show how to use a macro to replace Values, please? I want to switch from gross sales to gross margin
Great post!
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.
Hi Doug
If you use a shape rather than a button you should be able to change the colour.
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!
Hi Jon, this is very useful but how would you modify it for powerpivot tables? 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
Jon, could this also be done with the pivot columns (xlcolumnfield)?
Thanks for this amazing set of macros! 🙂
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?
Can you please explain how to do this with columns? Thank you!
Can you please show how to add columns?
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
Brent – can you please share the code
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
Can someone please help me to do the same exercise with the column? Thanks!
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.
Hi Chris , can you share the code, I have the same issue.
thanks
<<>>
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,
had the same issue, did you find any solutions to this?
Manish
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?
Hi Jon, Possible to have toggle fields take action on 2 pivot table created in same worksheet?
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.
Hi Mark – this is exactly what I’m after.
Any chance you could post your code please?
Hi, any chance you can send me your code?
Hi, could you please send me your code?
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
I think textbox won’t work, you need to add a shape – rectangle, circle etc.
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!
I am facing the same issue.. Did you get the solution
Same here. Can we have something similar to this toggle button to be worked for both Mac and Windows users?
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
It’s Great Thanks
Lahiru Perera
From Sri Lanka
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”
This is amazing! Do you have one to do the exact same thing but with the values selection instead?
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?
Yes, I’m looking for the slight modification to your first macro to modify the values area. Can you please help?
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.