A Step By Step Guide to Create a Pivot Table in Excel using VBA – MACRO CODE


Before I hand over this guide to you and you start using VBA to create a pivot table let me confess something.

I have learned using VBA just SIX years back.

And the first time when I wrote a macro code to create a pivot table, it was a failure.

Since then I have learned more from my bad coding rather than from the codes which actually work.

Today, I will show you a simple way to automate your pivot tables using a macro code.

Normally when you insert a pivot table in a worksheet it happens through a simple process, but that entire process is so quick that you never notice what happened.

In VBA, that entire process is same, just executes using a code.

In this guide, I’ll show you each step and explain how to write a code for it.

Just look at the below example, where you can run this macro code with a button...

...and it returns a new pivot table in a new worksheet in a flash.

Macro Codes To Create A Pivot Table

The Simple 8 Steps to Write a Macro Code in VBA to Create a Pivot Table in Excel

1. Declare Variables

The first step is to declare the variables which we need to use in our code to define different things.

'​​Declare Variables
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long

In the above code, we have declared:

  1. PSheet: To create a sheet for a new pivot table.
  2. DSheet: To use as a data sheet.
  3. PChache: To use as a name for pivot table cache.
  4. PTable: To use as a name for our pivot table.
  5. PRange: to define source data range.
  6. LastRow and LastCol: To get the last row and column of our data range.

2. Insert a New Worksheet

Before creating a pivot table, Excel inserts a blank sheet and then create a new pivot table there.

insert a new worksheet to use vba to create pivot table in excel

And, below code will do the same for you.

It will insert a new worksheet with the name “Pivot Table” before the active worksheet and if there is worksheet with the same name already, it will delete it first.

After inserting a new worksheet, this code will set the value of PSheet variable to pivot table worksheet and DSheet to source data worksheet.

'​​Declare Variables
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("PivotTable").Delete
Sheets.Add Before:=ActiveSheet
ActiveSheet.Name = "PivotTable"
Application.DisplayAlerts = True
Set PSheet = Worksheets(
"PivotTable")
Set DSheet = Worksheets(
"Data")

Customization Tip: If the name of the worksheets which you want to refer in the code is different then make sure to change it from the code where I have highlighted.

3. Define Data Range

Now, next thing is to define data range from the source worksheet.

Here you need to take care of one thing that you can't specify a fixed source range. You need a code which can identify the entire data from source sheet.

And, below is the code:

'​​​Define Data Range
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Cells(1, 1).Resize(LastRow, LastCol)

This code will start from the first cell of the data table and select up to the last row and then up to the last column.

And finally, define that selected range as a source.

4. Create Pivot Cache

In Excel 2000 and above, before creating a pivot table you need to create a pivot cache to define the data source.

Normally when you create a pivot table, Excel automatically creates a pivot cache without asking you, but when you need to use VBA, you need to write a code for this.

And  below code is for this:

'​​​​Define Pivot Cache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange). _
CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), _
TableName:="SalesPivotTable")

This code works in two way, first define a pivot cache by using data source and second define the cell address in the newly inserted worksheet to insert the pivot table.

You can change the position the pivot table by editing this code.

5. Insert a Blank Pivot Table

After pivot cache, next step is to insert a blank pivot table.

Just remember when you create a pivot table what happens, you always get a blank pivot first and then you define all the values, columns, and row.

insert a blank pivot to use vba to create pivot table in excel

This code will do the same:

'​Insert Blank Pivot Table
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Cells(1, 1), TableName:="SalesPivotTable")

This code creates a blank pivot table and names it "SalesPivotTable". You can change this name from the code itself.

6. Insert Row and Column Fields

After creating a blank pivot table, next thing is to insert row and column fields, just like you do normally.

For each row and column field, you need to write a code. Here we want to add years and month in row field and zones in the column field.

insert row column fields to use vba to create pivot table in excel

Here is the code:

'Insert Row Fields
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Year")
.Orientation = xlRowField
.Position = 1
End With


With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Month")
.Orientation = xlRowField
.Position = 2
End With


'Insert Column Fields
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Zone")
.Orientation = xlColumnField
.Position = 1
End With

In this code, you have mentioned year and month as two fields. Now, if you look at the code you'll find that there is also a position number is there.

​This position number defines the sequence of fields.

