Home
About me



 VBA Programming
Download my Add-In tool (run on 32-bit MS Office Excel)
VBA Basic for beginners
Excel Main Objects
More with Rows, Columns, Cells, Range ...
Working around your Worksheet ...
Statements
Functions
Conditional Statements and Loops Structure
Errors Handling
UserForms
Pivot Tables
Charting
AutoFilter, Advanced Filter
File I/O VBA Examples
ADO and DAO, integrating Excel and Access
Other VBA fun staff
 

Automating Pivot Tables

You usually create your pivot table from the Excel User Interface by choosing from Data menu item: Data>PivotTable and PivotChart Report Wizard, but you can also use VBA to create pivot table such as when you want to automate your routine summary report.

Figure 1.1 Click on the Layout button will bring you to the Pivot Table Layout dialog as shown in the next diagram



 


Figure 1.2  You can drag Field names from the right-hand side and drop them in the Row, Column, and Data areas of the PivotTable and PivotChart Report Wizard Layout dialog.



 

Figure 1.3  When you are done, click OK, then click Finish, and almost instantly, Excel creates a summary of the data that you want to see.




 

Figure 1.4 below shows another field ‘MATERIAL_STATUS’ was added to the Row area of the pivot table. You can add and remove other fields as you like to the Row, Column, and Data areas. You can move REGION to the Top, or to the Right, or to the Column, all depends on your need.




CreatePivotTable method 

The following example demonstrates an auto-creation of pivot table using VBA. In Excel 2000 and newer versions, you would first build a PivotCache object to input the data range. After the pivot table is defined, you use CreatePivotTable method to input pivot table output destination and pivot table name, and with this you create a blank pivot table based on your defined PivotCache.  In the .AddFields method, you can specify one or more fields that you want to include in the Row, Column, or Data area of the pivot table. To add a field (‘Material’ as in this example) to the Page Data area of the pivot table, you would change Orientation property of the field to xlDataField.

' Define input area and set up a pivot cache
Dim wsh As Worksheet, rng As Range, lastRow As Long, pt as PivotTable
lastRow = ActiveSheet.Cells(65536, 1).End(xlUp).Row
Set wsh = Worksheets("sheet1")
Set rng = wsh.Cells(1, 1).Resize(lastRow, 9)

' Delete any prior pivot tables
On Error Resume Next

For Each pt In wsh.PivotTables

    pt.TableRange2.Clear   ' TableRange2 refers to cell range of the entire pivot table

Next pt

ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, SourceData:= _
  rng.Address).CreatePivotTable TableDestination:=Sheets.Add.Cells(3, 1), _
  TableName:="PivotTable"

' Set up the Row and Column fields
ActiveSheet.PivotTables("PivotTable").AddFields RowFields:="Material_Status" _
  , ColumnFields:=Array("Location", "Region")

' Set up the Data field
ActiveSheet.PivotTables("PivotTable").PivotFields("Material").Orientation = _
  xlDataField

‘ Setting the Function property to xlSum allow you to use summation instead of using xlCount
ActiveSheet.PivotTables("PivotTable").PivotFields("Count of Material").Function = xlSum

‘ At this point, if you set the ManualUpdate to False, Excel calculates. You can immediately thereafter set it back to True
pt.ManualUpdate = False
pt.ManualUpdate = True

We begin with the data basis of a PivotCache object, from which pivot table is created with the CreatePivotTable method. Instead of using .AddFields method in the above example, we can use the Orientation property in the With..End With statement to change the orientation of the pivot fields as shown below. In this example, you see that we can suppress both the Sub-Total for the multiple column fields, and also the Grand Total rows and Grand Total columns. It also show you how to create a new workbook, give the new worksheet a name, copy the TableRange2 property and offset it by one row (to eliminate copying the title row in row 1, with the button something like ‘Sum of Material’), use paste Special option to paste only the values and format numbers. Note that xlPasteFormulasAndNumberFormats gets rid of both borders and the pivot nature of the table, but you could also use xlPasteAllExceptBorders. The final output should look like this sample.

Here is the code:

