How to use AverageIf function in excel macro - vba

The below code does not work. I am trying to create a pivot with average of Hrs and I don't want the value 0 to be considered in the average.
With ActiveSheet.PivotTables("AnalyticsPivotTable").PivotFields("Hrs")
.Orientation = xlDataField
.Position = 2
.Function = "=AverageIf(M:M,"">0"")"
.NumberFormat = "#,##0"

Related

Error 440: Method 'Create' of object 'PivotCaches' failed

I have been trying to create a macro that populates a pivot table. However, I keep getting this
Run-Time Error 440
on the Set Cache line.
Previously, I was running into other run time errors but those were easy fixes. I do not understand why the PivotCaches.Create method is not allowed in this case. SOS, please help!
Here is the code:
' Declare variables for pivots
Dim pivotWB As Workbook
Dim RawDataWS As Worksheet
Dim dataLocation As Range
Dim cache As PivotCache
Dim table As PivotTables
' name and set the workbook for pivot tables
folderName = ThisWorkbook.Sheets(1).Cells(5, 13).Value
fileName = ThisWorkbook.Sheets(1).Cells(6, 13).Value
extName = ThisWorkbook.Sheets(1).Cells(7, 13).Value
wbAddress = folderName & "\" & fileName & "." & extName
Set pivotWB = Workbooks.Open(wbAddress)
Set dataLocation = pivotWB.Sheets("Raw Data").Range("A:AK")
Set cache = pivotWB.PivotCaches.Create(SourceType:=xlDatabase,_
sourceData:=dataLocation, Version:=xlPivotTableVersion14)
For i = 1 To 5
' create new worksheet and pivot table
pivotWB.Sheets.Add Before:=Sheets(1)
pivotWB.Sheets(1).Name = Left(toPivot(i), 30)
cache.CreatePivotTable TableDestination:=pivotWB.Sheets(1).Cells(1, 1), TableName:=toPivot(i) & " Pivot Table"
' set rows
With pivotWB.Sheets(1).PivotTables(toPivot(i) & " Pivot Table").PivotFields("Rejection Category Description")
.Orientation = xlRowField
.Position = 1
End With
' set columns
With pivotWB.Sheets(1).PivotTables(toPivot(i) & " Pivot Table").PivotFields("Post Period")
.Orientation = xlColumnField
.Position = 1
End With
' set values
With pivotWB.Sheets(1).PivotTables(toPivot(i) & " Pivot Table").PivotFields("Procedure Code")
.Orientation = xlDataField
.Position = 1
.Function = xlCount
.NumberFormat = "#,##0"
.Name = "Count of Code"
End With
With pivotWB.Sheets(1).PivotTables(toPivot(i) & " Pivot Table").PivotFields("Amount")
.Orientation = xlDataField
.Position = 2
.Function = xlSum
.NumberFormat = "$#,##0"
.Name = "Sum of Amount"
End With
Next i
Following #Rory comment, you need to set the PivotCache object using the Address property.
Also, setting your table object to your PivotTable will create a much easier and shorter code.
See code below, more notes inside the code's comments.
Modified Code
' --- set the Pivot Cache ---
Set cache = pivotWB.PivotCaches.Create(SourceType:=xlDatabase, _
SourceData:=dataLocation.Address(False, False, xlR1C1, xlExternal))
For i = 1 To 5
' create new worksheet and pivot table
pivotWB.Sheets.Add Before:=Sheets(1)
pivotWB.Sheets(1).Name = Left(toPivot(i), 30)
' --- set the Pivot-Table Object ---
Set table = cache.CreatePivotTable(TableDestination:=pivotWB.Sheets(1).Cells(1, 1), TableName:=toPivot(i) & " Pivot Table")
With table ' <-- after you set the table object, you can simply use With statement now
' set rows
With .PivotFields("Rejection Category Description")
.Orientation = xlRowField
.Position = 1
End With
' set columns
With .PivotFields("Post Period")
.Orientation = xlColumnField
.Position = 1
End With
' set values
With .PivotFields("Procedure Code")
.Orientation = xlDataField
.Position = 1
.Function = xlCount
.NumberFormat = "#,##0"
.Name = "Count of Code"
End With
With .PivotFields("Amount")
.Orientation = xlDataField
.Position = 2
.Function = xlSum
.NumberFormat = "$#,##0"
.Name = "Sum of Amount"
End With
End With
Next i

vba excel - Pivot Tablle Calculated Field