​Whenever you need to add more than one fields (Row or Column) make sure to specify their position.

And, you can change fields by editing their name from code.

7. Insert Data Field

Now, the main thing is to define value field in your pivot table.

The code for defining values is a bit different from defining row and columns because here we need to define the formatting of number, position, and function.

'Insert Data Field
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Amount")
.Orientation = xlDataField
.Position = 1
.Function = xlSum
.NumberFormat = "#,##0"
.Name = "Revenue "
End With

With above code, you can add amount as the value field.

And this code will format values as a number with (,) separator. We are using xlsum to sum values but you can also use xlcount and other functions as well.

8. Format Pivot Table

In the end, you need to use a code to format your pivot table.

Normally in a pivot table there is also a default formatting and then you change that formatting. But with VBA you can define formatting style withing the code.

use vba to create pivot table in excel formatting

Code is:

'Format Pivot
TableActiveSheet.PivotTables("SalesPivotTable").ShowTableStyleRowStripes = TrueActiveSheet.PivotTables("SalesPivotTable").TableStyle2 = "PivotStyleMedium9"

Above code will apply row strips and "Pivot Style Medium 9" style but you can also use another style.

Finally, your code is ready to use.

Use VBA to Create a Pivot Table in Excel - Full Macro Code to Copy-Paste

Sub InsertPivotTable()
'Macro By ExcelChamps

'Declare Variables
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable As PivotTable
Dim PRange As Range
Dim LastRow As Long
Dim LastCol As Long

'Insert a New Blank Worksheet
On Error Resume Next
Application.DisplayAlerts = False
Worksheets("PivotTable").Delete
Sheets.Add Before:=ActiveSheet
ActiveSheet.Name = "PivotTable"
Application.DisplayAlerts = True
Set PSheet = Worksheets("PivotTable")
Set DSheet = Worksheets("Data")

'Define Data Range
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Cells(1, 1).Resize(LastRow, LastCol)

'Define Pivot Cache
Set PCache = ActiveWorkbook.PivotCaches.Create _
(SourceType:=xlDatabase, SourceData:=PRange). _
CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), _
TableName:="SalesPivotTable")

'Insert Blank Pivot Table
Set PTable = PCache.CreatePivotTable _
(TableDestination:=PSheet.Cells(1, 1), TableName:="SalesPivotTable")

'Insert Row Fields
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Year")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Month")
.Orientation = xlRowField
.Position = 2
End With

'Insert Column Fields
With ActiveSheet.PivotTables("SalesPivotTable").PivotFields("Zone")
.Orientation = xlColumnField
.Position = 1
End With

'Insert Data Field
With ActiveSheet.PivotTables("SalesPivotTable")
.PivotFields ("Amount")
.Orientation = xlDataField
.Function = xlSum
.NumberFormat = "#,##0"
.Name = "Revenue "
End With

'Format Pivot Table
ActiveSheet.PivotTables("SalesPivotTable").ShowTableStyleRowStripes = True
ActiveSheet.PivotTables("SalesPivotTable").TableStyle2 = "PivotStyleMedium9"

End Sub

Or, you can download these sample files from here to try it yourself.

Pivot Table on the Existing Worksheet

The code we have used above creates a pivot table on a new worksheet but sometimes you need to insert a pivot table in a worksheet which is already there in the workbook.

In the above code (Pivot Table in New Worksheet), in the part where you have written the code to insert a new worksheet and then name it.

You need to make some tweak in the code.

Don’t worry, I’ll show you.

The first thing you need to do is specify the worksheet (which is already there in the workbook) where you want to insert your pivot table and for this, we need to use the below code:

Now instead of inserting a new worksheet you just simply need to specify the worksheet name to the PSheet variable.

Set PSheet = Worksheets("PivotTable")

Set DSheet = Worksheets(“Data”)

There a bit more to do.

The first code which you have used creates a deletes the worksheet with the same name (if it existes) before inserting it.

Now when you insert a pivot table in the existing worksheet there’s a chance that you already have a pivot there with the same name.

What I’m saying is you need to delete that pivot first it it’s there. Isn’t it?

So for this, you need to add the code which should delete the pivot with the same name from the worksheet (if it’s there) before inserting a new one.

Here’s the code which you need to add:

Set PSheet = Worksheets("PivotTable")

