Reputation: 311
I'm trying to write a VBScript and I'm using functions such as Randomize, and MsgBox. I'm curious as to what is the difference of using () and not using them. For example:
Randomize
- This line works.
Randomize()
- This line works also.
MsgBox "Hello, World!"
- This works.
MsgBox ("Hello, World!")
- This works as well.
The script will be running on multiple machines with different versions of Windows (at least Windows XP). I'm wondering if I would be getting any compatibility/syntax issues in using these functions.
Upvotes: 31
Views: 153921
Reputation: 38765
A callable piece of code (routine) can be a Sub (called for a side effect/what it does) or a Function (called for its return value) or a mixture of both. As the documentation for MsgBox,
Displays a message in a dialog box, waits for the user to click a button, and returns a value indicating which button the user clicked.
MsgBox(prompt[, buttons][, title][, helpfile, context])
indicate, this routine is of the third kind.
The syntactical rules of VBScript are simple:
Use parameter list () when calling a (routine as a) function
If you want to display a message to the user and need to know the user's response:
Dim MyVar
MyVar = MsgBox ("Hello, World!", 65, "MsgBox Example")
' MyVar contains either 1 or 2, depending on which button is clicked.
Don't use parameter list () when calling a (routine as a) Sub
If you want to display a message to the user and are not interested in the response:
MsgBox "Hello, World!", 65, "MsgBox Example"
This beautiful simplicity is messed up by:
The design flaw of using () for parameter lists and to force call-by-value semantics
>> Sub S(n) : n = n + 1 : End Sub
>> n = 1
>> S n
>> WScript.Echo n
>> S (n)
>> WScript.Echo n
>>
2
2
S (n) does not mean "call S with n", but "call S with a copy of n's value".
Programmers seeing that
>> s = "value"
>> MsgBox(s)
'works' are in for a surprise when they try:
>> MsgBox(s, 65, "MsgBox Example")
>>
Error Number: 1044
Error Description: Cannot use parentheses when calling a Sub
The compiler's leniency with regard to empty () in a Sub call. The 'pure'
Sub Randomize (called for the side effect of setting the random seed) can be called by
Randomize()
although the () can neither mean "give me your return value) nor "pass something by value". A bit more strictness here would force programmers to be aware of the difference in
Randomize n
and
Randomize (n)
The Call statement that allows parameter list () in Sub calls:
>> s = "value"
>> Call MsgBox(s, 65, "MsgBox Example")
which further encourage programmers to use () without thinking.
(Based on What do you mean "cannot use parentheses?")
Upvotes: 29
Reputation: 106916
To my knowledge, these are the rules for calling subroutines and functions in VBScript:
Call
keyword, enclose the arguments in parenthesesSince you probably won’t be using the Call
keyword, you only need to learn the rule that if you call a function and want to assign or use the return value you need to enclose the arguments in parentheses. Otherwise, don't use parentheses.
Here are some examples:
WScript.Echo 1, "two", 3.3
- calling a subroutine
WScript.Echo(1, "two", 3.3)
- syntax error
Call WScript.Echo(1, "two", 3.3)
- keyword Call
requires parentheses
MsgBox "Error"
- calling a function "like" a subroutine
result = MsgBox("Continue?", 4)
- calling a function where the return value is used
WScript.Echo (1 + 2)*3, ("two"), (((3.3)))
- calling a subroutine where the arguments are computed by expressions involving parentheses (note that if you surround a variable by parentheses in an argument list it changes the behavior from call by reference to call by value)
WScript.Echo(1)
- apparently this is a subroutine call using parentheses, but in reality, the argument is simply the expression (1)
, and that is what tends to confuse people that are used to other programming languages where you have to specify parentheses when calling subroutines
I'm not sure how to interpret your example, Randomize()
. Randomize
is a subroutine that accepts a single optional argument, but even if the subroutine didn't have any arguments, it is acceptable to call it with an empty pair of parentheses. It seems that the VBScript parser has a special rule for an empty argument list. However, my advice is to avoid this special construct and simply call any subroutine without using parentheses.
I'm quite sure that these syntactic rules applies across different versions of operating systems.
Upvotes: 10
Reputation: 427
You are just using a single parameter inside the function, hence it is working fine in both the cases, like follows:
MsgBox "Hello, World!"
MsgBox ("Hello, World!")
But when you'll use more than one parameter, in VBScript a method with parentheses will throw an error and without parentheses will work fine like:
MsgBox "Hello, World!", vbExclamation
The above code will run smoothly, but
MsgBox ("Hello, World!", vbExclamation)
will throw an error.
Try this!! :-)
Upvotes: 3
Reputation: 116
You have to distinguish between subroutines and functions in VBA... Generally (as far as I know), subroutines do not return anything and the surrounding parentheses are optional. For functions, you need to write the parentheses.
As for your example, MsgBox is not a function but a subroutine and therefore the parentheses are optional in that case. One exception with functions is, when you do not assign the returned value, or when the function does not consume a parameter, you can leave away the parentheses too.
This answer goes into a bit more detail, but basically you should be on the save side, when you provide parentheses for functions and leave them away for subroutines.
Upvotes: 1