I have developed a Pivot Table and need to add a calculated field. Rather than using the 'named' (row) fields, I would like to use the 'reference' field in my calculation. The formula works fine using the 'named' field. but not when using a 'reference'. Below is part of the code and where is goes wrong. Appreciate your guidance and help.
'/-------------
'/ Insert Data Field
'/-------------
With pTable
With .PivotFields(wksDSheet.Cells(1, 5).Value)
.Orientation = xlDataField
.Position = 1
.Function = xlSum
'NumberFormat = "#,##0.00"
.Caption = "Actual Spent"
End With
s1 = pTable.PivotFields(wksDSheet.Cells(1, 5).Value)
With .PivotFields(wksDSheet.Cells(1, 6).Value)
.Orientation = xlDataField
.Position = 2
.Function = xlSum
'.NumberFormat = "#,##0.00"
.Caption = "YmBudget To date"
End With
With .PivotFields(wksDSheet.Cells(1, 7).Value)
.Orientation = xlDataField
.Position = 3
.Function = xlSum
'.NumberFormat = "#,##0.00"
.Caption = "YrBudget To Year"
s2 = pTable.PivotFields(wksDSheet.Cells(1, 7).Value)
End With
End With
'/-------------------
'/ Insert Calculated Fields
'/-------------------
'/ The Name and Formula
''' This works''''>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
' pTable.CalculatedFields.Add Name:="Available", _
Formula:="=YrBudget - Actual"
''' This does NOT work ''''>>>>>>>>>>>>>>>>>>>>>>>>
pTable.CalculatedFields.Add Name:="Available", _
Formula:="=s2 - s1"
With pTable.PivotFields("Available")
.Orientation = xlDataField
.Function = xlSum
.Position = 4
'.NumberFormat = "0.00"
.Caption = "Net Available"
End With

Two Pivot Tables in the same excel sheet

I have created a Pivot Table in the same sheet with the source data. Now, I want to create a second Pivot Table in the same sheet with same data source, but with different printed data inside the Pivot Table (of course). I keep getting an error, as it says that Pivot Table cannot overwrite another Pivot Table. However, they way I have selected the ranges where the pivot tables are created, they dont overwrite each other. I tested manually too. Also, if I record the process it just uses exact references for the source data, which I dont want to use because the lastrow and lastcolumn change daily. Just to remind it, the macro works great for creating the first table. The second table is the issue. Below, I will provide my code as it is now.
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable1 As PivotTable
Dim PTable2 As PivotTable
Dim PRange As Range
Application.DisplayAlerts = True
Set DSheet = Worksheets("Budget_Report")
Set PRange = DSheet.Range(Cells(1, 53), Cells.SpecialCells(xlCellTypeLastCell))
Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable1 = PCache.CreatePivotTable(TableDestination:=DSheet.Cells(4, 1), TableName:="PivotTable1")
Set PTable2 = PCache.CreatePivotTable(TableDestination:=DSheet.Cells(17, 2), TableName:="PivotTable2")
With ActiveSheet.PivotTables("PivotTable1")
With .PivotFields("T-Lane")
.Orientation = xlRowField
.Position = 1
.Subtotals(1) = True
.Subtotals(1) = False
End With
With .PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlAverage
.Caption = "Monthly Cost Forecast"
End With
End With
With ActiveSheet.PivotTables("PivotTable2")
With .PivotFields("Oran")
.Orientation = xlRowField
.Position = 1
.Subtotals(1) = True
.Subtotals(1) = False
End With
With .PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlAverage
.Caption = "Monthly Cost Forecast"
End With
End With
When you insert the first pivot table and insert another one before populating the first one, the empty pivot table range of the first pivot table occupies the destination cell [DSheet.Cells(17, 2)] of the second pivot table.
I think you should insert the first pivot table and populate it and then insert another one and populate that as well.
See if that resolves your issue.
Dim DSheet As Worksheet
Dim PCache As PivotCache
Dim PTable1 As PivotTable
Dim PTable2 As PivotTable
Dim PRange As Range
Application.DisplayAlerts = True
Set DSheet = Worksheets("Budget_Report")
Set PRange = DSheet.Range(Cells(1, 53), Cells.SpecialCells(xlCellTypeLastCell))
Set PCache = ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:=PRange)
Set PTable1 = PCache.CreatePivotTable(TableDestination:=DSheet.Cells(4, 1), TableName:="PivotTable1")
With ActiveSheet.PivotTables("PivotTable1")
With .PivotFields("T-Lane")
.Orientation = xlRowField
.Position = 1
.Subtotals(1) = True
.Subtotals(1) = False
End With
With .PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlAverage
.Caption = "Monthly Cost Forecast"
End With
End With
Set PTable2 = PCache.CreatePivotTable(TableDestination:=DSheet.Cells(17, 2), TableName:="PivotTable2")
With ActiveSheet.PivotTables("PivotTable2")
With .PivotFields("Oran")
.Orientation = xlRowField
.Position = 1
.Subtotals(1) = True
.Subtotals(1) = False
End With
With .PivotFields("Monthly Cost FCST")
.Orientation = xlDataField
.Position = 1
.Function = xlAverage
.Caption = "Monthly Cost Forecast"
End With
End With
From the MSDN doc on pivot tables:
"Important" If you define multiple PivotTables on the Excel
Worksheet, it is possible the resulting tables can grow and overlap
each other if the Activity returns a large dataset. In this scenario,
you will receive "A PivotTable report cannot overlap another
PivotTable report" when you refresh the data. You can correct this
error by adding addition columns or rows between the pivot tables to
allow the tables to grow with out overlapping.

Passing Excel Sheet name into macro VB