Dim ws As Worksheet, wsh As Worksheet, pt As PivotTable, pc As PivotCache
Dim rng As Range, lastRow As Long, wba As Workbook, wsp As Worksheet
lastRow = ActiveSheet.Cells(65536, 1).End(xlUp).Row
Set ws = Worksheets("sheet1")
Set rng = ws.Cells(1, 1).Resize(lastRow, 9)

On Error Resume Next
For Each pt In ws.PivotTables
  pt.TableRange2.Clear  'TableRange2 refers to cell range of the entire pivot table
Next

Set pc = ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase,SourceData:=rng.Address)
Set pt = pc.CreatePivotTable(TableDestination:=Sheets.Add.Range("A3"),
    TableName:="myPivotTable")

‘ To change the orientation of the pivot fields
With pt
   .PivotFields("Material").Orientation = xlDataField
   .PivotFields("Region").Orientation = xlRowField
   .PivotFields("Material_Status").Orientation = xlRowField
   .PivotFields("Location").Orientation = xlColumnField
End With

pt.PivotFields("Region").Subtotals(1) = False ' suppressing the subtotals for multiple column fields
pt.ColumnGrand = False   ‘ suppressing the Grand Total for rows
pt.RowGrand = True       ' set to False will suppress the Grand Total for Columns

Set wba = Workbooks.Add(xlWBATWorksheet)   ‘ create a new workbook to hole the pivot table report
Set wsp = wba.Worksheets(1)
wsp.Name = "summary report"      
‘ give the first worksheet in the new workbook a title
pt.TableRange2.Offset(1, 0).Copy  ‘ use Offset(1,0)  to avoid copy the title row of the pivot table

‘ copy the pivot table data to row 1 of the new report sheet
wsp.[A1].PasteSpecial Paste:=xlPasteFormulasAndNumberFormats
pt.TableRange2.Clear 
‘ erase the original pivot table
Set pc = Nothing      ‘ dissociate variable ‘pc’  from the object.

Note: if you want to have zeros instead of blanks in the Data area of the pivot table, use the following line:

pt.NullString = "0"

Return To Top

Filling in the blank Outline view in column A

If you had been using reports obtained pivot tables, you would notice this blank Outline view which are quite meaningless, usually in column A [see sample].  Here is a simple code that would let you fill in all those blank with the cell above it. See this sample output after you have executed the code.

Dim finalrow As Long
finalrow = Worksheets("summary report").Range("B65536").End(xlUp).Row
With Worksheets("summary report").Range("A3").Resize(finalrow - 2, 1)
  With .SpecialCells(xlCellTypeBlanks)
    .FormulaR1C1 = "=R[-1]C"
  End With
  .Value = .Value
End With

 

The following procedure combines all the methods that I have demonstrated above on creating pivot table and different ways of moving around cells, formatting and sorting the static summary report. This diagram shot is the exact output of what you should be seeing after you run the code. You can also DOWNLOAD the worksheet sample here.

Option Explicit
' Using pivot table to create a summary report, move around cells and formatting
Sub CreatePivotTable_SummaryReport()
Dim wsd As Worksheet
Dim pRange As Range
Dim ptCache As PivotCache
Dim pt As PivotTable
Dim finalrow As Long, finalcolumn As Long
Set wsd = Worksheets("sheet1")

' Delete all pivot tables
For Each pt In wsd.PivotTables
    pt.TableRange2.Clear
Next pt

' Define last row, last column, input area, and set up a pivot cache
finalrow = wsd.Cells(65536, 1).End(xlUp).Row
finalcolumn = wsd.Cells(1, 255).End(xlToLeft).Column
Set pRange = wsd.Cells(1, 1).Resize(finalrow, finalcolumn)
Set ptCache = ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, _
   SourceData:=pRange.Address)
Set pt = ptCache.CreatePivotTable(tabledestination:=wsd.Range("J2"), _
   tablename:="PivotTable1")

' Set up the row fields and column fields
pt.AddFields RowFields:=Array("Region", "Material_Status"), ColumnFields:="Location"

' Set up the Data area field, set function property to Summation, format as $ in K
' Move the PivotItem object (ie. pivot field 'Stock On-Hand') to the first position

