How to make my pivot fields dynamic in vba code - vba

I have a pivot table that sorts data for various people for each month over a 12-month period. The table that the data is generated from has a dynamic date range (ie the user can specify the start date which will cascade through the table). The pivot table and chart is generated from this master table as part of the data analysis.
This worked fantastic last month when I created this tool, however I realised in my code I have hard-coded names of the pivot fields to correspond to months from April (please see below). This makes my pivot table break when I try to run it from a start date in May. How can I make the "PivotFields"/data fields in the pivot table dynamic to correspond to the date range?
Relevant piece of the code found below. As one would expect, the error happens at:
"Compare individuals").PivotFields("Apr-17"), "Sum of Apr-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField
When trying to run my pivot chart/report from May.
Really appreciate any pointers!
Option Explicit
Sub CreatePivot()
Dim pt As PivotTable
Dim pf As PivotField
Dim pi As PivotItem
Dim pc As PivotCache
With ActiveWorkbook
For Each pc In .PivotCaches
pc.MissingItemsLimit = xlMissingItemsNone
Next pc
End With
'Generate base pivot chart
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"Indy", Version:=xlPivotTableVersion10). _
CreatePivotTable TableDestination:="'PivotSheet'!R8C6", TableName:="Compare individuals" _
, DefaultVersion:=xlPivotTableVersion10
Worksheets("PivotSheet").Activate
'Set Name and disc as field and filter respectively
With ActiveSheet.PivotTables("Compare individuals").PivotFields("Name")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("Compare individuals").PivotFields("Disc ")
.Orientation = xlPageField
.Position = 1
End With
'Add data; sums of each month per individual
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Apr-17"), "Sum of Apr-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("May-17"), "Sum of May-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Jun-17"), "Sum of Jun-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Jul-17"), "Sum of Jul-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Aug-17"), "Sum of Aug-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Sep-17"), "Sum of Sep-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Oct-17"), "Sum of Oct-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Nov-17"), "Sum of Nov-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Dec-17"), "Sum of Dec-17", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Jan-18"), "Sum of Jan-18", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Feb-18"), "Sum of Feb-18", xlSum
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields("Mar-18"), "Sum of Mar-18", xlSum
ActiveSheet.PivotTables("Compare individuals").PivotFields("Disc ").CurrentPage = _
"(All)"
'Set data in columns
With ActiveSheet.PivotTables("Compare individuals").DataPivotField
.Orientation = xlColumnField
.Position = 1
End With
EDIT: a bit more context.
My PivotTable looks like this:
The error ostensibly shows up because there's no "Apr-17" in the actual data table
My source data looks like this:
Wherein the months/date range are dynamic (from initial input).
What I want the code to do is this:
Ie put all the date columns into the table regardless of what they are called.

#A.Doe, give this a try
Dim f1 As PivotField
For Each f1 In ActiveSheet.PivotTables("Compare individuals").PivotFields
'MsgBox f1.Name test code
If (InStr(f1.Name, "17") > 0) Then 'or some valid condition
ActiveSheet.PivotTables("Compare individuals").AddDataField ActiveSheet.PivotTables( _
"Compare individuals").PivotFields(f1.Name), "Sum of " & f1.Name, xlSum
End If
Next

Related

application defined or object defined error when creating calculated fields

ActiveSheet.PivotTables("PivotTable13").AddDataField ActiveSheet.PivotTables( _
"PivotTable13").PivotFields("OOS VALUE"), "Sum of OOS VALUE", xlSum
ActiveSheet.PivotTables("PivotTable13").AddDataField ActiveSheet.PivotTables( _
"PivotTable13").PivotFields("Sales"), "Sum of Sales", xlSum
ActiveSheet.PivotTables("PivotTable13").CalculatedFields.Add "OOS", _
"=OOS VALUE/Sales", True
ActiveSheet.PivotTables("PivotTable13").PivotFields("OOS").Orientation = _
xlDataField
With ActiveSheet.PivotTables("PivotTable13").PivotFields("Sum of OOS VALUE")
.NumberFormat = "?#,##0.00"
End With
With ActiveSheet.PivotTables("PivotTable13").PivotFields("Sum of Sales")
.NumberFormat = "?#,##0.00"
End With
With ActiveSheet.PivotTables("PivotTable13").PivotFields("Sum of OOS")
.NumberFormat = "0.00%"
End With
I am getting the application defined or object defined error at the part where the calculated field is made. what's wrong? i'm using the record a macro feature if that helps

Excel VBA that Creates a Pivot Table

I have this macro that takes all of sheet1 and creates a pivot table of it. However, it is currently only looking at the amount of rows I had when I made it and not the entire sheet no matter how many rows it has that day. Is there any way to make it select all of sheet1 as the pivot table data every time?
If possible I would also like to alter the fix duplicates to be the entire column based on the column name (IDNUMBER) if able.
Range("$A$1:$AM$2428")
Range("$A$1:$AM$4000")
"PIVOT_STATE_REPORT!R1C1:R1048576C39"
Sub PIVOT_STATE()
'
' PIVOT_STATE Macro
'
'
'ActiveSheet.Range("$A$1:$AM$2428").RemoveDuplicates Columns:=36, Header:= _
'xlYes
Columns("AJ:AJ").Select
ActiveSheet.Range("$A$1:$AM$4000").RemoveDuplicates Columns:=36, Header:= _
xlYes
Range("A2").Select
Sheets.Add
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"PIVOT_STATE_REPORT!R1C1:R1048576C39", Version:=xlPivotTableVersion15). _
CreatePivotTable TableDestination:="Sheet1!R3C1", TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion15
Sheets("Sheet1").Select
Cells(3, 1).Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("State (Corrected)")
.Orientation = xlRowField
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Count"), "Sum of Count", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Claim Age in CS"), _
"Sum of Claim Age in CS", xlSum
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Days Since LHN"), _
"Sum of Days Since LHN", xlSum
Range("B3").Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Count")
.Caption = "Count of Count"
.Function = xlCount
End With
Range("C3").Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields( _
"Sum of Claim Age in CS")
.Caption = "Average of Claim Age in CS"
.Function = xlAverage
.NumberFormat = "0"
End With
Range("D3").Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields( _
"Sum of Days Since LHN")
.Caption = "Average of Days Since LHN"
.Function = xlAverage
.NumberFormat = "0"
End With
With ActiveSheet.PivotTables("PivotTable1").PivotFields("State (Corrected)")
End With
End Sub
Thanks in advance!
I would use the last row and column formulas provided in this function.
Then make the source a combo of these variables.
Function LastRowColumn(sht As Worksheet, RowColumn As String) As Long
'PURPOSE: Function To Return the Last Row Or Column Number In the Active
Spreadsheet
'INPUT: "R" or "C" to determine which direction to search
Dim rc As Long
Select Case LCase(Left(RowColumn, 1)) 'If they put in 'row' or column instead of 'r' or 'c'.
Case "c"
LastRowColumn = sht.Cells.Find("*", LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious).Column
Case "r"
LastRowColumn = sht.Cells.Find("*", LookIn:=xlFormulas, SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious).Row
Case Else
LastRowColumn = 1
End Select
End Function
Then inside of your macro call out:
x = LastRowColumn(ActiveSheet, "column")
y = LastRowColumn(ActiveSheet, "Row")
plast = cells(x,y)
Then make a range based off that for the source of the pivot table
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"PIVOT_STATE_REPORT!A1:" & plast, Version:=xlPivotTableVersion15). _
CreatePivotTable TableDestination:="Sheet1!R3C1", TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion15
I think the easiest way of doing this will be to replace these lines of your code
Columns("AJ:AJ").Select
ActiveSheet.Range("$A$1:$AM$4000").RemoveDuplicates Columns:=36, Header:=xlYes
Range("A2").Select
With
Dim rData As Range: Set rData = ActiveSheet.Range("A1", ActiveSheet.Range("A1").End(xlDown))
Set rData = Range(rData, rData.End(xlToRight))
rData.RemoveDuplicates Columns:=36, Header:=xlYes
ActiveWorkbook.PivotCaches.Create SourceType:=xlDatabase, SourceData:=rData
The update this be where you make your PivotCache
`
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"PIVOT_STATE_REPORT!R1C1:R1048576C39", Version:=xlPivotTableVersion15). _
CreatePivotTable TableDestination:="Sheet1!R3C1", TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion15c
`
With the following code using the rData range as the Source Data
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
rData, Version:=xlPivotTableVersion15). _
CreatePivotTable TableDestination:="Sheet1!R3C1", TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion15
Note this assumes that there are no gaps in the columns or rows of your Data. The End(xlDown) is the equivalent of holding the Ctrl and Down key

