Excel 2010 VBA: Invalid procedure call when adding data field to pivot table - vba

I want to create multiple pivot tables by encapsulating the complexity into functions and procedures (I did already manage to create pivots with VBA, but one module for each pivot, meaning lots of repetitive code...)
I managed to create procedures and functions to create the pivot, add a filter, and a row field. But when it comes to adding a data field, I get an invalid procedure call; the strange thing however is that I get that error only when I use variables to pass info: looking at the line prodicung the error, the first line works perfectly fine, whereas I cannot get the second line running (the variables contain the correct values):
pivotName.addDataField pivotName.PivotFields("sdID"), "SD ID number", xlCount 'works fine
pivotName.addDataField pivotName.PivotFields(fieldName), fieldDescription, calcMethod 'produces Invalid procedure call error
As I am running out of ideas, any help would be highly appreciated!
Thank you very much,
Alexander

The reason for the error is due to calcMethod being declared earlier in the code as a string.
The .addDataField method accepts the following parameters:
.AddDataField(Field, Caption, Function)
The parameter Function is of the XLConsolidationFunction enum and therefore should be declared and assigned like below:
Dim calcMethod As XlConsolidationFunction
calcMethod = xlCount
Once declared and assigned as above, you can use it within your method in the following way where fieldName and fieldDescription are both strings:
pivotName.addDataField pivotName.PivotFields(fieldName), fieldDescription, calcMethod

As you can see in the comment from Gareth, the problem was to declare calcMethod (optional function) as string, not as XLConsolidatedFunction.
Thank you once again!

Related

Name error when trying to call a function

I'm still learning VBA so I might be doing a lot of very basic mistakes. At the moment I'm trying to make a macro which could count the rows of a table. This sub works perfectly (with a table named "Tab").
Sub AddRowTable()
ActiveSheet.ListObjects("Tab").ListRows.Add (2)
End Sub
However, when I try to convert this sub to a function so I can call it with the name of the table as variable, I get a name error when writing "=AddRowTableFunction(Tab)" in a cell.
Function AddRowTableFunction(TableName)
ActiveSheet.ListObjects(TableName).ListRows.Add (3)
End Function
I understand that it is just a problem of type, but I just cant find how to do it properly.
Thanks.
At the moment I'm trying to make a macro which could count the rows of a table.
First off, that is not what your code is doing. Your code is adding a row to the table. The number of rows would be accessed using ListRows.Count.
when I try to convert this sub to a function so I can call it with the name of the table as variable...
You don't need a Function in order to include a variable. The differance between a Sub and a Function is that a Function returns a variable, while a Sub does not (i.e. a Function gives back a variable to the code that used it). Both Subs and Functions can take variables.
A Function that returns the number of rows in a given table would be something like this:
Function AddRowTableFunction(TableName As String)
AddRowTableFunction = ActiveSheet.ListObjects(TableName).ListRows.Count
End Function
For adding a row, you would probably use a Sub, because the action of adding a row doesn't return any information:
Sub AddRowTable(TableName As String)
ActiveSheet.ListObjects(TableName).ListRows.Add
End Sub
Finally, when using the Function in a formula, as Apafey pointed out, you need to write "Tab" (in quotes), not just Tab. "Tab" tells Excel to pass the text of the word Tab, while Tab tells Excel to look for a range named Tab, which probably doesn't exist.
You should try:
=AddRowTableFunction("Tab")
You wrote:
=AddRowTableFunction(Tab)
that is not fine.
As FaneDuru said, an UDF function can't change other cells, which explains the error). Thnaks !

VBA - Compile Error: Expected Function or Variable

To start, I am not a programmer. Im just someone trying to make a document that has an "invoice" number that increases on the document that goes up every time I print the document. I found a macro code online but I keep getting the
Compile error
I'll attach a snap shot of what im getting with the piece that keeps screwing up high lighted.
Is there something I'm doing wrong?
To expand on braX's answer...
That's the syntax for assigning the return value of a Function or Property Get member - namely, you are assigning to the procedure's identifier:
Public Function GetTotallyRandomNumber() As Long
GetTotallyRandomNumber = 4
End Function
Seems you mean to have a local variable named SerialNumber, however VBA already knows this identifier as the name of a Sub procedure named SerialNumber, and because a Sub procedure doesn't return anything, it can't legally be assigned like this.
Declare a local variable inside the procedure's scope, before the illegal assignment:
Dim SerialNumber As String
SerialNumber = System.PrivateProfileString(...)
And then your code will work... however I wouldn't recommend using the exact same name as the procedure.
My recommendation would be to name the local variable SerialNumber, and to rename the Sub procedure so that its name starts with a verb. Procedures do something, they're actions: find a meaningful name that describes what it does, and go with that.
Naming is hard though - if you can't find a simple name that describes what your procedure does, it's probably because it's doing too many things. Split it up into smaller, more focused procedures.
Public Sub PrintActiveDocumentAndAddSerialNumberBookmark()
You are treating a Function like a Subroutine. Subroutines do not return values.
If you want the routine to return a value, then change Sub to Function (at the top)
If you are not wanting it to return anything, then choose a different variable name instead of SerialNumber, or change the name of the Subroutine.
You cannot use a variable name that is the same as the name of the Subroutine.

Excel VBA, naming arguments causes "invalid procedure call or argument" Error 5

I have an Excel VBA script that creates a Table (a ListObject) from a range stored in the variable Storytable and then applied list formatting.
The positional parameter version of this line works fine:
Set Tbl = ActiveSheet.ListObjects.Add(xlSrcRange, StoryTable, , xlYes)
I would prefer to use named parameters, but naming the parameters causes an "invalid procedure call or argument" error (Error code 5) on this line:
Set Tbl = ActiveSheet.ListObjects.Add(SourceType:=xlSrcRange, Source:=StoryTable, TableStyleName:=xlYes)
even though this is pretty much identical to the example provided for the ListObjects.Add method in the Excel online help.
A bit of experimentation has shown that even naming just the final parameter TableStyleName:=xlYes in the first version of this line is enough to trigger the error.
What am I doing wrong here?
The fourth parameter to which you originally supplied xlYes is called XlListObjectHasHeaders, not TableStyleName. TableStyleName is the sixth parameter, and it does not accept xlYes as a valid option.
The online help is not only wrong in naming the parameters, it's also outdated and does not include TableStyleName.

VBA error in saving file using Format (date) function

I'm trying to save an activeworkbook but when I use the following code, I keep getting the error "compile error: expected function or variable" with the word "format" highlighted.
It boggles my mind because I used the exact same function and format in another macro and it saved the file perfectly. I also made sure they had the same types of variables defined already...
Here's the one line code
ActiveWorkbook.SaveAs Filename:=SavedPath & format(Date, "mmddyyyy") & " 4512 GLUpload.xlsm"
The variable savedpath is fine because when I run this line without the format part, it saves the file, but not sure why this screw it up. Also noticed in my other code, format is capitalized but it's not here.
The compiler error you are getting indicates that VBA is expecting an assignable value (either a literal, a variable, or the return value of a function). This means that one of the identifiers in the statement to the right of the equals sign doesn't fall into those categories. So, either SavedPath is defined somewhere as Sub SavedPath(), or there is a Sub Format(arg1, arg2) defined somewhere (if it had a different number of arguments you would get a "Wrong number of arguments or invalid property assignment" error). The second clue (in the comments) is that changing format to the strongly typed Format$ gave a "Type-declaration character does not match declared data type" error. This points to the compiler not treating the symbol format as a function call (Format$() is the strongly typed version of Format()). The solution is to track down the errant use of the VBA function name and re-name it.
A perfect example of why avoiding VBA keywords and function names is good practice.

Presence of parentheses suddenly causes code to break

I had a line of VBA code that basically looked like this:
MyControls.Add(Factory.CreateMyControl(param1, param2))
Where Factory.CreateMyControl is just a sneaky way to allow the new instance of my class module being returned to have a constructor.
It was working without any issues for several weeks. Suddenly, it begins throwing the error object doesn't support this property or method which is baffling me because everything looks like it always has.
After stepping into and through the code, I finally narrowed it down to the line above, and found the issue. The issue was the pair of parentheses surrounding the parameter(s) for the Add function. When I changed the code to the following:
MyControls.Add Factory.CreateMyControl(param1, param2)
It worked just as it always had before the unexpected break.
I now understand that this is the basic syntax in VBA for calling Sub's with parameters: to simply include all parameters in a comma-separated fashion without any parentheses (unless you're setting a Function's return value to another variable or using it's value for some other purpose).
My real question is, why did this suddenly just stop working?
Is it a common occurrence using VBA in Office 2007 for code that once worked to break without warning?
Or could this have been caused by some kind of patch that happened without my knowledge?
With parentheses around, the Sub's parameters per default were passed ByVal instead of ByRef. Without parentheses around, the default is ByRef
Example:
Dim r As Range
Sub test(v As Variant)
MsgBox TypeName(v)
End Sub
Sub main()
Set r = Range("A1")
test r 'ByRef; TypeName is Range
test (r) 'ByVal; TypeName is not Range but the type of the content of A1
End Sub