VB中,使用Call与不使用它的区别

来源:互联网 发布:网络销售的自我包装 编辑:程序博客网 时间:2024/04/30 06:36

  讨论它们的区别源自一处代码:

Sheet1.Cells(2,1).CopyFromRecordset(Rs) 'Rs为一个ADO.Recordset对象。

我发现它不能运行,但是在调用前加上了Call,就可以运行了。这个问题困扰了我很久,都是因为不求甚解,结果发现早晚会出问题。

  经查阅相关资料,特将VB的Sub和Function调用语法总结如下:

1、Call SubA(P1,P2)
2、SubA P1,P2
3、Call FunA(P1,P2)
4、FunA P1,P2
5、VarA=FunA(P1,P2)
  也就是说,用Call调用的Sub或Function,以及取得了返回值的Function,需要加括号,而不要返回值的Function及未加Call调用的Sub,是不加括号的。第3、4种形式对于系统内置函数无效,只能针对用户自定义函数使用。这看似灵活的两种方式,有时却能带给人迷惑。请看以下程序:
Sub Demo(S As String)
  S = "DEF"
End Sub
Sub Main()
  Dim A As String
 
  A = "ABC"
  Debug.Print A
  Demo A
  Debug.Print A
 
  A = "ABC"
  Debug.Print A
  Call Demo(A)
  Debug.Print A
  A = "ABC"
  Debug.Print A
  Demo (A)
  Debug.Print A
End Sub
  结果:
ABC
DEF
ABC
DEF
ABC
ABC
  因为String这种对象类型,如果不声明参数方式,其默认为ByRef而不是ByVal,因此,Sub Demo内的S = "DEF",是能够改变实参的内容的,因此前两次调用后的结果都显示DEF。注意第三次调用的结果,前后都是ABC。为什么呢?因为Demo (A)是上述第2种,而不是第1种形式的调用。那()是啥意思啊?()就是个运算符,而不是Sub调用的最外层标志。也就是说,在第三次调用中,(A)并不表示共有一个参数,第一个参数是A,而是表示共有一个参数,第一个参数是(A)。那么(A)是个表达式,其结果是个临时量,类型于A & ""一样,已经不是指A变量本身了,因此过程内改变的是这个临时量而不是A,所以不影响Main中的A。如果你不相信这种结论,可以测试一下下面的Sub:
Sub Demo(S As String, T As String)
End Sub
Sub Main()
  Demo "1", "2"
  Call Demo("1", "2")
  Demo ("1", "2") '语法错误
End Sub
  就是说,带括号必须用Call,要不就不能用括号,一个参数时的那种括号是参数自己的一部分,碰巧看起来很像个带括号调用而已。推荐使用Call使得语法明朗(虽然写起来长些),包括MsgBox。为了不让人混乱,据说VB.Net已做了新规定,要求调用必须加括号。