transform Vertical information into horizontal

I would like to have this transformation in vba
And to inderstend better i shere with you this picture
Now i have another column and i should have this information in the new table, but i don't find haw to make this?
All I did was setup your sample data and then record a macro and saved recorded macro generated below.
Now note: if your data is larger then you may want to record using key strokes to put cursor at beginning of table and then at the end of the table or "Define data as a table" and use the table.... but this gives you the general idea.
Sub Macro1()
' Macro1 Macro
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"Sheet1!R1C1:R10C4", Version:=xlPivotTableVersion14).CreatePivotTable _
TableDestination:="Sheet1!R13C1", TableName:="PivotTable1", DefaultVersion _
:=xlPivotTableVersion14
Sheets("Sheet1").Select
Cells(13, 1).Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Customer ")
.Orientation = xlRowField
.Position = 1
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Group"), "Sum of Group", xlSum
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Price")
.Orientation = xlColumnField
.Position = 1
End With
Columns("C:C").ColumnWidth = 5.71
ActiveSheet.PivotTables("PivotTable1").PivotFields("Price").Subtotals = Array( _
False, True, False, False, False, False, False, False, False, False, False, False)
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Group")
.Orientation = xlColumnField
.Position = 2
End With
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Price"), "Sum of Price", xlSum
Range("E14").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Price").Caption = _
"Prix"
Range("B18").Select
ActiveSheet.PivotTables("PivotTable1").RowGrand = False
End Sub
Which then results in:
to handle the new column: Id combine the values in the raw data. if however you are after something different I would need to see an example of the desired output.

Creating a pivot table in VBA

I have an xlsm file with some VBA code in it. I basically have a folder with a lot of csv files in it. When I execute the VBA code in the xlsm file, it needs to loop through each csv file, select the data in it and then create a pivot table from the data and export the sheet with the pivot table into a fresh workbook.
It needs to be dynamic in the sense that the amount of data (rows) is not the same in each csv file, so it first needs to select the block of data and then create the pivotcaches etc.
My code fails when trying to create the pivot table. See below for the relevant code. This code kicks off the job to loop through each csv:
Sub RunBatch()
Dim Filename, Pathname As String
Dim wb As Workbook
Pathname = "\\troy\Anfield\Product & Risk Management\Muhammad\2014\PnL Attribution Reports\20140822\"
Filename = Dir(Pathname & "*.csv")
Do While Filename <> ""
Set wb = Workbooks.Open(Pathname & Filename)
CreatePivotTableSummary wb
wb.Close SaveChanges:=True
Filename = Dir()
Loop
End Sub
This code is the one that actually creates the pivot:
Sub CreatePivotTableSummary(wb As Workbook)
Dim WorkbookName As String
WorkbookName = wb.Name
wb.Activate
Set DataRange = Range(Selection, Selection.End(xlToRight))
Set DataRange = Range(Selection, Selection.End(xlDown))
Set OutputRange = Sheet2.Range("A3")
Sheets.Add
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=DataRange, Version:=xlPivotTableVersion14).CreatePivotTable TableDestination:=OutputRange, TableName:=WorkbookName, DefaultVersion:=xlPivotTableVersion14
Sheet2.Select
With wb.ActiveSheet.PivotTables(WorkbookName)
.PivotFields("Portfolio").Orientation = xlRowField
.PivotFields("Portfolio").Position = 1
.PivotFields("TradePortfolio").Orientation = xlRowField
.PivotFields("TradePortfolio").Position = 2
.PivotFields("InstrType").Orientation = xlRowField
.PivotFields("InstrType").Position = 3
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("TPL"), "Sum of TPL", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("ThTPL Deco"), "Sum of ThTPL Deco", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Corr Attr"), "Sum of Corr Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Cr Attr"), "Sum of Cr Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Cross Effec"), "Sum of Cross Effec", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("FX Attr"), "Sum of FX Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Infl Attr"), "Sum of Infl Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("IR Attr"), "Sum of IR Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Price Attr"), "Sum of Price Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Residual"), "Sum of Residual", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Time Attr"), "Sum of Time Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Trd Attr"), "Sum of Trd Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("Vol Attr"), "Sum of Vol Attr", xlSum
.AddDataField ActiveSheet.PivotTables(WorkbookName).PivotFields("YC Attr"), "Sum of YC Attr", xlSum
.PivotFields("Sum of TPL").NumberFormat = "#,##0"
.PivotFields("Sum of ThTPL Deco").NumberFormat = "#,##0"
.PivotFields("Sum of Corr Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Cr Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Cross Effec").NumberFormat = "#,##0"
.PivotFields("Sum of FX Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Infl Attr").NumberFormat = "#,##0"
.PivotFields("Sum of IR Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Price Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Residual").NumberFormat = "#,##0"
.PivotFields("Sum of Time Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Trd Attr").NumberFormat = "#,##0"
.PivotFields("Sum of Vol Attr").NumberFormat = "#,##0"
.PivotFields("Sum of YC Attr").NumberFormat = "#,##0"
.RowAxisLayout xlTabularRow
.TableStyle2 = "PivotStyleMedium2"
.PivotFields("InstrType").PivotFilters.Add Type:=xlValueDoesNotEqual, DataField:=ActiveSheet.PivotTables(WorkbookName).PivotFields("Sum of TPL"), Value1:=0
End With
End Sub
It fails at this point:
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=DataRange, Version:=xlPivotTableVersion14).CreatePivotTable TableDestination:=OutputRange, TableName:=WorkbookName, DefaultVersion:=xlPivotTableVersion14
with the error:
Invalid procedure call or argument
Please can someone assist?
Thank you
Sometimes, we get this error when any data range does not have a column Header.
Check whether first row of your data range has some header for all columns.
Pivot table creation fails, if it could not find a column header.

