Code not working for Pivot Data Set having Rows>65536 - vba

My purpose is to create a Pivot Table and further a Pivot Chart out of the Dump data (A1:AE170000) I have. I've attached my code below, which works perfectly fine if I reduce my data to around 60-65k rows, but not otherwise.
It throws Runtime error 13 : Type Mismatch at the line I am setting up my Pivot Cache (PTCache).
Private Sub OptionButton3_Click()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
ThisWorkbook.Sheets("Data").Activate
Dim PTCache As PivotCache
Dim PT As PivotTable
'Setting range as my entire data set
Dim PTRange As Range
Set PTRange = Range("A1", Range("A1").End(xlToRight).End(xlDown))
'Adding a new worksheet for Pivot Table and Chart
Dim ws As Worksheet
Set ws = Sheets.Add
ws.Name = "All"
PTRange.Select
ThisWorkbook.Sheets("All").Activate
'Runtime error 13:Type Mismatch at this line while setting PTCache
Set PTCache = ActiveWorkbook.PivotCaches.Create(xlDatabase, PTRange)
Set PT = ActiveSheet.PivotTables.Add(PTCache, Range("A1"), "All")
With PT
.PivotFields("Name").Orientation = xlPageField
.PivotFields("Rate").Orientation = xlDataField
.PivotFields("Date").Orientation = xlRowField
End With
PT.PivotSelect ("")
Charts.Add
ActiveChart.Location where:=xlLocationAsObject, Name:=PT.Parent.Name
ActiveChart.ChartType = xlLine
ActiveChart.Parent.Top = Range("I7").Top
ActiveChart.Parent.Left = Range("I7").Left
Range("A2").Select
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

From PivotCaches.Create Method (Excel) (my emphasis):
<blah><blah> ... When passing as a range, it is recommended to either use a string to specify the workbook, worksheet, and cell range, or set up a named range and pass the name as a string. Passing a Range object may cause "type mismatch" errors unexpectedly.
Just set up a string var to the external address of the Data worksheet's Range.CurrentRegion property radiating out from A1 and use that.
Option Explicit
Private Sub OptionButton3_Click()
'Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim PT As PivotTable, PTCache As PivotCache
Dim PTRange As Range, ws As Worksheet, strRNG As String
strRNG = ThisWorkbook.Worksheets("Data").Cells(1, 1).CurrentRegion.Address(external:=True)
With Worksheets.Add(after:=Sheets(Sheets.Count))
.Name = "All"
Set PTCache = .Parent.PivotCaches.Create(xlDatabase, strRNG)
Set PT = .PivotTables.Add(PTCache, .Range("A1"), "All")
With PT
.PivotFields("Name").Orientation = xlPageField
.PivotFields("Rate").Orientation = xlDataField
.PivotFields("Date").Orientation = xlRowField
End With
PT.PivotSelect ("")
End With
'all the chart stuff here
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Related

Circle through a power pivot table's slicer or filter and copy (each pivot table produced) in a new worksheet with the same name as the slicer item

I have a multidimensional power pivot table in sheet "Template2" created by a data model. I want VBA which circles through the slicer "Slicer_Sublot_code" and for each selection a new sheet to be created named after the slicer's selected item and the filtered pivot table to be pasted in it maintaining only values and format.
So far I have managed to create the empty sheets named by the slicer's items (the VBA reads the names from a range F2:F10 instead of taking them from the slicer which would be ideal):
Sub AddSheets()
Dim xRg As Excel.Range
Dim wSh As Excel.Worksheet
Dim wBk As Excel.Workbook
Set wSh = ActiveSheet
Set wBk = ActiveWorkbook
Application.ScreenUpdating = False
For Each xRg In wSh.Range("F2:F10")
With wBk
.Sheets.Add after:=.Sheets(.Sheets.Count)
On Error Resume Next
ActiveSheet.Name = xRg.Value
If Err.Number = 1004 Then
Debug.Print xRg.Value & " already used as a sheet name"
End If
On Error GoTo 0
End With
Next xRg
Application.ScreenUpdating = True
End Sub
I have also managed to do the copy/paste of the pivot table (keeping values and format) on a new sheet but the name is pre-defined "Report":
Sub PivotTablePasteSpecial()
Dim SourcePivottable As PivotTable
Dim DestinationRange As Range
Dim aCell As Range
Application.Calculation = xlCalculationManual
Application.DisplayStatusBar = False
Application.EnableEvents = False
Application.ScreenUpdating = False
Set SourcePivottable = Worksheets("Template2").PivotTables(1)
Set DestinationRange = Worksheets("Report").Range("A1")
' Copy TableRange1
SourcePivottable.TableRange1.Copy
With DestinationRange.Offset( _
SourcePivottable.TableRange1.Row - SourcePivottable.TableRange2.Row, 0)
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
.PasteSpecial Paste:=xlPasteColumnWidths
End With
' Copy everything above TableRange1 cell-by-cell
For Each aCell In SourcePivottable.TableRange2.Cells
If Not Intersect(aCell, SourcePivottable.TableRange1) Is Nothing Then Exit For
aCell.Copy
With DestinationRange.Offset( _
aCell.Row - SourcePivottable.TableRange2.Row, _
aCell.Column - SourcePivottable.TableRange2.Column)
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
End With
Next aCell
Application.Calculation = xlCalculationAutomatic
Application.DisplayStatusBar = True
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
How can I combine the 2 in order to achieve the desired outcome described in the first paragraph?

Unable to take screenshot (JPEG) of a defined range

I am trying to take a screenshot of a range with a button and put the JPEG in the same folder. The defined range is 'header'
It runs fine for some time then all of sudden I get one of the following errors.
Vba code:
Sub CommandB_Click()
dt = Format(CStr(Now), "yy_mm_dd_hh_mm")
Const FName As String = "Screenshotzx.jpg"
Dim pic_rng As Range
Dim ShTemp As Worksheet
Dim ChTemp As Chart
Dim PicTemp As Picture
Application.ScreenUpdating = False
Set pic_rng = ActiveSheet.Range("header")
Set ShTemp = Worksheets.Add
Charts.Add
ActiveChart.Location Where:=xlLocationAsObject, Name:=ShTemp.Name
Set ChTemp = ActiveChart
pic_rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
ChTemp.Paste
Set PicTemp = Selection
With ChTemp.Parent
.Width = 1400
.Height = 720
End With
ChTemp.Export Filename:=ThisWorkbook.Path & "\" & "Scrnsht.jpg", FilterName:="jpg"
Application.DisplayAlerts = False
ShTemp.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Error Code 13 Type Mismatch on the following line
Set PicTemp = Selection
Error Code 1004 on the following line
pic_rng.CopyPicture Appearance:=xlScreen, Format:=xlPicture
What about something like this (gets rid of unused variables dt and Fname and avoids ActiveSheet, ActiveChart and Selection)? Note that this uses AddChart2, which is only available in Excel 2013 and later.
Sub SaveRangeAsJPEG()
Dim pic_rng As Range
Dim ChTemp As Chart
Dim ShTemp As Worksheet
Application.ScreenUpdating = False
Set pic_rng = Sheets("YourSheetName").Range("header") 'change to your sheet name
Set ShTemp = Worksheets.Add
Set ChTemp = ShTemp.Shapes.AddChart2.Chart
pic_rng.CopyPicture xlScreen, xlPicture
ChTemp.Paste
With ChTemp.ChartArea
.Width = 1400
.Height = 720
End With
ChTemp.Export Filename:=ThisWorkbook.Path & "\" & "Scrnsht.jpg", FilterName:="jpg"
Application.DisplayAlerts = False
ShTemp.Delete
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub

VBA Code to Control Multiple Pivot Table Slicers