Set DSheet = Worksheets(“Data”)

Worksheets("PivotTable").Activate

On Error Resume Next

ActiveSheet.PivotTables("SalesPivotTable").TableRange2.Clear

Let me tell you what this code does.

First of all, it simply set PSheet as your the worksheet where you want to insert the pivot table and which already in your workbook, plus set data worksheets as DSheet.

After that, it activates the worksheet and deletes the pivot table “Sales Pivot Table” from it.

Customizations Tips: If the name of the worksheets in your workbook is different then you can change from the code. I have highlighted the code where you need to do it.

Here is the full code which you can use and here is the sample file to try it yourself.

Make sure to knock me in the comment section if you face any problem, I’ll try to help you with my best.

In the End,

By using this code we can automate your pivot tables. And the best part is, this is a one time set up and after that, we just need a click to create a pivot table and you can save your a ton of time. Now tell me one thing.

Have you ever used a VBA code to create a pivot table?

Please share your views with me in the comment box, I'd love to share with you and make sure to share this tip with your friends.

VBA is one of the Advanced Excel Skills, and if you are getting started with VBA, make sure to check out there (What is VBAExcel Programming, and Useful Macro Examples and VBA Codes).

About the Author

puneet one point one

Puneet is using Excel since his college days. He helped thousands of people to understand the power of the spreadsheets and learn Microsoft Excel. You can find him online, tweeting about Excel, on a running track, or sometimes hiking up a mountain.

151 thoughts

Leave a Comment