Excel VBA - Stuck on generating pivot table from variable data range

I have the code below which theoretically should create a pivot table on a 2nd sheet (which exists) using the data it finds on the 'DATA' sheet. However it always crashes as soon as it reaches the part to create the pivot table.
I originally come from a fixed size and afterwards changed it so it should take all the data on my 'DATA' sheet regardless of whether it's a 2x3 or 58x13 table
Sheets("DATA").Select
Range("H1").Select
ActiveCell.FormulaR1C1 = "l"
Range("A1").Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
Sheets("DATA").Range("A1").CurrentRegion, _
Version:=xlPivotTableVersion14).CreatePivotTable _
TableDestination:="Prior. per user!R1C1", TableName:="PivotTable1", _
DefaultVersion:=xlPivotTableVersion14
Sheets("Prior. per user").Select
Cells(1, 1).Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Priority")
.Orientation = xlColumnField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Caller")
.Orientation = xlRowField
.Position = 1
End With
Range("D2").Select
ActiveSheet.PivotTables("PivotTable1").PivotFields("Priority").PivotItems( _
"Medium").Position = 2
Columns("D:D").ColumnWidth = 7.43
Columns("C:C").ColumnWidth = 10
ActiveSheet.PivotTables("PivotTable1").AddDataField ActiveSheet.PivotTables( _
"PivotTable1").PivotFields("Number"), "Sum of Number", xlSum
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Sum of Number")
.Caption = "Count of Number"
.Function = xlCount
End With
If anyone sees what's wrong with it, it would be much appreciated.
Your target sheet name has spaces in it so you need to enclose it in single quotes:
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
Sheets("DATA").Range("A1").CurrentRegion, _
Version:=xlPivotTableVersion14).CreatePivotTable _
TableDestination:="'Prior. per user'!R1C1", TableName:="PivotTable1", _
DefaultVersion:=xlPivotTableVersion14
Personally, I would also use a variable to refer to the pivot table:
Dim PT As PivotTable
Set PT = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
Sheets("DATA").Range("A1").CurrentRegion, _
Version:=xlPivotTableVersion14).CreatePivotTable(TableDestination:="'Prior. per user'!R1C1", TableName:="PivotTable1", _
DefaultVersion:=xlPivotTableVersion14)
With PT
With .PivotFields("Priority")
.Orientation = xlColumnField
.Position = 1
End With
With .PivotFields("Caller")
.Orientation = xlRowField
.Position = 1
End With
.PivotFields("Priority").PivotItems("Medium").Position = 2
.Parent.Columns("D:D").ColumnWidth = 7.43
.Parent.Columns("C:C").ColumnWidth = 10
.AddDataField .PivotFields("Number"), "Count of Number", xlCount
End With