I think this should be a simple one considering I have very little VB knowledge :) I have recorded a macro to create a pivot table for a range on the current sheet. Of course what this gives me is the code to create a pivot table for that specific sheet. I am trying to adjust the code to grab the name of the active sheet so I can use this macro across different sheets. I have tried to search and find exactly how to retrieve the name and then supply that name to the code that will being the process of creating the pivot table.
I am hitting a roadblock at the ActiveWorkbook.PivotCaches.Create section of the code. I am getting the "Run-time error '1004': Application-defined or object-defined error" message.
Any help would be greatly appreciated!
Sub Macro1()
Dim sht As String
sht = ActiveSheet.Name
Columns("A:K").Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
Worksheets(sht).Range("!R1C1:R1048576C11"), Version:=6).CreatePivotTable TableDestination:= _
Worksheets(sht).Range("!R1C14"), TableName:="PivotTable3", DefaultVersion:=6
ActiveSheet.Select
Cells(1, 14).Select
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Department")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable3").PivotFields( _
"Originating Master Name")
.Orientation = xlRowField
.Position = 2
End With
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Net")
.Orientation = xlRowField
.Position = 3
End With
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Month")
.Orientation = xlRowField
.Position = 4
End With
ActiveSheet.PivotTables("PivotTable3").AddDataField ActiveSheet.PivotTables( _
"PivotTable3").PivotFields("Net"), "Count of Net", xlCount
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Month")
.Orientation = xlColumnField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable3").PivotFields("Count of Net")
.Caption = "Sum of Net"
.Function = xlSum
End With
End Sub
Change this
Worksheets(sht).Range("!R1C1:R1048576C11")
To this
ActiveWorkbook.Sheets(sht).Range("A1:K1048576")
And this
Worksheets(sht).Range("!R1C14")
To this
ActiveWorkbook.Sheets(sht).Range("N1")

Inserting a date from a cell into a Pivot table to use it as a filter

Im very new to VBA. I will explain my project.
I have an Excel sheet with a lot of information that I want to filter. For the moment my code looks like this:
With ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"CREATION_DATE")
.Orientation = xlPageField
.Position = 1
End With
ActiveSheet.PivotTables("Tableau croisé dynamique2").AddDataField ActiveSheet. _
PivotTables("Tableau croisé dynamique2").PivotFields("AMOUNT"), _
"Nombre de AMOUNT", xlCount
With ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields("STATUS")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"VENDOR_NAME")
.Orientation = xlRowField
.Position = 2
End With
With ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"INVOICE_NUM")
.Orientation = xlRowField
.Position = 3
End With
With ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"Nombre de AMOUNT")
.Caption = "Somme de AMOUNT"
.Function = xlSum
End With
ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"CREATION_DATE").CurrentPage = "08/09/2016"
This code works to extract to filter with the date 08/09/2016.
Now, I would like to make the pivot table get this date in a cell ahead of launching the code.
But I don't want to have to go in to the code every time to change the date I want.
I would like something like this:
Ex: I write "09/09/2016" in cell "A1"
ActiveSheet.PivotTables("Tableau croisé dynamique2").PivotFields( _
"CREATION_DATE").CurrentPage = "A1"
But I am getting a debugging error.
After some testing, I found the cause (on my Excel Book). It was related to formatting the Pivot Field "CREATION_DATE", once I added the following section it worked.
Set PvtFld = PvtTbl.PivotFields("CREATION_DATE")
With PvtFld
.Orientation = xlPageField
.NumberFormat = "dd/mm/yyyy" ' << this line
.Position = 1
End With
And for the full code:
Sub PivotFilterDate()
Dim PvtTbl As PivotTable
Dim PvtFld As PivotField
' set your Pivot Table (after created) to a variable
Set PvtTbl = Sheets("PivotSpanish").PivotTables("Tableau croisé dynamique2")
' Set "CREATION_DATE" to a Pivot Field variable
Set PvtFld = PvtTbl.PivotFields("CREATION_DATE")
With PvtFld
.Orientation = xlPageField
.NumberFormat = "dd/mm/yyyy"
.Position = 1
End With
' you can modify your code to change all field setting, like following 2:
With PvtTbl.PivotFields("STATUS")
.Orientation = xlRowField
.Position = 1
End With
With PvtTbl.PivotFields("VENDOR_NAME")
.Orientation = xlRowField
.Position = 2
End With
' clear previous filters
PvtFld.ClearAllFilters
' --- trapping errors ---
' added a Boolean Flag to trap scenarios where no Pivot Item found that matches the value in Cell A1
Dim PvtItemExists As Boolean
PvtItemExists = False
' check all Pivot items in Pivot Field ("CREATION_DATE")
For Each PvtItem In PvtFld.PivotItems
' check if current Pivot Item equals the value in Cell A1
If PvtItem.Value = CStr(CDate(Range("D1").Value)) Then
PvtItemExists = True
Exit For
End If
Next PvtItem
If PvtItemExists Then
PvtFld.CurrentPage = CStr(CDate(Range("D1").Value))
Else
MsgBox "No data matches for date " & CDate(Range("D1").Value) & " in Pivot Table", vbCritical
End If
End Sub