30

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

Randomize- 这条线有效。

Randomize()- 这条线也有效。

MsgBox "Hello world!"- 这行得通。

MsgBox ("Hello world!")- 这也有效。

该脚本将在具有不同 Windows 版本(至少 Windows XP)的多台机器上运行。我想知道在使用这些函数时是否会遇到任何兼容性/语法问题。

4

5 回答 5

27

一段可调用的代码(例程)可以是 Sub(调用副作用/它的作用)或 Function(调用它的返回值)或两者的混合。作为 MsgBox 的文档

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

MsgBox(提示[, 按钮][, 标题][, 帮助文件, 上下文])

表明,这个程序是第三种。

VBScript 的语法规则很简单:

调用(routine as a)函数时使用参数list()

如果您想向用户显示消息并且需要知道用户的回复:

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

调用 (routine as a) 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 调用中的 empty() 的宽大处理。可以通过以下方式调用“纯”子随机化(称为设置随机种子的副作用)

Randomize()

尽管 () 既不能表示“给我你的返回值”也不能表示“按值传递”。这里更严格一点会迫使 prgrammers 意识到

Randomize n

Randomize (n)

在 Sub 调用中允许参数 list() 的 Call 语句:

s = "value" 调用 MsgBox(s, 65, "MsgBox Example")

这进一步鼓励程序员不假思索地使用 ()。

(基于你的意思是“不能使用括号?”

于 2012-11-29T09:17:07.050 回答
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 解析器对空参数列表有一个特殊规则。但是,我的建议是避免使用这种特殊结构,只需调用任何子程序而不使用括号。

我很确定这些句法规则适用于不同版本的操作系统。

于 2012-11-29T08:51:09.917 回答
3

您只是在函数内部使用了一个参数,因此它在两种情况下都可以正常工作,如下所示:

MsgBox "Hello world!"
MsgBox ("Hello world!")

但是,当您使用多个参数时,在 VBScript 方法中,括号会引发错误,而没有括号将可以正常工作,例如:

MsgBox "Hello world!", vbExclamation

上面的代码将运行顺利,但

MsgBox ("Hello world!", vbExclamation)

会抛出错误。尝试这个!!:-)

于 2012-11-29T17:22:16.003 回答
1

您必须在 vba 中区分子例程和函数...通常(据我所知),子例程不返回任何内容,并且周围的括号是可选的。对于函数,您需要编写括号。

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

这个答案更详细一点,但基本上你应该在保存方面,当你为函数提供括号并将它们留给子例程时。

于 2012-11-29T08:12:44.747 回答
0

"" 和 () 的区别是:

使用 "" 你没有调用任何东西。
使用 () 你正在调用一个子。

子示例:

Sub = MsgBox("Msg",vbYesNo,vbCritical,"Title")
Select Case Sub
     Case = vbYes
          MsgBox"You said yes"
     Case = vbNo
          MsgBox"You said no"
 End Select

与正常:

 MsgBox"This is normal"
于 2020-01-09T18:02:11.800 回答