VBA; Invalid procedure or argument error - vba

A little background;
I have to run a weekly reports for my job on Monday for the previous week, however I need to consolidated the material, I did and made a pivot table and I have to do this for multiple worksheets. However I decided to create a macro to do this redundant task. Created it now I seem get this error message "Invalid Procedure or Argument". I can't get it to open in my in a new work sheet, t his is my code >>
Sub weekmaster()
'
' weekmaster Macro
' Macro for the week
'
' Keyboard Shortcut: Ctrl+t
'
Cells.Select
Sheets.Add
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"weekmaster!R1C1:R1048576C62", Version:=xlPivotTableVersion12). _
CreatePivotTable TableDestination:="Sheet9!R3C1", TableName:="PivotTable1" _
, DefaultVersion:=xlPivotTableVersion12
Sheets("Sheet9").Select
Cells(3, 1).Select
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Order ID")
.Orientation = xlRowField
.Position = 1
End With

It appears you're missing one argument. CreatePivotTable takes the following arguments:
expression.CreatePivotTable(TableDestination, TableName, ReadData, DefaultVersion)
TableDestination Required Variant The cell in the upper-left corner of the PivotTable report’s destination range (the range on the worksheet where the resulting PivotTable report will be placed). The destination range must be on a worksheet in the workbook that contains the PivotCache object specified by expression.
TableName Optional Variant The name of the new PivotTable report.
ReadData Optional Variant True to create a PivotTable cache that contains all of the records from the external database; this cache can be very large. False to enable setting some of the fields as server-based page fields before the data is actually read.
DefaultVersion Optional Variant The default version of the PivotTable report.
Subsequently, you'll probably want to add 'true' between your TableName and DefaultVersion.
Cheers, LC

You'll get an error if you run the macro more than once, or if Sheet9 already exists (because the macro tries to create the same pivot table with the same name on the same sheet). If I am to assume that you a new PivotTable in a new worksheet to be generated every time you go to your data sheet and run the macro, you can update your code with the following:
Dim myRange as Range
dim myNewSheet as Worksheet
' Stores all continuous data on the sheet in the myRange variable
Set myRange = Range("A1").CurrentRegion
' Adds a new sheet and stores it in the myNewSheet variable
Set myNewSheet = Sheets.Add
' Use the variables to create the new pivot table
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
myRange, Version:=xlPivotTableVersion12).CreatePivotTable _
TableDestination:=myNewSheet.Cells(3, 1), DefaultVersion _
:=xlPivotTableVersion12
' Select your Order ID field
With myNewSheet.PivotTables(1).PivotFields("Order ID")
.Orientation = xlRowField
.Position = 1
End With

Related

using a wildcard to prevent subtotal line from being filtered and copied excel vba

