VBA code to make a pivot table is not working - excel

I am having an issue with my pivot tables. For some reason, this code was working this morning but now it is not. Here is my code up until the error.
Dim WSD2 As Worksheet
Set WSD2 = ActiveWorkbook.Sheets.Add(After:= _
Worksheets(Worksheets.Count))
WSD2.Name = "POS Info"
'--------------------------------------------------
' Step 2: Create the pivot table
'--------------------------------------------------
Dim WSD As Worksheet
Dim PTCache As PivotCache
Dim PT As PivotTable
Dim PRange As Range
Dim FinalRow As Long
Dim FinalCol As Long
Dim StartPT As String
Dim BottomRowStart As Range ' this is for pivot table
Dim BottomRowEnd As Range ' this is for pivot table
Set WSD = Worksheets("aggregateData")
' Select the data for pivot table
FinalRow = WSD.Cells(Rows.Count, 2).End(xlUp).Row
FinalCol = WSD.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = WSD.Cells(2, 1).Resize(FinalRow, FinalCol)
Set PTCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange, Version:=xlPivotTableVersion14)
'Where do I want the pivot table to start
StartPT = WSD2.Range("A1").Address(ReferenceStyle:=xlR1C1)
Set WSD2 = Worksheets("POS Info")
'Begin to Create the Pivot Table
Set PT = PTCache.CreatePivotTable(TableDestination:=StartPT, TableName:="POS Data")
The last line is where I get the following error message:
"Application-defined or object-defined error".
Any help would be much appreciated.
Thanks,
G

Like #GSerg said in the comment, TableDestination needs to be a range instead of an address.
Right now you assign an address to the TableDestination, which really is just a string (text) saying "$A$3" or similar. You need to change this to TableDestination:=WSD2.range(StartPT) and then you code should work.
Note that it is possible that this worked previously but not any more because you may have added more worksheets to the document. Then when VBA tries to understand the address "$A$3" it cannot decide which worksheet to use and hence throws an error. It's therefore always smart to be quite clear when referring to ranges, and to do it via their workbook.worksheets path. See here for more.

Related

Change automatically the range of the datasource of a pivot table of each worksheet

I want to change automatically the range of the sourcedata of each pivot table of each worksheet. I have the sheet 'DATA' which feeds every pivot table of the workbook. The point is that the range of the DATA sheet is variable. So when I change the DATA sheet I want to refresh all the pivot table adjusting also the rnew range of data.
I wrote the following script, but it is not working. I don't know why:
Sub Prueba_Rango_TD()
Dim ws As Worksheet
Dim LastRow As Integer
LastRow = Cells(Rows.Count, 3).End(xlUp).Row
For Each ws In ThisWorkbook.Worksheets
For Each tbl In ws.ListObjects
tbl.Resize tbl.Range.Resize("DATA!B8:O" & Ultima_fila)
Next tbl
Next ws
End Sub
Can you help me please?
Thank you!
The easy way you do this is by recording a Macro.
Then you will se what type of Objects being used and where the pointer of your first Pivot, something like this:
ActiveSheet.PivotTables("PivotTable1").ChangePivotCache
ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=ThisWorkbook.Worksheets("DATA").UsedRange.Address,
Version:=xlPivotTableVersion12)
If all the other sheets points towards the same data Cashe you do it with the loop.
.PivotTables("PivotTable1").ChangePivotCache ("DATA!PivotTable1")
.PivotTables("PivotTable1").RefreshTable

Excel Pivot table dynamic range update via VBA returns too many rows