With pt.PivotFields("Stock On-Hand")
    .Orientation = xlDataField
    .Function = xlSum
    .Position = 1
    .NumberFormat = "$#,##0,\K"
End With

With pt
    .PivotFields("Region").Subtotals(1) = False
' suppressing the subtotals for multiple column fields
    .ColumnGrand = False    ' suppressing the Grand Total for rows
    .RowGrand = True
    .NullString = "0"
End With

' Calculate the pivot table
pt.ManualUpdate = False
pt.ManualUpdate = True

' Copy data from pt.TableRange2 property to Cell S2, and wipe out the constants that were pasted
pt.TableRange2.Offset(1, 0).Copy
Worksheets("sheet1").Cells(2, finalcolumn + 11).PasteSpecial _
  Paste:=xlPasteFormulasAndNumberFormats

' Delete original pivot table & pivot cache
pt.TableRange2.Clear
Set ptCache = Nothing

' Fill all blanks in Outline view
Range(Range("IV2").End(xlToLeft).Address).End(xlToLeft).Offset(, 1).Select
Range(ActiveCell, ActiveCell.End(xlDown)).Rows.Offset(, -1).Select
With Selection
  With .SpecialCells(xlCellTypeBlanks)
    .FormulaR1C1 = "=R[-1]C"
  End With
  .Value = .Value
End With

' Delete unwanted empty columns, formatting and sorting in a designated column
Range(ActiveCell.Offset(, -1), ActiveCell.End(xlToLeft).Offset(, 2).Address) _
   .EntireColumn.Delete
Range("IV2").End(xlToLeft).Offset(1, 0).Select
Range(ActiveCell, ActiveCell.End(xlDown)).Rows.Select
With Selection
    .Font.Size = 11
    .Font.ColorIndex = 3
    .Font.Bold = True
End With

' Autofit the selection columns
Selection.Offset(-1, 0).Resize(Selection.Rows.Count + 1, Selection.Columns.Count _
   + 6).Offset(, -6).Select
Selection.Columns.AutoFit

' Sort by Grand Total
Rows("1:2").Find(What:="Grand Total", SearchDirection:=xlNext).Activate
Selection.Sort Key1:=ActiveCell, Order1:=xlDescending, Orientation:=xlTopToBottom

End Sub

 

A note on Sort Method
 
It sorts a PivotTable report, a range, or the active region if the specified range contains only one cell.

expression.Sort(Key1, Order1, Key2, Type, Order2, Key3, Order3, Header, OrderCustom, MatchCase, Orientation, SortMethod, DataOption1, DataOption2, DataOption3)

expression Required. An expression that returns one of the objects in the Applies To list.


Key1
Optional Variant. The first sort field, as either text (a PivotTable field or range name) or a Range object ("Dept" or Cells(1, 1), for example).


Order1
Optional Error! Hyperlink reference not valid.. The sort order for the field or range specified in Key1.

XlSortOrder can be one of these XlSortOrder constants:

  • xlDescending. Sorts Key1 in descending order.
  • xlAscending default. Sorts Key1 in ascending order.


K
ey2 Optional Variant. The second sort field, as either text (a PivotTable field or range name) or a Range object. If you omit this argument, there’s no second sort field. Cannot be used when sorting Pivot Table reports.


Type
Optional Error! Hyperlink reference not valid.. Specifies which elements are to be sorted. Use this argument only when sorting PivotTable reports.

XlSortType can be one of these XlSortType constants:

  • xlSortLabels. Sorts the PivotTable report by labels.
  • xlSortValues. Sorts the PivotTable report by values.


Order2
Optional Error! Hyperlink reference not valid.. The sort order for the field or range specified in Key2. Cannot be used when sorting PivotTable reports.

XlSortOrder can be one of these XlSortOrder constants:

  • xlDescending. Sorts Key2 in descending order.
  • xlAscending default. Sorts Key2 in ascending order.


Key3
Optional Variant. The third sort field, as either text (a range name) or a Range object. If you omit this argument, there’s no third sort field. Cannot be used when sorting PivotTable reports.