I have a situation where I have a list of salespeople that gets filtered and moves all that filtered data to it's own spreadsheet. The problem that I am having is the macro is also filtering the subtotal line so its creating a sheet with no data and it's also creating a situation where the sheet is so large I cant save the file.
I wrote some code that i thought would prevent any worksheet starting with "Sheet" to not get filtered, but I don't know how to use a wildcard in a string. Need a wildcard since the "Sheet #" is different depending on the month.
Dim Sht As Worksheet
Dim Rng As Range
Dim List As Collection
Dim varValue As Variant
Dim E As Long
' // Set your Sheet name
Set Sht = Application.ActiveSheet
' // set your auto-filter, A6
With Sht.Range("A2")
.AutoFilter
End With
' // Set your agent Column range # (2) that you want to filter it
Set Rng = Range(Sht.AutoFilter.Range.Columns(22).Address)
ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort.SortFields.Add
Key:=Range _
("V:V"), SortOn:=xlSortOnValues, Order:=xlAscending,
DataOption:= _
xlSortTextAsNumbers
With ActiveWorkbook.Worksheets("Sheet1").AutoFilter.Sort
.Header = xlYes
.MatchCase = False
.Orientation = xlTopToBottom
.SortMethod = xlPinYin
.Apply
End With
' // Create a new Collection Object
Set List = New Collection
' // Fill Collection with Unique Values
On Error Resume Next
For E = 2 To Rng.Rows.Count
List.Add Rng.Cells(E, 1), CStr(Rng.Cells(E, 1))
Next E
' // Start looping in through the collection Values
For Each varValue In List
' // Filter the Autofilter to macth the current Value
'Rng.AutoFilter Field:=22, Criteria1:=varValue, _
' Operator:=xlAnd, Criteria2:="<>"
Rng.AutoFilter Field:=22, Criteria1:="<>Sheet*", _
Operator:=xlAnd, Criteria2:=varValue
' // Copy the AutoFiltered Range to new Workbook
'If List = (Blanks) Then
Sht.AutoFilter.Range.Copy
The Criteria1:="<>Sheet*" code is what I tried to do and the code above is what is was before. So my question is what can be done to prevent to the subtotal row sheet from being created?
Don't add the sheet name to the autofilter criteria. Just check the sheet name before you autofilter at all.
If Not ActiveSheet.Name Like "Sheet*" Then
'Do whatever you need to do
End If
On the other hand, you can remove the Not keyword if you wanted to include sheet names starting with sheet:
If ActiveSheet.Name Like "Sheet*" Then
Append a timestamp to your sheetname string. The basic idea is to use the "time" function, i.e. time (now), where time can be extracted as yy,mm,dd,hh,ss. Separately define variables strings to store each of the desired time components. Then, create a name like sheetname= myname string+my dd+ my hh.... I think it can become problematic if you try to add the time results directly to your sheetname string, so save the time result first, then combine strings.
I like to start my project by setting up my workbook with sheets(1).name ="blank". Hide it, unhide it, and copy it perpetually.
Good luck.
So after playing with the code for awhile I realized that using a wildcard for "Sheet*" wouldn't work since all the filtered results started with "Sheet" in the first place. But by adding
If varValue <> "" Then (which states that if the filtered result isn't blank than continue code) after Rng.AutoFilter Field:=22, Criteria1:="<>Sheet*", Operator:=xlAnd, Criteria2:=varValue
it fixed the issue. Now the code skips the subtotal line successfully.

VBA: Creating a Pivot Table

I've been able to create Pivot Tables in code before but that was adding to a new worksheet. I'm now trying to add a Pivot Table to an existing worksheet and am getting error message "Run-time error 1004: The PivotTable field name is not valid". The code is below, my error begins in the last segment beginning with ActiveWorkbook and ending with xlPivotTableVersion14. Any help would be much appreciated.
Public Sub AlliedPT()
Dim AlliedData As String
Dim SAProw As Long
Dim PivotSheet As String
Sheets("Sheet1").Select
SAProw = Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Sheet1").Select
ActiveWorkbook.Names.Add Name:="AlliedData", RefersTo:= _
"=Sheet1!$A$1:$N$" & SAProw
Sheets("PivotSheet").Select
PivotSheet = ActiveSheet.Name
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"AlliedData", Version:=xlPivotTableVersion14).CreatePivotTable _
TableDestination:=PivotSheet & "!R3C6", TableName:="PivotTable18",
DefaultVersion _
:=xlPivotTableVersion14
End Sub
I think you should check your Row 1 Columns A-N in SHeet 1 and make sure there is a unique, non-blank column name for each column in your source data. The first row contains the pivot table field names.

Can you make a pivot table by column index as opposed to column name in VBA