I'm trying to set-up some VBA code that will allow me to control multiple pivot tables (and data sources) with 1 slicer.
In the past, I have only needed to implement VBA code that controls 1 additional slicer, but now I am trying to set-it up to control 2 slicers and am running into issues.
Here is my code that I used in the past for controlling 1 slicer:
As a module:
Public PrevCat As String
In ThisWorkbook:
Private Sub Workbook_Open()
PrevCat = Sheet27.Range("O5").Value
End Sub
Primary code:
Option Explicit
Private Sub Worksheet_Calculate()
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim Field As PivotField
Dim NewCat As String
NewCat = Sheet27.Range("O5").Value
If NewCat <> PrevCat Then
Application.EnableEvents = False
Set pt = Sheet27.PivotTables("Pivot Match 2")
Set Field = pt.PivotFields("Region")
With Field
.ClearAllFilters
On Error Resume Next
.CurrentPage = NewCat
On Error GoTo 0
End With
pt.RefreshTable
PrevCat = NewCat
Application.EnableEvents = True
End If
Application.ScreenUpdating = True
End Sub
Like I said, this code works perfectly for controlling 1 additional slicer. However, I need the code to control 2 slicers. All i did was add an additional If statement, but it doesn't seem to work:
Option Explicit
Private Sub Worksheet_Calculate()
Application.ScreenUpdating = False
Dim pt As PivotTable
Dim Field As PivotField
Dim NewCat As String
NewCat = Sheet27.Range("O5").Value
If NewCat <> PrevCat Then
Application.EnableEvents = False
Set pt = Sheet27.PivotTables("Pivot Match 2")
Set Field = pt.PivotFields("Region")
With Field
.ClearAllFilters
On Error Resume Next
.CurrentPage = NewCat
On Error GoTo 0
End With
pt.RefreshTable
PrevCat = NewCat
Application.EnableEvents = True
End If
If NewCat <> PrevCat Then
Application.EnableEvents = False
Set pt = Sheet27.PivotTables("Pivot Match 3")
Set Field = pt.PivotFields("Region")
With Field
.ClearAllFilters
On Error Resume Next
.CurrentPage = NewCat
On Error GoTo 0
End With
pt.RefreshTable
PrevCat = NewCat
Application.EnableEvents = True
End If
Application.ScreenUpdating = True
End Sub
Any ideas on how i can get this to work?

I am unable to add Data Field to my Pivot Table VBA

I get a runtime error
Unable to get the PivotTables property of Worksheet class
when I run the following code:
Sub UpdatePivot()
Dim ws As Worksheet, SrcData As String, pvtCache As PivotCache
Dim ws2 As Worksheet, NR As Long, NC As Long, ws3 As Worksheet
Dim pf As PivotField, pt As PivotTable, df As PivotField, str As String
'Set ws = ThisWorkbook.Worksheets("Lisun Data")
Set ws2 = ThisWorkbook.Worksheets("Cover")
Set ws3 = ThisWorkbook.Worksheets("Stockist")
Set pt = ws3.PivotTables("PivotTable3")
Set pt = ws3.PivotTables("PivotTable3")
With pt.PivotFields(" May-17")
.Orientation = xlColumnField
.Function = xlSum
.Position = 1
End With
End Sub
May I know what is wrong?
I did add the data source to a data model beforehand, and I'm not sure what exactly is causing the error.
Try the code below to try and trap your errors, explanations inside the code's comments:
Option Explicit
Sub UpdatePivot()
Dim ws As Worksheet, SrcData As String, pvtCache As PivotCache
Dim ws2 As Worksheet, NR As Long, NC As Long, ws3 As Worksheet
Dim pf As PivotField, pt As PivotTable, df As PivotField, str As String
'Set ws = ThisWorkbook.Worksheets("Lisun Data")
Set ws2 = ThisWorkbook.Worksheets("Cover")
Set ws3 = ThisWorkbook.Worksheets("Stockist")
' 1ST: Trap the Pivot-Table object
On Error Resume Next
Set pt = ws3.PivotTables("PivotTable3")
On Error GoTo 0
If pt Is Nothing Then '<-- Pivot Table does't exist (Pivot Table renamed ?)
MsgBox "Pivot-Table object Error!"
Else ' Pivot-Table object exists
' 2NDT: Trap the PivotField object
On Error Resume Next
Set pf = pt.PivotFields(" May-17")
On Error GoTo 0
If pf Is Nothing Then
MsgBox "Pivot-Field object Error!"
Else
With pf
.Orientation = xlColumnField
.Function = xlSum
.Position = 1
End With
End If
End If
End Sub
Thank you to #Shai Rado for all your feedback, extremely valuable. Also big big thanks to #jeffreyweir, I recorded a macro and found out the answer that I needed. The code for adding any pivot field from a data model is below:
ActiveSheet.PivotTables("PivotTable3").AddDataField ActiveSheet.PivotTables( _
"PivotTable3").CubeFields("[Measures].[Sum of May-17]"), "Sum of May-17"