Order3
Optional Error! Hyperlink reference not valid.. The sort order for the field or range specified in Key3. Cannot be used when sorting PivotTable reports.

XlSortOrder can be one of these XlSortOrder constants:

  • xlDescending. Sorts Key3 in descending order.
  • xlAscending default. Sorts Key3 in ascending order.


Header
Optional Error! Hyperlink reference not valid.. Specifies whether or not the first row contains headers. Cannot be used when sorting PivotTable reports.

XlYesNoGuess can be one of these XlYesNoGuess constants:

  • xlGuess. Let Microsoft Excel determine whether there’s a header, and to determine where it is, if there is one.
  • xlNo default. (The entire range should be sorted).
  • xlYes. (The entire range should not be sorted).

OrderCustom Optional Variant. This argument is a one-based integer offset to the list of custom sort orders. If you omit OrderCustom , a normal sort is used.


MatchCase
Optional Variant. True to do a case-sensitive sort; False to do a sort that’s not case sensitive. Cannot be used when sorting PivotTable reports.


Orientation
Optional Error! Hyperlink reference not valid.. The sort orientation.

XlSortOrientation can be one of these XlSortOrientation constants.

  • xlSortRows default. Sorts by row.
  • xlSortColumns. Sorts by column.


SortMethod
Optional Error! Hyperlink reference not valid.. The type of sort. Some of these constants may not be available to you, depending on the language support (U.S. English, for example) that you’ve selected or installed.

XlSortMethod can be one of these XlSortMethod constants.

  • xlStroke Sorting by the quantity of strokes in each character.
  • xlPinYin default. Phonetic Chinese sort order for characters.


DataOption1
Optional Error! Hyperlink reference not valid.. Specifies how to sort text in key 1. Cannot be used when sorting PivotTable reports.

XlSortDataOption can be one of these XlSortDataOption constants”

  • xlSortTextAsNumbers. Treat text as numeric data for the sort.
  • xlSortNormal default. Sorts numeric and text data separately.


DataOption2
Optional Error! Hyperlink reference not valid.. Specifies how to sort text in key 2. Cannot be used when sorting PivotTable reports.

XlSortDataOption can be one of these XlSortDataOption constants:

  • xlSortTextAsNumbers. Treats text as numeric data for the sort.
  • xlSortNormal default. Sorts numeric and text data separately.


DataOption3
Optional Error! Hyperlink reference not valid.. Specifies how to sort text in key 3. Cannot be used when sorting PivotTable reports.

XlSortDataOption can be one of these XlSortDataOption constants:

  • xlSortTextAsNumbers. Treats text as numeric data for the sort.
  • xlSortNormal default. Sorts numeric and text data separately.

Remarks:
The settings for Header, Order1, Order2, Order3, OrderCustom, and Orientation are saved, for the particular worksheet, each time you use this method. If you don’t specify values for these arguments the next time you call the method, the saved values are used. Set these arguments explicitly each time you use Sort method, if you choose not to use the saved values.

Text strings which are not convertible to numeric data are sorted normally. 

Note:  If no arguments are defined with the Sort method, Microsoft Excel will sort the selection, chosen to be sorted, in ascending order.

This example sorts the range A1:C20 on Sheet1, using cell A1 as the first sort key and cell B1 as the second sort key. The sort is done in ascending order by row, and there are no headers. This example assumes there is data in the range A1:C20.
Sub SortRange1()
   Worksheets("Sheet1").Range("A1:C20").Sort _
        Key1:=Worksheets("Sheet1").Range("A1"), _
        Key2:=Worksheets("Sheet1").Range("B1")
End Sub


This example sorts the region that contains cell A1 (the active region) on Sheet1, sorting by the data in the first column and automatically using a header row if one exists. This example assumes there is data in the active region, which includes cell A1. The Sort method determines the active region automatically.
Sub SortRange2()
   Worksheets("Sheet1").Range("A1").Sort _
        Key1:=Worksheets("Sheet1").Columns("A"), Header:=xlGuess
End Sub

Return To Top

This site was created in Feb.2007
by William Tan