I have a table composed of 400 rows and 35 columns, and made a VBA script to make a pivot table comparing 2 columns vs 12 separate columns successfully.
While generating the pivot table, column headers are used (to avoid confusion). I am new with VBA, and this is how I called everything up to my errors
ActiveCell.Select
Range("AA3").Select
Selection.CurrentRegion.Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"Practitioners!R3C1:R246C27", Version:=xlPivotTableVersion15). _
CreatePivotTable TableDestination:="Practitioners!R3C29", TableName:= _
"PivotTable8", DefaultVersion:=xlPivotTableVersion15
Sheets("Practitioners").Select
Cells(3, 29).Select
ActiveWorkbook.ShowPivotTableFieldList = False
With ActiveSheet.PivotTables("PivotTable8").PivotFields("Capability")
.Orientation = xlRowField
.Position = 1
End With
With ActiveSheet.PivotTables("PivotTable8").PivotFields("Sub-Capability")
.Orientation = xlRowField
.Position = 2
End With
ActiveSheet.PivotTables("PivotTable8").AddDataField ActiveSheet.PivotTables( _
"PivotTable8").PivotFields("Grade"), "Count of Grade", xlCount
ActiveSheet.PivotTables("PivotTable8").AddDataField ActiveSheet.PivotTables( _
"PivotTable8").PivotFields("06-Feb-2017"), "Count of 06-Feb-2017", xlCount
but my column headers will change every week, and altering the name of the header means the VBA code will not work because it is no longer "06-Feb-2017".
I tried making a reference to an absolute cell in my code, but came up with an error
Run-time error '1004, Unable to get the PivotFields property of the
PivotTable class
Is there a way to refer to the PivotFields as an absolute cell reference (ie B3)?
Try the code below (explanations are inside the code comments).
You need to make sure that the formatting of Cell "B3" is identical to the one in the PivotTable, otherwise you will get a run-time error at the following line:
.AddDataField PvtTbl.PivotFields(PvtFlfVal), "Count of " & PvtFlfVal, xlCount
Code
Option Explicit
Sub DynamicPivotTableCountField()
Dim PvtTbl As Pivottable
Dim PvtFlfVal ' As String
' set the Pivot Table, replace "Sheet1" with your sheet's name (don't use ActiveSheet)
Set PvtTbl = Worksheets("Practitioners").PivotTables("PivotTable8")
' get the value from Cell B3, make sure it's formatted the way you need it for the Pivot Table later
PvtFlfVal = Format(Worksheets("Practitioners").Range("B3").Value, "dd-mmm-yyyy")
With PvtTbl
.AddDataField PvtTbl.PivotFields(PvtFlfVal), "Count of " & PvtFlfVal, xlCount
End With
End Sub

Combine Print Ranges from Multiple Worksheets VBA EXCEL

I am trying to figure out how to print the "ActiveSheet" or Sheet1 along with "Sheet5" (rows 1-6, A:M) being displayed at the bottom with a 2 row space in between the end of Sheet1 and the beginning of data from Sheet5. I've been trying to look up similar questions and read something about a "Union" but I wasn't sure how it would fit here.
Private Sub CommandButton1_Click()
Dim Sel_Manager As String
'Headers repeated at the top
Application.PrintCommunication = False
With ActiveSheet.PageSetup
.PrintTitleRows = "$2:$2"
.PrintTitleColumns = "$B:$M"
.Orientation = xlLandscape
.Zoom = False
.FitToPagesWide = 1
.FitToPagesTall = 1
End With
'Manager selection through ComboBox dropdown
Sel_Manager = ComboBox1
'Inserting autofilters for worksheet
Cells.Select
Selection.AutoFilter
'Manager defined in the dropdown ComboBox
ActiveSheet.Range("B2", Range("M2").End(xlDown)).AutoFilter Field:=1, Criteria1:=Sel_Manager
ActiveSheet.Range("B2", Range("M2").End(xlDown)).AutoFilter Field:=2, Criteria1:="A"
'Here I select range to be printed and specify manager in filename
ActiveSheet.Range("B2", Range("M2").End(xlDown)).Select
Selection.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
Sel_Manager + ".pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, OpenAfterPublish:=True
ActiveSheet.ShowAllData
Application.PrintCommunication = True
End Sub
This may give you some ideas.
I created two worksheets. One, called "Main", contains data that has "names" in column B and some As in column C. The other, called "Extra" contains the six rows to appear at the bottom of the filtered data.
I do not use Excel's identifiers when referencing worksheets. The first sheet will have an identifier of Sheet1 and a name of "Sheet1". If you immediately create another sheet it will have an identifier of Sheet2 and a name of "Sheet2". However, if Sheet1 is renamed before the second sheet is created, it will have an identifier of Sheet2 and a name of "Sheet1". It can all get very confusing.
I have hardcoded the selected manager as "Aaaaa" rather than make it a user entered parameter. I have prepared worksheet "Main" for printing but have not output it.
Option Explicit
Sub Test()
Dim Manager As String
Dim RngFiltered As Range
Dim RowSht1Last As Long
Manager = "Aaaaa"
With Worksheets("Main")
.AutoFilterMode = False ' Switch off auto filtering if on
' Find last row containing a value
RowSht1Last = .Cells.Find("*", .Range("A1"), xlFormulas, , xlByRows, xlPrevious).Row
With .Range("B2:M2")
.AutoFilter Field:=1, Criteria1:=Manager
.AutoFilter Field:=2, Criteria1:="A"
End With
Set RngFiltered = .Cells.SpecialCells(xlCellTypeVisible)
' Just to show the filtered range. Note, I cannot find a documented limit
' on the number of sub-ranges within a range. If there is a limit, I have
' never managed to reach it. However Range.Address has a limit which is a
' little under 255.
Debug.Print Replace(RngFiltered.Address, "$", "")
Worksheets("Extra").Range("A1:M6").Copy Destination:=.Cells(RowSht1Last + 2, "A")
' ###### Output visible rows
' Delete rows copied from Sheet5
.Rows(RowSht1Last + 2 & ":" & RowSht1Last + 8).Delete
End With
End Sub

How to define PIVOT table source dynamically?

I'm trying to do a PIVOT table from different worksheets and insert each PIVOT output in a certain column into a table.
Sub PivotvpcodeSATURATION()
Dim wsNew As Worksheet
Dim i As Integer
Dim z As Integer
Set ws1 = ActiveWorkbook.Sheets("24.11.")
Set ws2 = ActiveWorkbook.Sheets("25.11.")
Set ws3 = ActiveWorkbook.Sheets("26.11.")
Set ws4 = ActiveWorkbook.Sheets("27.11.")
Set ws5 = ActiveWorkbook.Sheets("28.11.")
Set ws6 = ActiveWorkbook.Sheets("29.11.")
Set ws7 = ActiveWorkbook.Sheets("30.11.")
Set wsNew = Sheets.Add
i = 3
z = 16
Do
ws1.Select
Range("A2").Select
ActiveWorkbook.PivotCaches.Create(SourceType:=xlDatabase, SourceData:= _
"24.11.!R1C2:R11754C10", Version:=xlPivotTableVersion14).CreatePivotTable _
TableDestination:=wsNew.Name & "!R3C1", TableName:="PivotTable", DefaultVersion _
:=xlPivotTableVersion14
wsNew.Select
Cells(3, 1).Select
With ActiveSheet.PivotTables("PivotTable").PivotFields("VP CODE")
.Orientation = xlRowField
.Position = 1
End With
wsNew.Select
ActiveSheet.PivotTables("PivotTable").AddDataField ActiveSheet.PivotTables( _
"PivotTable").PivotFields("1/0"), "Sum of 1/0", xlSum
wsNew.Select
Range("B4").Select
Range(Selection, Selection.End(xlDown)).Select
Selection.Copy
Sheets("VP_Saturation").Select
' Range(Cells(3, z).Address).Select
ActiveSheet.Paste
Application.DisplayAlerts = False
wsNew.Delete
Application.DisplayAlerts = True
z = z + 2
Loop Until z = 28
End Sub
The thing i am non able to reach is,
how to define a worksheets name as a variable, so that i don't have to select w1, w2,w.., wn each time, and don't have to put a sheet name inside 24.11.!R1C2:R11754C10 .
As well the column name where to insert copied Pivot result i define as a variable Cells(3, z).Address.Select, but this string returns an error.
Maybe someone can help with it? Thanks!
put all worksheets in an array and do a cycle on each element of the array with For Each....Next
regarding your second question, change:
SourceData:="24.11.!R1C2:R11754C10"
to
SourceData:=ws1.name&"!R1C2:R11754C10"
and it will feed the worksheet name into the string
third question:
replace
Range(Cells(3, z).Address).Select
with
Cells(3, z).Select
If you use a template Excel file where the format doesn't change. I suggest creating a dynamic named range for all your data sources. Then just go to each pivot table and refer to the named range in Change Source Pivot Table Options.
All your VBA has to do is a variation of ThisWorkbook.RefreshAll.
Use a variation of this formula to create the dynamic named range: =Data!$A$5:OFFSET(Data!$A$5,COUNTA(Data!$A:$A)-1,52). Basically choose the data source sheet, the starting cell, and how many columns over the data sits. The rows will adjust automatically.