Your email address will not be published.

  1. Thanks, I managed to create my 1st pivot table using your code. If I want to use the same data source to create 2nd pivot table in different sheet (eg. sheet2), how do I go about it?

    Reply
  2. Je suis très ravi de trouver les solutions à mes difficultés concernant la création d’un Tableau croisé Dynamique par VBA

    Reply
  3. Get error 5 when I try to create a pivot table. I have done this in the past but in Office 2016 I can’t get it to work.

    Reply
  4. Hi Puneet,
    Thanks a lot for this free tutorial on Pivot table by VBA. I am a 65 years old mathematics teacher, who also handles data analysis. Although built in pivot table serves my purpose, I have been curious to create one using VBA.
    Thanks a lot once again.
    Ashokan
    Singapore

    Reply
  5. Set PCache = ActiveWorkbook.PivotCaches.Create _
    (SourceType:=xlDatabase, SourceData:=PRange). _
    CreatePivotTable(TableDestination:=PSheet.Cells(20, 2), _
    TableName:=”TeamQualityMetrics”)

    Dear Sir,
    On this I am getting a compile error, Method or data member not found.
    Can you pls help

    Regards

    Manoj

    Reply
    • I have delete that part of the code and add it like this and it is working for me:

      Set PRange = DSheet.Cells(1, 1).Resize(LastRow1, LastCol)

      ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
      PRange, Version:=6).CreatePivotTable TableDestination:= _
      “PivotTable!R1C1″, TableName:=”SalesPivotTable”, DefaultVersion:=6
      Sheets(“PivotTable”).Select
      Cells(1, 1).Select
      With ActiveSheet.PivotTables(“SalesPivotTable”)
      .ColumnGrand = True
      .HasAutoFormat = True
      .DisplayErrorString = False
      .DisplayNullString = True
      .EnableDrilldown = True
      .ErrorString = “”
      .MergeLabels = False
      .NullString = “”
      .PageFieldOrder = 2
      .PageFieldWrapCount = 0
      .PreserveFormatting = True
      .RowGrand = True
      .SaveData = True
      .PrintTitles = False
      .RepeatItemsOnEachPrintedPage = True
      .TotalsAnnotation = False
      .CompactRowIndent = 1
      .InGridDropZones = False
      .DisplayFieldCaptions = True
      .DisplayMemberPropertyTooltips = False
      .DisplayContextTooltips = True
      .ShowDrillIndicators = True
      .PrintDrillIndicators = False
      .AllowMultipleFilters = False
      .SortUsingCustomLists = True
      .FieldListSortAscending = False
      .ShowValuesRow = False
      .CalculatedMembersInFilters = False
      .RowAxisLayout xlCompactRow
      End With
      With ActiveSheet.PivotTables(“SalesPivotTable”).PivotCache
      .RefreshOnFileOpen = False
      .MissingItemsLimit = xlMissingItemsDefault
      End With
      ActiveSheet.PivotTables(“SalesPivotTable”).RepeatAllLabels xlRepeatLabels

      ‘Insert Row Fields
      With ActiveSheet.PivotTables(“SalesPivotTable”).PivotFields(“Local Legal Entity Code”)
      .Orientation = xlRowField
      .Position = 1
      End With

      Reply
  6. Hello. Thank you for the great tutorial.

    Can you please explain how I can add the coding to this VBA Project to select the check box “Add this data the the Data Model” located at the bottom of the in the Create Pivot Table Screen?

    Reply
  7. What is the code to change to show to subtotals, collapse buttons + – and to view in Tabular?

    Thanks,

    Victor

    Reply
  8. Hi,

    I used your code, and it works great! But my pivot does not need a column field, so I removed the code to add the column field (i.e. my column would just show sum of sales) but now it doesn’t show any values. It just gives me the rows

    Reply
  9. Ok, first of all, thanks sooo much for what this code!

    I was trying to figure out how to automate a Pivot table for a long time.

    Now, I know it’s not common/good practice or whatever to have several pivot tables in the same worksheet… but that’s something I want to do. There’s about 8 pivot tables I want in the same worksheet will all be very small and the current report format does have manually made tables all in the same worksheet.

    I tried, but I get errors –

    Run-time error 1004: The PivotTable field name is not valid. To crete a PivotTable report, you must use date that is organized as a list with labeled columns. If you are changing the name of a PivoTable field, you must type a new name for the field.

    I am using a common field in both tables. But the bump seems to be where I define the Pivot Cache a second time… I have been trying to take things out and add things, but I’m lost.

    Reply
  10. this code worked for me if placed data with starting point A1, but even after making necessary changes in Prange, when starting point is different, just PivotTable sheet got created without pivot table.

    Reply
  11. I have been trying to create a pivot table automatically using VBA macro for months – no, years! And this afternoon, with your help – I did it. Thank you so much!

    Reply
  12. Hi,

    Using this code I created 2 pivot tables in one sheet and trying to connect 1 slicer with both the tables but in Slicer Connection settings I don’t find option to select another table. Can anybody help me in this?
    My codes are:-

    Sub Team_Review()
    ‘Declare Variables
    Dim PSheet As Worksheet
    Dim DSheet As Worksheet
    Dim PCache As PivotCache
    Dim PTable As PivotTable
    Dim pvtFld As PivotField
    Dim PRange As Range
    Dim LastRow As Long
    Dim LastCol As Long
    Application.ScreenUpdating = False
    ‘Insert a New Blank Worksheet
    On Error Resume Next
    Application.DisplayAlerts = False
    Worksheets(“Team Quality Metrics”).Delete
    Sheets.Add Before:=ActiveSheet
    ActiveSheet.Name = “Team Quality Metrics”
    Application.DisplayAlerts = True
    Set PSheet = Worksheets(“Team Quality Metrics”)
    Set DSheet = Worksheets(“Temp”)

    ‘Define Data Range
    LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
    LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
    Set PRange = DSheet.Cells(1, 1).Resize(LastRow, LastCol)

    ‘Define Pivot Cache
    Set PCache = ActiveWorkbook.PivotCaches.Create _
    (SourceType:=xlDatabase, SourceData:=PRange). _
    CreatePivotTable(TableDestination:=PSheet.Cells(20, 2), _
    TableName:=”TeamQualityMetrics”)

    ‘Insert Blank Pivot Table
    Set PTable = PCache.CreatePivotTable _
    (TableDestination:=PSheet.Cells(19, 1), TableName:=”TeamQualityMetrics”)

    ‘Define Pivot Cache
    Set PCache = ActiveWorkbook.PivotCaches.Create _
    (SourceType:=xlDatabase, SourceData:=PRange). _
    CreatePivotTable(TableDestination:=PSheet.Cells(2, 2), _
    TableName:=”TeamQualityMetrics1″)

    ‘Insert Blank Pivot Table
    Set PTable = PCache.CreatePivotTable _
    (TableDestination:=PSheet.Cells(1, 1), TableName:=”TeamQualityMetric1″)

    ActiveWorkbook.SlicerCaches.Add2(ActiveSheet.PivotTables(“TeamQualityMetrics1”) _
    , “Author”).Slicers.Add ActiveSheet, , “Author”, “Author”, 122.4, 496.2, 144, _
    194.25

    Reply
  13. Hi Puneet,

    I have prepared the Pivot Table through your syntax of vba given, but I thing I need to know that there is one report filter at the top of Pivot where I have to select specific pivot items. Can you please describe the Syntax select Items from Report filter?

    Reagards,
    Naveen Pathak

    Reply
  14. Hi,

    For some reason my code only seems to be creating the tab and no creating the pivot table.
    I guess it is struggling to get the data from the source but honestly i’m not sure.

    My source data is from B4:U904.

    Sub CreatePivot()

    ‘Declare Variables
    Dim PSheet As Worksheet
    Dim DSheet As Worksheet
    Dim PCache As PivotCache
    Dim PTable As PivotTable
    Dim PRange As Range
    Dim LastRow As Long
    Dim LastCol As Long

    ‘Declare Variables
    On Error Resume Next
    Application.DisplayAlerts = False
    Worksheets(“PivotTable”).Delete
    Sheets.Add Before:=ActiveSheet
    ActiveSheet.Name = “PivotTable”
    Application.DisplayAlerts = True
    Set PSheet = Worksheets(“PivotTable”)
    Set DSheet = Worksheets(“Data”)

    ‘Define Data Range
    LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
    LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
    Set PRange = DSheet.Cells(4, 2).Resize(LastRow, LastCol)

    ‘Define Pivot Cache
    Set PCache = ActiveWorkbook.PivotCaches.Create _
    (SourceType:=xlDatabase, SourceData:=PRange). _
    CreatePivotTable(TableDestination:=PSheet.Cells(3, 1), _
    TableName:=”PivotTable1″)

    Set PTable = PCache.CreatePivotTable _
    (TableDestination:=PSheet.Cells(1, 1), TableName:=”PivotTable1″)

    ‘Insert Row Fields
    With ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Threshold result”)
    .Orientation = xlRowField
    .Position = 1
    End With

    With ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Applicable”)
    .Orientation = xlRowField
    .Position = 2
    End With

    With ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Frequency”)
    .Orientation = xlRowField
    .Position = 3
    End With

    ‘Insert Data Field
    With ActiveSheet.PivotTables(“PivotTable1”).PivotFields(“Amount”)
    .Orientation = xlDataField
    .Position = 1
    .Function = xlSum
    .NumberFormat = “#,##0”
    .Name = “Count of Metric assignment ID”
    End With

    ‘Format Pivot
    TableActiveSheet.PivotTables(“PivotTable1”).ShowTableStyleRowStripes = TrueActiveSheet.PivotTables(“PivotTable1”).TableStyle2 = “PivotStyleMedium9”

    End Sub

    Any help would be much appreciated! .
    Thanks,
    Nathan

    Reply
  15. Pivot cache fix!

    Hi,

    I was really struggling to get it to work. The solution is actually really simple.
    You need to get rid of the destination in PCashe (this code is repeated later on in insert blank pivot table.

    Cheers,
    Mat

    ‘Define Pivot Cache
    Set PCache = ActiveWorkbook.PivotCaches.Create(xlDatabase, “T_GRIR”)

    ‘Insert Blank Pivot Table
    Set PTable = PCache.CreatePivotTable _
    (TableDestination:=PSheet.Cells(1, 1), TableName:=”GRIRpt”)

    Reply
  16. HI Punnet,
    I copied your code but when I use a command button to automatically update the pivot table, it doesn’t work. At first when i click my command button a blank pivot table appears and when i go back to my module where i copied your code then click the run again it appears the data. Why is it happening and everytime i click the run button in my module it adds more and more data that came from my source sheet.

    Reply
  17. Hey Puneet, I used this code successfully in a couple of spreadsheet. However when I tried to use this with a spreadsheet where its data set starts from Row 7 (Row 1 to Row 6 are just informative) and having a Grand Total Row in the last Row, it just doesnt work as it should.

    I tried using offset function to omit the last row by -1 when defining the data range for LastRow but it still captured the Grand Total Row.

    I set PRange as DSheet.Cells(7,1) as well, it still captured blank rows for some reason.

    I debugged and narrowed down to the Define Data Range section where