I'm new here and a novice at VBA, so apologies in advance...
I'm trying to create a macro-button so that, when pressed, the Data Source for my Pivot Table (named 'Item Summary') is updated to a range of data that changes in size depending on the project, but will always be on a Worksheet called 'Usage' & the Pivot Table is on a worksheet named 'Item Summary' with data starting in cell A2.
The below works; however, it seems to be returning extra rows at the bottom resulting in a row of '(blank)' data on my Pivot Table -_- Any help would be much appreciated!
Dim Data_sht As Worksheet
Dim Pivot_sht As Worksheet
Dim StartPoint As Range
Dim DataRange As Range
Dim PivotName As String
Dim NewRange As String
'Set Variables Equal to Data Sheet and Pivot Sheet
Set Data_sht = Worksheets("Usage")
Set Pivot_sht = Worksheets("Item Summary")
'Enter in Pivot Table Name
PivotName = "Item Summary"
'Dynamically Retrieve Range Address of Data
Set StartPoint = Data_sht.Range("A2")
Set DataRange = Data_sht.Range(StartPoint, StartPoint.SpecialCells(xlLastCell))
NewRange = Data_sht.Name & "!" & _
DataRange.Address(ReferenceStyle:=xlR1C1)
I tried using the below edit in the 3rd to last line using a question/thread called, "Excel Pivot table range update via VBA gets too many rows"; however, I get a "Method 'Range' of object_Worksheet' failed." error :( Hopefully I'm just missing a tiny misspelled item, but I've been spinning my wheels here for a couple of hours now, so figured I'd see if anyone is able to assist.
Dim Data_sht As Worksheet
Dim Pivot_sht As Worksheet
Dim StartPoint As Range
Dim DataRange As Range
Dim PivotName As String
Dim NewRange As String
Dim LastCol As Long
Dim DownCell As Long
'Set Variables Equal to Data Sheet and Pivot Sheet
Set Data_sht = Worksheets("Usage")
Set Pivot_sht = Worksheets("Item Summary")
'Enter in Pivot Table Name
PivotName = "Item Summary"
'Dynamically Retrieve Range Address of Data
Set StartPoint = Data_sht.Range("A2")
LastCol = StartPoint.End(xlToRight).Column
DownCell = StartPoint.End(xlDown).Row
**Set DataRange = Data_sht.Range(StartPoint, Cells(DownCell, LastCol))**
NewRange = Data_sht.Name & "!" & _
DataRange.Address(ReferenceStyle:=xlR1C1)

How to update multiple Pivot Tables with multiple DataSources?

Hello beautiful people!
I am using Excel 2010 and I am trying to come up with a handy macro which would update all pivot tables in a workbook. I want it to be universal that means to be applicable to ANY workbook which contains pivot tables. By update I do not mean mere Pivot table Refresh as the data in our reports are getting rewritten and all that remains from the original source range is header. This means I need to Change the Data Source to new range dynamically.
Example: I have a Dashboard with 8 pivot tables on Summary sheet. Every Pivot table has its own DataSource on different sheet (pivot1 has data on Sheet1, pivot2 has data on Sheet2, etc.)
I started with a basic Macro which changes/updates the DataSource for a single Pivot table and which I use in various iterations in other macros - taken from here:
ActiveWorkbook.PivotTables(PivotTable1).ChangePivotCache ActiveWorkbook. _
PivotCaches.Create(SourceType:=xlDatabase, SourceData:=SrcData, _
Version:=xlPivotTableVersion15)
Now, my thought-process was like this:
Since the header is what is in the SourceData, I need to find a way to get that range and just expand it to last row with the usual
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
I tried to achieve this with .SourceData property but it appeared to be useless since property .SourceData is Variant type. So I did some digging around the excel forums some more and found a code to convert this into desired type:
Application.Evaluate(Application.ConvertFormula(pt.SourceData, xlR1C1, xlA1))
I believe I implemented this correctly with some string trimming to get desired references but even though it looks great in theory (atleast in my eyes) I am getting runtime error (please see below) and now I am at loss. Therefore, I am turning to you guys to see if you could share some knowledge or offer an advice.
This is the current code I need help with (with explanations):
Sub pivot_updator()
Dim lastRow As Long
Dim pt As PivotTable
Dim ws As Worksheet
Dim dataArea As Range
Dim sSheetTrim As String
Dim sRangeTrim As String
For Each ws In ActiveWorkbook.Sheets
For Each pt In ws.PivotTables
'evaluate String to get Range after conversion from Variant - recovered from another forum
Set dataArea = Application.Evaluate(Application.ConvertFormula(pt.SourceData, xlR1C1, xlA1))
'some trimming to get desired references for lastRow (sheet in which the SourceData are located) and dataArea (starting cell and last column of SourceData)
sSheetTrim = Left(pt.SourceData, 6)
sRangeTrim = Left(dataArea.Address, 8)
lastRow = Sheets(sSheetTrim).Cells(Rows.Count, 1).End(xlUp).Row
'gluing the starting cell and lastcolumn (sRangeTrim) together with ending cell in last row (lastrow)
Set dataArea = Range(sRangeTrim & lastRow)
'test that I am getting correct Range for the pivot SourceData update
MsgBox dataArea.Address
'following gives me the Runtime error -2147024809(80070057)
pt.ChangePivotCache ActiveWorkbook. _
PivotCaches.Create _
(SourceType:=xlDatabase, _
SourceData:=dataArea, _
Version:=xlPivotTableVersion12)
'just to be sure the pivot table refreshes after the SourceData is updated
pt.RefreshTable
Next pt
Next ws
MsgBox "Pivot Update Done"
End Sub
Running this Sub prompts me with Runtime error -2147024809(80070057):
"The PivotTable field name is not valid. To create a pivot table report you must use data that is organized as a list with labeled columns, If you are changing the name of a PivotTable field, you must type a new name for the field."
What it should do is cycle through all Pivot Tables and expand their respective DataSource ranges to last row.
Since this is supposed to be all-time universal macro, you should be able to test it yourself on any workbook which contains pivot table.
I will be grateful for any suggestion and advice, also feel free to criticize my coding in general, I am fairly new to VBA. Thank you for spending your time looking into my issue and investing your beautifulness into it.
Beautiful people,
Fortunately, after taking a break and coming back to this issue with clear head, I was able to determine the problem. Even though the dynamic range cell references were set correctly, the scope of the range was not. There was no Sheet information in dataArea which is why the runtime error for invalid pivot table was present. It was probably a result of Application.Evaluate which omitted the sheet reference.
I had to further add a code which trimmed the string address to contain Sheet name on which pivot source data were located.
Please see amended code below:
Sub pivot_updator()
Dim lastRow As Long
Dim pt As PivotTable
Dim ws As Worksheet
Dim dataArea As Range
Dim sSheetTrim As String
Dim sRangeTrim As String
Dim SourceDataSheet As String
Application.ScreenUpdating = False
Application.Calculation = xlManual
For Each ws In ActiveWorkbook.Sheets
For Each pt In ws.PivotTables
'evaluate String to get Range after conversion from Variant - recovered from another forum
SourceDataSheet = Application.ConvertFormula(pt.SourceData, xlR1C1, xlA1)
Set dataArea = Application.Evaluate(Application.ConvertFormula(pt.SourceData, xlR1C1, xlA1))
'implemented fix - trim to get desired Sheet name on which pivot source data are located
sSheetTrim = Split(SourceDataSheet, "!")(0)
sSheetTrim = Split(SourceDataSheet, "'")(1)
sSheetTrim = Split(sSheetTrim, "]")(1)
'some trimming to get desired references for lastRow (sheet in which the SourceData are located) and dataArea (starting cell and last column of SourceData)
sRangeTrim = Left(dataArea.Address, 8)
lastRow = Sheets(sSheetTrim).Cells(Rows.Count, 2).End(xlUp).Row
'gluing the starting cell and lastcolumn (sRangeTrim) together with ending cell in last row (lastrow)
Set dataArea = Sheets(sSheetTrim).Range(sRangeTrim & lastRow)
'test that I am getting correct Range for the pivot SourceData update
'following gives me the Runtime error -2147024809(80070057) // MAYBE the DATA AREA DOES NOT DEFINE SHEET
pt.ChangePivotCache ActiveWorkbook. _
PivotCaches.Create _
(SourceType:=xlDatabase, _
SourceData:=dataArea, _
Version:=xlPivotTableVersion12)
'just to be sure the pivot table refreshes after the SourceData is updated
pt.RefreshTable
Next pt
Next ws
Application.ScreenUpdating = True
Application.Calculation = xlAutomatic
MsgBox "Pivot Update Done"
End Sub
The code is now working fine, I will see if there happen to be any mishaps I had not think of and possibly update the code.
I would like to thank anyone who commented on this question and proposed any solution and also to anyone who viewed it and read through it.
Thank you.

How to Create a table that changes size based on a determined value

VBA CODE:
I have a series of tables (one per sheet) that need to increase or decrease in size dynamically, based on number that has been input by a user (on another sheet).
Each row in each of the tables needs to maintain the formatting and formulas from the rows above, whilst being "inserted".
I have used the below to successfully increase the size of the table with the correct formatting, but this only adds rows to the table.. and if someone clicks the macro button multiple times we could end up with far too many rows. Hence why I would like a dynamic table where the rows are determined by a number and it wouldn't matter if someone was click happy.
I have also made another attempt which does increase the size of the table, but it doesn't insert additional rows, so the table overlaps data that is in rows below the determined table. This attempt does not copy the formatting either... but this is all i have so far. Any help would be much appreciated, I've been working on this for a couple of months and can't find a suitable answer (after days of searching).
Sub InsertNumberOfRows()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim NBOFROWS As Range
Dim wkb As Workbook
Set NBOFROWS = Worksheets("Rates").Range("K4")
Set wkb = Workbooks("POD Automation10.1")
With wkb
Set sh1 = ActiveWorkbook.Sheets("POD Cost Plan")
Set sh2 = ActiveWorkbook.Sheets("Development Calculator")
Set sh3 = ActiveWorkbook.Sheets("Calculator Calculations")
sh1.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
sh2.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
sh3.Select
Rows("10:10").Select
Selection.EntireRow.Offset(1).Resize(NBOFROWS.Value).Insert Shift:=xlDown,
CopyOrigin:=xlFormatFromLeftOrAbove
End With
End Sub
NEXT ATTEMPT:
Sub InsertNumberOfRows()
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim sh3 As Worksheet
Dim Value As Range
Dim wkb As Workbook
Dim rng As Range
Dim tbl As ListObject
Set Value = Worksheets("Rates").Range("K4")
Set wkb = Workbooks("POD Automation10.2")
With wkb
Set sh1 = ActiveWorkbook.Sheets("POD Cost Plan")
Set sh2 = ActiveWorkbook.Sheets("Development Calculator")
Set sh3 = ActiveWorkbook.Sheets("Calculator Calculations")
sh1.Select
Set tbl = ActiveSheet.ListObjects("POD_CostPlan_Tbl")
Set rng = Range("POD_CostPlan_Tbl[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
sh2.Select
Set tbl = ActiveSheet.ListObjects("TBL_UserEntry")
Set rng = Range("TBL_UserEntry[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
sh3.Select
Set tbl = ActiveSheet.ListObjects("TBL_Calculations")
Set rng = Range("TBL_Calculations[#All]").Resize(tbl.Range.Rows.Count + Value, tbl.Range.Columns.Count)
tbl.Resize rng
End With
End Sub
A better approach would be to use ListObject properties to add rows and columns. For example:
With ActiveSheet.ListObjects("Table1")
' Insert column at the end of table:
.ListColumns.Add
' Add row tp the bottom of table:
.ListRows.Add AlwaysInsert:= True
End With
If I were you, I would change all those to Tables, so everything (rows and columns) gets updated automatically.
https://www.thespreadsheetguru.com/blog/2014/6/20/the-vba-guide-to-listobject-excel-tables
Ctrl+T: This shortcut converts a range of related information to an Excel Table. To use this shortcut, just select any cell in a range of related data first.

Trying to create a pivot table in a newly created worksheet

So I am trying to create a pivot table. The code that I have now works fine. However, what I am trying to do now is create a new worksheet in my workbook and have the pivot table be made in the new worksheet. This code works fine when the worksheet is already there, however, once I add in the new line of code to create the new worksheet, it fails me.
Sub ISM_Pivot()
'-------------------------------------------------
' Step 1: Create a new worksheet for pivot table
'--------------------------------------------------
Dim WSD2 As Worksheet
Set WSD2 = ActiveWorkbook.Sheets.Add(After:= _
Worksheets(Worksheets.Count))
WSD2.Name = "POS Info"
'--------------------------------------------------
' Step 2: Create the pivot table
'--------------------------------------------------
Dim WSD As Worksheet
Dim PTCache As PivotCache
Dim PT As PivotTable
Dim PRange As Range
Dim FinalRow As Long
Dim FinalCol As Long
Dim StartPT As String
Set WSD = Worksheets("aggregateData")
' Select the data for pivot table
FinalRow = WSD.Cells(Rows.Count, 2).End(xlUp).Row
FinalCol = WSD.Cells(1, Columns.Count).End(xlToLeft).Column
Set PRange = WSD.Cells(2, 1).Resize(FinalRow, FinalCol)
Set PTCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange, Version:=xlPivotTableVersion14)
'Where do I want the pivot table to start
StartPT = WSD2.Range("A1").Address(ReferenceStyle:=xlR1C1)
'Begin to Create the Pivot Table
Set PT = PTCache.CreatePivotTable(TableDestination:=StartPT, TableName:="POS Data")
The last line of code is where it fails me. I get an application defined or object-defined error.
Any help would be great,
Thanks,
Griffin

Resources