Use VBA to change filters on all pivot tables

I have an Excel workbook with several hundred pivot tables. All of the pivot tables are using data from an SSAS cube. The tables are all basically structured the same way, but they have different "location" filters. What I want to do is have code that will change a "date" filter for all of the tables so that I do not need to manually update each of the tables. (No, slicers will not work for me). I'm very much new to using VBA, so I'm a bit at a loss. I found this code, which I thought might work, but all it does for me is clear the filters on the other tables...possibly because I'm pulling from an external source? Any help would be greatly appreciated.
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
On Error Resume Next
Dim wsMain As Worksheet
Dim ws As Worksheet
Dim ptMain As PivotTable
Dim pt As PivotTable
Dim pfMain As PivotField
Dim pf As PivotField
Dim pi As PivotItem
Dim bMI As Boolean
On Error Resume Next
Set wsMain = ActiveSheet
Set ptMain = Target
Application.EnableEvents = False
Application.ScreenUpdating = False
For Each pfMain In ptMain.PageFields
bMI = pfMain.EnableMultiplePageItems
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
If ws.Name & "_" & pt <> wsMain.Name & "_" & ptMain Then
pt.ManualUpdate = True
Set pf = pt.PivotFields(pfMain.Name)
bMI = pfMain.EnableMultiplePageItems
With pf
.ClearAllFilters
Select Case bMI
Case False
.CurrentPage = pfMain.CurrentPage.Value
Case True
.CurrentPage = "(All)"
For Each pi In pfMain.PivotItems
.PivotItems(pi.Name).Visible = pi.Visible
Next pi
.EnableMultiplePageItems = bMI
End Select
End With
bMI = False
Set pf = Nothing
pt.ManualUpdate = False
End If
Next pt
Next ws
Next pfMain
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Kindly try the following code.
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
On Error Resume Next
Dim wsMain As Worksheet
Dim ws As Worksheet
Dim ptMain As PivotTable
Dim pt As PivotTable
Dim pfMain As PivotField`enter code here`
Dim pf As PivotField
Dim pi As PivotItem
Dim pvfilter as string
On Error Resume Next
Set wsMain = ActiveSheet
Set ptMain = Target
Application.EnableEvents = False
Application.ScreenUpdating = False
pvfilter = InputBox("Enter the pivot filter string")
For Each pfMain In ptMain.PageFields
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
If ws.Name & "_" & pt <> wsMain.Name & "_" & ptMain Then
pt.ManualUpdate = True
Set pf = pt.PivotFields(pfMain.Name)
With pf
.ClearAllFilters
.CurrentPage = pvfilter
End With
Set pf = Nothing
pt.ManualUpdate = False
End If
Next pt
Next ws
Next pfMain
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
I would suggest you update this code as subroutine and run this macro whenever you need to apply a filter to pivot tables instead of directly using the code in pivot update event.
Sub Test()
On Error Resume Next
Dim wsMain As Worksheet
Dim ws As Worksheet
Dim ptMain As PivotTable
Dim pt As PivotTable
Dim pfMain As PivotField
Dim pf As PivotField
Dim pi As PivotItem
Dim pvfilter As String
On Error Resume Next
Set wsMain = ActiveSheet
Set ptMain = Target
Application.EnableEvents = False
Application.ScreenUpdating = False
pvfilter = InputBox("Enter the pivot filter string")
For Each pfMain In ptMain.PageFields
For Each ws In ThisWorkbook.Worksheets
For Each pt In ws.PivotTables
If ws.Name & "_" & pt <> wsMain.Name & "_" & ptMain Then
pt.ManualUpdate = True
Set pf = pt.PivotFields(pfMain.Name)
With pf
.ClearAllFilters
.CurrentPage = pvfilter
End With
Set pf = Nothing
pt.ManualUpdate = False
End If
Next pt
Next ws
Next pfMain
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub