I'm trying to call a function in Excel VBA (2007), and am recieving a syntax error on the call. I have an array of data structures called ImportSets, which contains worksheets and strings, and am trying to pass members of items in that array to a function, called Import.
The calling code looks like this:
For n = 1 To 7
Debug.Print ("Destsheet: " & ImportSets(n).DestSheet.name)
Debug.Print ("Sourcesheet: " & ImportSets(n).SourceSheet.name)
Debug.Print ("Sourcecolumn: " & ImportSets(n).SourceColumn)
Import(CostAnalysisWorksheet.Sheets("Reimbursements"), ImportSets(n).DestSheet, ImportSets(n).SourceSheet, ImportSets(n).SourceColumn)
Next n
All of the Debug.Print statements return meaningful and correct strings, and check for the existence of "Reimbursements" returns true. The method call is on one line. Here is the ImportSet object code:
Public Type ImportSet
DestSheet As Worksheet
SourceSheet As Worksheet
SourceColumn As String
...other code...
End Type
The function body looks like this:
Function Import(ByRef ReimbursementSheet As Worksheet, ByRef DestSheet As Worksheet, ByRef ImportSheet As Worksheet, ByRef ImportSheetPriceColumn As String) As String
....code here .....
End Function
I am getting a red-highlighted syntax error on the function call (in the first snippet). I am probably missing something stupid. What is it?
This Q&A is being used as a duplicate target, but none of the answers are telling the whole story.
First, this behavior has nothing to do with the version of Excel or whatever the host application is: it's just standard VBA syntax, and the rules have been been the same for well over 20 years now - JavaScript and Perl have their respective kinks as well, as does every single programming language ever made.
When the parentheses are delimiting an argument list, the VBE puts the opening parenthesis immediately after the invoked function:
When the parentheses are interpreted as part of the first argument (i.e. a parenthesized expression), the VBE puts a space between the invoked procedure and its argument list:
This code wouldn't compile:
Because the entire parenthesized expression is the first argument, and there's no way
("test", vbInformation)
can be evaluated as a value - it's a syntax error, like in the OP.If the expression can be evaluated as a value, this value is then passed by value (
ByVal
) regardless of the invoked procedure's signature specifying that parameter asByRef
- see 5.3.1.11 Procedure Invocation Argument Processing, runtime semantics:The solution is, as others concluded, to drop the parentheses when making a procedure call:
...or to consistently use the obsolete explicit call syntax:
Parentheses are only needed when making a function call (i.e. when capturing the return value into a local variable):
The important point is how you want the function to return the value and whether your passing variables ByVal or ByRef. ByRef allows the function to change the variable ByVal means the function cannot change the variable.
These 2 examples essentially do the same thing but note the subtlety in manipulating a variable ByRef and returning a variable from a function.
or alternatively pass the variables ByRef and manipulate with the function
This example is quite trivial but often an object, array etc may need passed to a function for processing ByRef rather than to provide an answer ByVal
I haven't used VBA in Excel 2007 but older versions only allow you to put brackets around function call parameters if you're assigning the return value to a variable. Try this: