I am trying to get my Public Sub to make a call against two functions, each creating different pivot tables off of the same data sheet. I know that both of my functions work independently, but I keep getting an "application defined or object defined error" when I combine them in to a single sub.
The macro below does execute the first function and creates the intended pivot table. It just stops when it gets to the second function and provides me with the application or object defined error mentioned above. I have independently defined each function so I am not sure why I am getting an issue.
Option Explicit
Public Sub RunPivots()
Call BuildPivot1("Travel Payment Data by Employee")
Call BuildPivot2("Travel Payment Data by Acct Dim")
End Sub
Function BuildPivot1(paramSheet As String)
On Error GoTo ErrHandle
Dim FinalRow As Long
Dim DataSheet As String
Dim PvtCache As PivotCache
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
Dim DataRng As Range
Dim TableDest As Range
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
If ws.Name Like "*SQL" & "*" Then
'~~> This check is required to ensure that you don't get an error
'~~> if there is only one sheet left and it matches the delete criteria
If ThisWorkbook.Sheets.Count = 1 Then
MsgBox "There is only one sheet left and you cannot delete it"
Else
'~~> This is required to supress the dialog box which excel shows
'~~> When you delete a sheet. Remove it if you want to see the
'~~~> Dialog Box
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
End If
Next
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
DataSheet = "Export Worksheet"
' set data range for Pivot Table
Set DataRng = Sheets(DataSheet).Range(Cells(1, 1), Cells(FinalRow, 15))
' check if worksheet exists
Dim currws As Worksheet
For Each currws In ActiveWorkbook.Worksheets
If currws.Name = paramSheet Then
Set ws = Worksheets(paramSheet)
Exit For
End If
Next currws
' create new worksheet if does not exist
If ws Is Nothing Then
Set ws = Worksheets.Add
ws.Name = paramSheet
End If
' set range for Pivot table placement
Set TableDest = Sheets(paramSheet).Cells(1, 1)
' create pivot cache
Set PvtCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=DataRng, _
Version:=xlPivotTableVersion15)
'check if "PivotTable4" Pivot Table exists
Dim currpvt As PivotTable
For Each currpvt In ws.PivotTables
If currpvt.Name = "PivotTable4" Then
Set PvtTbl = ws.PivotTables("PivotTable4")
Exit For
End If
Next currpvt
' create new pivot table if does not exist
If PvtTbl Is Nothing Then
Set PvtTbl = PvtCache.CreatePivotTable( _
TableDestination:=TableDest, _
TableName:="PivotTable4")
End If
With PvtTbl.PivotFields("Security Org")
.Orientation = xlRowField
.Position = 1
End With
With PvtTbl.PivotFields("Fiscal Month")
.Orientation = xlRowField
.Position = 2
End With
With PvtTbl.PivotFields("Budget Org")
.Orientation = xlRowField
.Position = 3
End With
With PvtTbl.PivotFields("Vendor Name")
.Orientation = xlRowField
.Position = 4
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlRowField
.Position = 5
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlColumnField
.Position = 1
End With
Range("B:E").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "$#,##0.00"
Range("B1").Select
PvtTbl.CompactLayoutColumnHeader = _
"Fiscal Year"
Range("A2").Select
PvtTbl.CompactLayoutRowHeader = _
"Security Org and Vendor"
Range("G8").Select
' Add data field if does not exist
On Error Resume Next
PvtTbl.AddDataField PvtTbl.PivotFields("Dollar Amount"), "Sum of Dollar Amount", xlSum
PvtTbl.PivotFields("Budget Org").ShowDetail = _
False
Exit Function
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Exit Function
End Function
Function BuildPivot2(paramSheet As String)
On Error GoTo ErrHandle
Dim FinalRow As Long
Dim DataSheet As String
Dim PvtCache As PivotCache
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
Dim DataRng As Range
Dim TableDest As Range
Dim ws As Worksheet
For Each ws In ThisWorkbook.Sheets
If ws.Name Like "*SQL" & "*" Then
'~~> This check is required to ensure that you don't get an error
'~~> if there is only one sheet left and it matches the delete criteria
If ThisWorkbook.Sheets.Count = 1 Then
MsgBox "There is only one sheet left and you cannot delete it"
Else
'~~> This is required to supress the dialog box which excel shows
'~~> When you delete a sheet. Remove it if you want to see the
'~~~> Dialog Box
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End If
End If
Next
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
DataSheet = "Export Worksheet"
' set data range for Pivot Table
DataSheet = "Export Worksheet"
' set data range for Pivot Table
With Sheets(DataSheet)
Set DataRng = .Range(Cells(1, 1), .Cells(FinalRow, 15))
End With
' check if worksheet exists
Dim currws As Worksheet
For Each currws In ActiveWorkbook.Worksheets
If currws.Name = paramSheet Then
Set ws = Worksheets(paramSheet)
Exit For
End If
Next currws
' create new worksheet if does not exist
If ws Is Nothing Then
Set ws = Worksheets.Add
ws.Name = paramSheet
End If
' set range for Pivot table placement
Set TableDest = Sheets(paramSheet).Cells(1, 1)
' create pivot cache
Set PvtCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=DataRng, _
Version:=xlPivotTableVersion15)
'check if "PivotTable4" Pivot Table exists
Dim currpvt As PivotTable
For Each currpvt In ws.PivotTables
If currpvt.Name = "PivotTable4" Then
Set PvtTbl = ws.PivotTables("PivotTable4")
Exit For
End If
Next currpvt
' create new pivot table if does not exist
If PvtTbl Is Nothing Then
Set PvtTbl = PvtCache.CreatePivotTable( _
TableDestination:=TableDest, _
TableName:="PivotTable4")
End If
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlColumnField
.Position = 1
End With
With PvtTbl.PivotFields("Fund")
.Orientation = xlRowField
.Position = 1
End With
With PvtTbl.PivotFields("Budget Org")
.Orientation = xlRowField
.Position = 2
End With
With PvtTbl.PivotFields("Cost Org")
.Orientation = xlRowField
.Position = 3
End With
Range("B:E").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.NumberFormat = "$#,##0.00"
Range("B1").Select
PvtTbl.CompactLayoutColumnHeader = _
"Fiscal Year"
Range("A2").Select
PvtTbl.CompactLayoutRowHeader = _
"Security Org and Vendor"
Range("G8").Select
' Add data field if does not exist
On Error Resume Next
PvtTbl.AddDataField PvtTbl.PivotFields("Dollar Amount"), "Sum of Dollar Amount", xlSum
PvtTbl.PivotFields("Budget Org").ShowDetail = _
False
Exit Function
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Exit Function
End Function
You need to make sure all of your Cells() and Range() calls are qualified with a worksheet object. For example:
Set DataRng = Sheets(DataSheet).Range(Cells(1, 1), Cells(FinalRow, 15))
will fail if the DataSheet worksheet is not the activesheet.
Fix like this:
With Sheets(DataSheet)
Set DataRng = .Range(.Cells(1, 1), .Cells(FinalRow, 15))
End With
Related
I've searched and found Create Pivot tables within a for loop, but haven't been able to get it to work.
I've got a workbook with 11 sheets and a table in each sheet, so I'd like to create a loop that will go through every sheet and create a pivot table next to the existing table.
I'm getting an "Invalid Procedure or argument " error for the Pivot Table code.
This code is probably far too simple, but here's my attempt:
sub PivotLoop()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Set cache = Nothing
Set PivT = Nothing
With ws
On Error Resume Next
On Error GoTo 0
Set cache = ThisWorkbook.PivotCaches.Create(SourceType:=xlDatabase, _
SourceData:=Range("Table" & ws.Index), Version:=xlPivotTableVersion15)
Set PivT = ws.PivotTables.Add(PivotCache:=cache, _
TableDestination:=Range("h2"), TableName:="PivotTable" & ws.Index)
End With
Next ws
End Sub
It's done essentially like this. In your specific case, it will obviously be slightly different, depending on your sheet names, your ranges, whether you want counts, sums, averages, etc.
Option Explicit
Sub test()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
' don't touch a sheet with a specific name...if needed...
If ws.Name <> "Master" Then
' now we want to build a pivot table
Range("A1").Select
Sheets.Add
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"Sheet1!R1C1:R10C3", Version:=xlPivotTableVersion15).CreatePivotTable _
TableDestination:="Sheet5!R3C1", TableName:="PivotTable1", DefaultVersion _
:=xlPivotTableVersion15
With ActiveSheet.PivotTables("PivotTable1").PivotFields("field1")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable1").PivotFields("field2")
.Orientation = xlColumnField
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("field3"), "Sum of field3", xlSum
End If
Next ws
End Sub
It helps a lot if you turn on the Macro recorder and see what kind of code it produces and you click through the steps.
Got it to work if anyone else wants to do it.
sub PivotTableLoop ()
Dim ws as Worksheet
Dim PivC As PivotCache
Dim PivT As PivotTable
Dim Table As ListObject
For Each ws In WeeklyReport.Worksheets
Set PivC = Nothing
Set PivT = Nothing
Set Table = Nothing
On Error Resume Next
' Set PivotTable Cache
Set PivC = WeeklyReport.PivotCaches.Create(SourceType:=xlDatabase, _
SourceData:=ws.ListObjects(1), Version:=xlPivotTableVersion15)
' Create the PivotTable
Set PivT = ws.PivotTables.Add(PivotCache:=PivC, _
TableDestination:=ws.Range("i2"), TableName:="PivotTable" & ws.Index)
On Error GoTo 0
For Each PivT In ws.PivotTables
PivT.PivotFields("day").Orientation = xlRowField
PivT.PivotFields("Competitor").Orientation = xlColumnField
PivT.AddDataField PivT.PivotFields("Sales"), xlSum
PivT.PivotFields("Sales").NumberFormat = "$0.00"
Next PivT
Next ws
End Sub
my problem is the following : I have a data source in sheets("Source") that I update time over time, so that the number of lines is increasing. I want to automatically update the Pivotables linked to this data source, in sheets("Overview") trhough a vba code. In Sheets ("Overview") there are 2 Pivot tables as well as plots.
Here is the code :
Sub UpdatePivotTableRange()
Dim Data_Sheet As Worksheet
Dim Pivot_Sheet As Worksheet
Dim StartPoint As Range
Dim DataRange As Range
Dim PivotName1 As String
Dim PivotName2 As String
Dim NewRange As String
Dim LastCol As Long
Dim lastRow As Long
'Set Pivot Table & Source Worksheet
Set Data_Sheet = ThisWorkbook.Worksheets("Source")
Set Pivot_Sheet = ThisWorkbook.Worksheets("Overview")
'Enter in Pivot Table Name
PivotName1 = "PivotTable1"
PivotName2 = "PivoTable2"
'Defining Staring Point & Dynamic Range
Data_Sheet.Activate
Set StartPoint = Data_Sheet.Range("A1")
LastCol = StartPoint.End(xlToRight).Column
DownCell = StartPoint.End(xlDown).Row
Set DataRange = Data_Sheet.Range(StartPoint, Cells(DownCell, LastCol))
NewRange = Data_Sheet.Name & "!" & DataRange.Address(ReferenceStyle:=xlR1C1)
'Change Pivot Tables Data Source Range Address
Pivot_Sheet.PivotTables(PivotName1). _
ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=NewRange)
Pivot_Sheet.PivotTables(PivotName2). _
ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=NewRange)
'Ensure Pivot Table is Refreshed
Pivot_Sheet.PivotTables(PivotName1).RefreshTable
Pivot_Sheet.PivotTables(PivotName2).RefreshTable
'Complete Message
Pivot_Sheet.Activate
MsgBox "Your Pivot Table is now updated."
End Sub
I get the following errors :
either "Run-time error'5': Invalid procedure call or argument" or;
"Run-time error '1004': The Pivot Table field name is not valid".
Can you help please ?
Regards,
Leopold
`
Instead of the address of the cell, you can apply the range area directly.
Sub UpdatePivotTableRange()
Dim Data_Sheet As Worksheet
Dim Pivot_Sheet As Worksheet
Dim StartPoint As Range
Dim DataRange As Range
Dim PivotName1 As String
Dim PivotName2 As String
Dim NewRange As String
Dim LastCol As Long
Dim lastRow As Long
Dim Pv As PivotTable
Dim Wb As Workbook
Dim pvFD As PivotField
Set Wb = ThisWorkbook
'Set Pivot Table & Source Worksheet
Set Data_Sheet = ThisWorkbook.Worksheets("Source")
Set Pivot_Sheet = ThisWorkbook.Worksheets("Overview")
'Enter in Pivot Table Name
PivotName1 = "PivotTable1"
PivotName2 = "PivoTable2"
'Defining Staring Point & Dynamic Range
Data_Sheet.Activate
Set StartPoint = Data_Sheet.Range("A1")
LastCol = StartPoint.End(xlToRight).Column
DownCell = StartPoint.End(xlDown).Row
With Data_Sheet
Set DataRange = .Range(StartPoint, .Cells(DownCell, LastCol))
'Set DataRange = StartPoint.CurrentRegion '<~~ same upper line
End With
'NewRange = Data_Sheet.Name & "!" & DataRange.Address(ReferenceStyle:=xlR1C1)
'Change Pivot Tables Data Source Range Address
Set Pv = Pivot_Sheet.PivotTables(PivotName1)
With Pv
.ChangePivotCache Wb.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=DataRange) '<~~ directly apply range object
.ClearTable '<~~ This is necessary because the item does not reflect well as it increases.
.RowAxisLayout xlCompactRow
.RefreshTable
End With
Set pvFD = Pv.PivotFields("id")
With pvFD
.Orientation = xlRowField
.Position = 1
End With
Set pvFD = Pv.PivotFields("name")
With pvFD
.Orientation = xlRowField
.Position = 2
End With
Set pvFD = Pv.PivotFields("id")
With pvFD
.Orientation = xlRowField
.Position = 1
End With
Set pvFD = Pv.CalculatedFields.Add("Mysum", Formula:="q1-q2")
With pvFD
.Orientation = xlDataField
.Position = 1
End With
Set Pv = Pivot_Sheet.PivotTables(PivotName2)
With Pv
.ChangePivotCache Wb.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=DataRange) '<~~ directly apply range object
.ClearTable '<~~ This is necessary because the item does not reflect well as it increases.
.RowAxisLayout xlOutlineRow
.RefreshTable
End With
Set pvFD = Pv.PivotFields("id")
With pvFD
.Orientation = xlRowField
.Position = 1
End With
Set pvFD = Pv.PivotFields("name")
With pvFD
.Orientation = xlRowField
.Position = 2
End With
Set pvFD = Pv.PivotFields("id")
With pvFD
.Orientation = xlRowField
.Position = 1
End With
Set pvFD = Pv.CalculatedFields.Add("Mymutiply", Formula:="q1*q2")
With pvFD
.Orientation = xlDataField
.Position = 1
End With
Pivot_Sheet.Activate
MsgBox "Your Pivot Table is now updated."
End Sub
Data Sheet
Pivot Sheet
I receive the error when set the pivot cache. I.e at this line:-
Set pvt = pvtCache.CreatePivotTable(TableDestination:=StartPvt, TableName:="PivotTable2")
I have used this macro in another workbook and I have not received this error.
Sub PivTable()
'
' Insert a pivot table
'
Dim sht As Worksheet
Dim pvtCache As PivotCache
Dim pvt As PivotTable
Dim StartPvt As String
Dim SrcData As String
Dim ws As Worksheet
Dim x As Long
Set ws = Worksheets("Cash Month End")
With ws
x = .Range("b999999").End(xlUp).Row
End With
'Data Range to pivot
SrcData = "Cash Month End!(R4C1:R" & x & "C24)"
' Insert Sheet
Sheets.Add.Name = "Cash Pivot"
'Where the pivot must start
StartPvt = "Cash Pivot!R3C1"
'Create the pivot cache
Set pvtCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=SrcData)
'Create Pivot Table from Pivot Cache
Set pvt = pvtCache.CreatePivotTable(TableDestination:=StartPvt, TableName:="PivotTable2")
'Add fields
With ActiveSheet.PivotTables("PivotTable2").PivotFields("Segment")
.Orientation = xlPageField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable2").PivotFields("Region")
.Orientation = xlRowField
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable2").AddDataField ActiveSheet.PivotTables( _
"PivotTable2").PivotFields("No."), "Sum of No", xlSum
End Sub
I am newbie in vba and am trying to create a PivotTable using VBA with excel.
I would like to creat like as below image as input sheet.
I am trying to add row labels of region, month, number, status and values are value1, value2 and total here I am able to set range for pivot, while executing it creates "pivottable" sheet only. not generate any pivot table for sheet1.
My Code:
Option Explicit
Public Sub Input_File__1()
ThisWorkbook.Sheets(1).TextBox1.Text = Application.GetOpenFilename()
End Sub
'======================================================================
Public Sub Output_File_1()
Dim get_fldr, item As String
Dim fldr As FileDialog
Set fldr = Application.FileDialog(msoFileDialogFolderPicker)
With fldr
.AllowMultiSelect = False
If .Show <> -1 Then GoTo nextcode:
item = .SelectedItems(1)
If Right(item, 1) <> "\" Then
item = item & "\"
End If
End With
nextcode:
get_fldr = item
Set fldr = Nothing
ThisWorkbook.Worksheets(1).TextBox2.Text = get_fldr
End Sub
'======================================================================
Public Sub Process_start()
Dim Raw_Data_1, Output As String
Dim Raw_data, Start_Time As String
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
Start_Time = Time()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Raw_Data_1 = ThisWorkbook.Sheets(1).TextBox1.Text
Output = ThisWorkbook.Sheets(1).TextBox2.Text
Workbooks.Open Raw_Data_1: Set Raw_data = ActiveWorkbook
Raw_data.Sheets("Sheet1").Activate
On Error Resume Next
'Worksheets("Sheet1").Delete
Sheets.Add before:=ActiveSheet
ActiveSheet.Name = "Pivottable"
Application.DisplayAlerts = True
Set PSheet = Worksheets("Pivottable")
Set DSheet = Worksheets("Sheet1")
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).coloumn
Set PRange = DSheet.Range("A1").CurrentRegion
Set PCache = ActiveWorkbook.PivotCaches.Create_(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(1, 1), TableName:="PRIMEPivotTable")
With PTable.PivotFields("Region")
.Orientation = xlRowField
.Position = 1
End With
This needs some tidying up but should get you started.
Note the use of Option Explicit so variables have to be declared.
Columns names are as per your supplied workbook.
Option Explicit
Sub test()
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim LastRow As Long
Dim LastCol As Long
Dim PRange As Range
Dim PCache As PivotCache
Dim PTable As PivotTable
Sheets.Add
ActiveSheet.Name = "Pivottable"
Set PSheet = Worksheets("Pivottable")
Set DSheet = Worksheets("Sheet1")
LastRow = DSheet.Cells(Rows.Count, 1).End(xlUp).Row
LastCol = DSheet.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = DSheet.Range("A1").CurrentRegion
Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable = PCache.CreatePivotTable(TableDestination:=PSheet.Cells(1, 1), TableName:="PRIMEPivotTable")
With PTable.PivotFields("Region")
.Orientation = xlRowField
.Position = 1
End With
With PTable.PivotFields("Channel")
.Orientation = xlRowField
.Position = 2
End With
With PTable.PivotFields("AW code")
.Orientation = xlRowField
.Position = 3
End With
PTable.AddDataField PSheet.PivotTables _
("PRIMEPivotTable").PivotFields("Bk"), "Sum of Bk", xlSum
PTable.AddDataField PSheet.PivotTables _
("PRIMEPivotTable").PivotFields("DY"), "Sum of DY", xlSum
PTable.AddDataField PSheet.PivotTables _
("PRIMEPivotTable").PivotFields("TOTal"), "Sum of TOTal", xlSum
End Sub
The code in my answer below is a little long, but it should deliver you the result you are seeking for.
First, to be on the safe side, first check if "Pivottable" sheet already exists in Raw_data workbook object (no need to create it again).
Second, the code is divided in the middle to 2 sections:
If the MACRO was ran before (this is the 2+ times you are running it), then "PRIMEPivotTable" Pivot-Table is already created, and there’s no need to create it again, or to set-up the Pivot-Table’s fields.
All you need to do is refresh the PivotTable with the updated PivotCache (with updated Pivot-Cache’s source range).
If this is the first time running this MACRO, then you need to set-up the PivotTable and all necessary PivotFields.
Detaile explanation of every step inide the code's comments.
Code
Option Explicit
Sub AutoPivot()
Dim Raw_data As Workbook
Dim PSheet As Worksheet
Dim DSheet As Worksheet
Dim PTable As PivotTable
Dim PCache As PivotCache
Dim PRange As Range
Dim LastRow As Long, LastCol As Long
Dim Raw_Data_1 As String, Output As String, Start_Time As String
Start_Time = Time()
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Raw_Data_1 = ThisWorkbook.Sheets(1).TextBox1.Text
Output = ThisWorkbook.Sheets(1).TextBox2.Text
' set the WorkBook object
Set Raw_data = Workbooks.Open(Raw_Data_1)
Set DSheet = Raw_data.Worksheets("Sheet1")
' first check if "Pivottable" sheet exits (from previous MACRO runs)
On Error Resume Next
Set PSheet = Raw_data.Sheets("Pivottable")
On Error GoTo 0
If PSheet Is Nothing Then '
Set PSheet = Raw_data.Sheets.Add(before:=Raw_data.ActiveSheet) ' create a new worksheet and assign the worksheet object
PSheet.Name = "Pivottable"
Else ' "Pivottable" already exists
' do nothing , or something else you might want
End If
With DSheet
LastRow = .Cells(.Rows.Count, 1).End(xlUp).Row
LastCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
' set the Pivot-Cache Source Range with the values found for LastRow and LastCol
Set PRange = .Range("A1", .Cells(LastRow, LastCol))
End With
' set a new/updated Pivot Cache object
Set PCache = ActiveWorkbook.PivotCaches.Add(SourceType:=xlDatabase, SourceData:=PRange.Address(True, True, xlA1, xlExternal))
' add this line in case the Pivot table doesn't exit >> first time running this Macro
On Error Resume Next
Set PTable = PSheet.PivotTables("PRIMEPivotTable") ' check if "PRIMEPivotTable" Pivot-Table already created (in past runs of this Macro)
On Error GoTo 0
If PTable Is Nothing Then ' Pivot-Table still doesn't exist, need to create it
' create a new Pivot-Table in "Pivottable" sheet
Set PTable = PSheet.PivotTables.Add(PivotCache:=PCache, TableDestination:=PSheet.Range("A1"), TableName:="PRIMEPivotTable")
With PTable
' add the row fields
With .PivotFields("Region")
.Orientation = xlRowField
.Position = 1
End With
With .PivotFields("month")
.Orientation = xlRowField
.Position = 2
End With
With .PivotFields("number")
.Orientation = xlRowField
.Position = 3
End With
With .PivotFields("Status")
.Orientation = xlRowField
.Position = 4
End With
' add the 3 value fields (as Sum of..)
.AddDataField .PivotFields("value1"), "Sum of value1", xlSum
.AddDataField .PivotFields("value2"), "Sum of value2", xlSum
.AddDataField .PivotFields("TOTal"), "Sum of TOTal", xlSum
End With
Else ' Pivot-Table "PRIMEPivotTable" already exists >> just update the Pivot-Table with updated Pivot-Cache (update Source Range)
' just refresh the Pivot cache with the updated Range
PTable.ChangePivotCache PCache
PTable.RefreshTable
End If
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
I am trying to create a pivot table on a new sheet. Additionally, I would like to create another call to create another different pivot table using the same data from the first data sheet.
having trouble with the macro below. I think it is a small error, but can't figure it out.
Sub Macro2()
Dim FinalRow As Long
Dim DataSheet As String
Dim PvtCache As PivotCache
Dim PvtTbl As PivotTable
Dim DataRng As Range
Dim TableDest As Range
Dim ws As Worksheet
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
DataSheet = ActiveSheet.Name
'set data range for Pivot Table -- ' conversion of R1C1:R & FinalRow & C15
Set DataRng = Sheets(DataSheet).Range(Cells(1, 1), Cells(FinalRow, 15))
Set ws = Worksheets.Add
ws.Name = "Travel Payment Data by Employee"
'set range for Pivot table placement -- Conversion of R1C1
Set TableDest = Sheets("Travel Payment Data by Employee").Cells(1, 1)
Set PvtCache = ActiveWorkbook.PivotCaches.Create(xlDatabase, DataRng, xlPivotTableVersion15)
'check if "PivotTable4" Pivot Table already created (in past runs of this Macro)
Set PvtTbl = ActiveWorkbook.Sheets("Travel Payment Data by Employee").PivotTables("PivotTable4")
With PvtTbl.PivotFields("Security Org")
.Orientation = xlRowField
.Position = 1
End With
With PvtTbl.PivotFields("Fiscal Month")
.Orientation = xlRowField
.Position = 2
End With
With PvtTbl.PivotFields("Budget Org")
.Orientation = xlRowField
.Position = 3
End With
With PvtTbl.PivotFields("Vendor Name")
.Orientation = xlRowField
.Position = 4
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlRowField
.Position = 5
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlColumnField
.Position = 1
End With
PvtTbl.AddDataField ActiveSheet.PivotTables( _
"PivotTable2").PivotFields("Dollar Amount"), "Sum of Dollar Amount", xlSum
End Sub
Consider the following adjustment with a subroutine calling a function, passing in new worksheet names for new identical pivot tables. If you do not intend identical pivots, adjust them in code conditionally by sheet name or copies of function. The main changes from your code are as follows:
ACTIVE SHEET: Remove the need to search ActiveSheet.Name as adding more worksheets will alter active sheets. Simply hard-code or pass as parameter the data source.
OBJECT CHECK: You need to check if Worksheet exits and PivotTable exists. For these, you will need to iterate through all current such objects and conditionally set worksheet, pivot table objects (see For...Next loops and If ... Is Nothing checks).
For PivotField, since Dollar Amounts will exist in Pivot Table data source but not necessarily display, iterating through all of them might not work like above. So conditionally add only if does not error out see On Resume Next handle.
VBA
Option Explicit
Public Sub RunPivots()
Call BuildPivot("Travel Payment Data by Employee")
Call BuildPivot("Other Worksheet")
Call BuildPivot("Still More Worksheet")
End Sub
Function BuildPivot(paramSheet As String)
On Error GoTo ErrHandle
Dim FinalRow As Long
Dim DataSheet As String
Dim PvtCache As PivotCache
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
Dim DataRng As Range
Dim TableDest As Range
Dim ws As Worksheet
FinalRow = Cells(Rows.Count, 1).End(xlUp).Row
DataSheet = "DataSourceWorksheet"
' set data range for Pivot Table
Set DataRng = Sheets(DataSheet).Range(Cells(1, 1), Cells(FinalRow, 15))
' check if worksheet exists
Dim currws As Worksheet
For Each currws In ActiveWorkbook.Worksheets
If currws.Name = paramSheet Then
Set ws = Worksheets(paramSheet)
Exit For
End If
Next currws
' create new worksheet if does not exist
If ws Is Nothing Then
Set ws = Worksheets.Add
ws.Name = paramSheet
End If
' set range for Pivot table placement
Set TableDest = Sheets(paramSheet).Cells(1, 1)
' create pivot cache
Set PvtCache = ActiveWorkbook.PivotCaches.Create( _
SourceType:=xlDatabase, _
SourceData:=DataRng, _
Version:=xlPivotTableVersion15)
'check if "PivotTable4" Pivot Table exists
Dim currpvt As PivotTable
For Each currpvt In ws.PivotTables
If currpvt.Name = "PivotTable4" Then
Set PvtTbl = ws.PivotTables("PivotTable4")
Exit For
End If
Next currpvt
' create new pivot table if does not exist
If PvtTbl Is Nothing Then
Set PvtTbl = PvtCache.CreatePivotTable( _
TableDestination:=TableDest, _
TableName:="PivotTable4")
End If
With PvtTbl.PivotFields("Security Org")
.Orientation = xlRowField
.Position = 1
End With
With PvtTbl.PivotFields("Fiscal Month")
.Orientation = xlRowField
.Position = 2
End With
With PvtTbl.PivotFields("Budget Org")
.Orientation = xlRowField
.Position = 3
End With
With PvtTbl.PivotFields("Vendor Name")
.Orientation = xlRowField
.Position = 4
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlRowField
.Position = 5
End With
With PvtTbl.PivotFields("Fiscal Year")
.Orientation = xlColumnField
.Position = 1
End With
' Add data field if does not exist
On Error Resume Next
PvtTbl.AddDataField PvtTbl.PivotFields("Dollar Amount"), "Sum of Dollar Amount", xlSum
Exit Function
ErrHandle:
MsgBox Err.Number & " - " & Err.Description, vbCritical, "RUNTIME ERROR"
Exit Function
End Function