在VBScript中,MsgBox ""与MsgBox()有何区别?

31

我正在尝试编写 VBScript,使用一些函数例如 Randomize 和 MsgBox。 我很好奇使用 () 和不使用它们有什么区别。 例如:

Randomize - 这行可以工作。

Randomize() - 这行也可以工作。

MsgBox "Hello, World!" - 这是可行的。

MsgBox ("Hello, World!") - 这也可以工作。

这个脚本将在多台安装有不同版本的 Windows(至少是 Windows XP)的计算机上运行。 我想知道是否会在使用这些函数时出现任何兼容性/语法问题。

4个回答

29

可调用的一段代码(例程)可以是一个Sub(因其作用而被调用),也可以是一个Function(因其返回值而被调用),或者两者混合。正如MsgBox文档所示,

显示对话框中的消息,等待用户单击按钮,并返回指示用户单击了哪个按钮的值。

MsgBox(prompt[, buttons][, title][, helpfile, context])

表明该例程属于第三种。

VBScript的语法规则很简单:

在调用函数时使用参数列表()

如果您想向用户显示消息并需要知道用户的响应:

Dim MyVar
MyVar = MsgBox ("Hello, World!", 65, "MsgBox Example")
   ' MyVar contains either 1 or 2, depending on which button is clicked.

调用(子过程)Sub时,不要使用参数列表()

如果你只是想向用户显示一条消息而不关心其响应:

MsgBox "Hello, World!", 65, "MsgBox Example"

这种美丽的简洁性被以下问题搅乱:

使用 () 来表示参数列表和强制按值调用语义的设计缺陷

>> Sub S(n) : n = n + 1 : End Sub
>> n = 1
>> S n
>> WScript.Echo n
>> S (n)
>> WScript.Echo n
>>
2
2

S(n)并不意味着“用n调用S”,而是“用n的值的副本调用S”。

程序员看到这个可能会误解

>> s = "value"
>> MsgBox(s)
'

工作人员'在尝试时会有惊喜:

'
>> MsgBox(s, 65, "MsgBox Example")
>>
Error Number:       1044
Error Description:  Cannot use parentheses when calling a Sub

编译器在处理Sub调用中的空()时比较宽松。被用于设置随机数种子的副作用而被调用的“纯净”Sub Randomize可以被调用。

Randomize()

虽然()不能既表示“给我你的返回值”也不能表示“传递某个值”,但在这里更加严格的规定会迫使程序员注意其差异。

Randomize n

Randomize (n)

使用 Call 语句可以在 Sub 调用中传递参数列表 ():

>> s = "value"
>> Call MsgBox(s, 65, "MsgBox Example")

这进一步鼓励程序员在毫无思考的情况下使用括号。

(基于What do you mean "cannot use parentheses?"


2
我建议使用 vbOkCancel 而不是硬编码 65。这样更易读。 - Matthieu Cormier
5
65等同于vbOkCancel + vbInformation。常量可以在这里找到:http://www.techonthenet.com/access/constants/msgbox_args.php - Matthieu Cormier
我知道如何使用它,但我想更清楚一些。MsgBox是一个函数还是一个子程序或某种混合体? - Ejaz Ahmed

10
据我所知,以下是在VBScript中调用子程序和函数的规则:
- 当调用一个子程序或者函数且不需要返回值时,不要使用括号。 - 当调用一个函数并且需要分配或使用返回值时,需要将参数括在括号内。 - 当使用Call关键词调用子程序时,需要将参数括在括号内。
由于您可能不会使用Call关键词,您只需要学习一个规则:如果您调用一个函数并且希望分配或使用返回值,则需要将参数括在括号内。否则,不要使用括号。 以下是一些示例:
- WScript.Echo 1, "two", 3.3 - 调用一个子程序 - WScript.Echo(1, "two", 3.3) - 语法错误 - Call WScript.Echo(1, "two", 3.3) - 关键词Call需要括号 - MsgBox "Error" - 调用一个“像”子程序的函数 - result = MsgBox("Continue?", 4) - 调用一个需要返回值的函数 - WScript.Echo (1 + 2)*3, ("two"), (((3.3))) - 调用一个子程序,在参数列表中使用括号包围的表达式进行计算 (注意,如果您在参数列表中用括号括住一个变量,则会将其从按引用传递更改为按值传递的行为)。
  • WScript.Echo(1) - 显然这是使用括号的子例程调用,但实际上,参数只是表达式(1),这往往会让那些习惯其他编程语言需要在调用子例程时指定括号的人感到困惑。

  • 我不确定如何解释你的示例Randomize()Randomize是一个接受单个可选参数的子例程,即使子例程没有任何参数,使用空括号对它进行调用也是可以接受的。似乎VBScript解析器对于空参数列表有特殊规则。但是,我的建议是避免使用这种特殊结构,而是简单地调用任何子例程而不使用括号。

  • 我相当确定这些语法规则适用于不同版本的操作系统。


    3

    你只是在函数内使用单个参数,因此在以下两种情况下都能正常工作:

    MsgBox "Hello, World!"
    MsgBox ("Hello, World!")
    

    但是当你使用多个参数时,在VBScript中带有括号的方法会抛出错误,而没有括号的方法将正常工作,如下所示:

    MsgBox "Hello, World!", vbExclamation
    

    以上代码可以正常运行,但是...
    MsgBox ("Hello, World!", vbExclamation)
    

    该操作会引发一个错误。

    尝试这个!! :-)


    请更正您的最后一个示例。 - Ekkehard.Horner
    谢谢@Ekkehard.Horner!! 我已经用简单的方式描述了它(或者你可以说是用通俗易懂的语言)。你想让我修改什么?请详细说明。提前致谢! - Shivam Gupta
    1
    你最后的例子只是工作中的一个副本,所以它不会抛出错误。 - Ekkehard.Horner
    嘿,谢谢@Ekkehard.Horner提醒我。我明白了你的意思并纠正了我的答案。我忘记在最后一个例子中加括号了。非常感谢你!! - Shivam Gupta
    1
    仅供参考,带括号和多个变量的MsgBox将起作用,即如果您将其分配给一个值。 - freginold

    1

    在VBA中,您必须区分子程序和函数...一般来说(据我所知),子程序不返回任何内容,周围的括号是可选的。对于函数,您需要编写括号。

    至于您的示例,MsgBox不是一个函数,而是一个子程序,因此在这种情况下,括号是可选的。有一个例外,当您不分配返回值或函数不使用参数时,您也可以省略括号。

    这个答案提供了更详细的信息,但基本上,对于函数,提供括号会更保险,对于子程序,则可以省略括号。


    MsgBox只是一个可以用作Sub或Function的例子;在Sub调用中,参数列表()是禁止的;当应用于参数传递语义时,“consume”是一个误导性的术语。 - Ekkehard.Horner
    2
    除非使用“Call”关键字,否则禁止。 - Ansgar Wiechers

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接