VBS ByRef和ByVal参数

标签: , , , ,

翻译自 MSDN VBScript 文档《ByRef and ByVal Parameters》,建议有能力的同学阅读原文。

当你调用一个过程或者函数的时候,每个参数都能以传址或者传值的方式传递。当一个参数以传址的方式传递时,在调用的过程中变量的值可以被改变,这个改变在调用过程结束之后仍然持续。当一个参数以传值的方式传递时,在调用的过程中对变量值的任何改变都不会在调用过程结束之后持续。

在一个 Sub 或者 Function 声明中,每一个参数都可以指定为 ByRef 或者 ByVal。如果两者都没有指定,默认为 ByRef

如果指定为 ByVal,那么在调用过程中对应的参数总是以传值的方式传递。

如果指定为 ByRef 或者两个都不指定,那么在调用过程中参数以传址的方式传递。如果参数被小括号括起来,并且小括号并不属于参数列表,那么参数以传值的方式传递。当传递的变量是类的参数时,参数也以传值的方式传递。除此之外,参数以传址的方式传递。

指定 ByRef 和 ByVal

在下面这个例子中, MyParam 变量加上了 ByRef 关键字。在调用过程时,变量 MyArg 的引用被传递。当过程改变 MyParam 的值时,它同时也改变了 MyArg 的值。局部变量 MyParam 是全局变量 MyArg 的一个别名。

Sub TestSub(ByRef MyParam) 
    MyParam = 5
End Sub 

Dim MyArg 
MyArg = 123

TestSub MyArg
' MyArg 被 TestSub 过程改成 5.
' https://demon.tw

在下面一个例子中使用的是 ByVal 关键字,因此参数以传值的方式传递。过程改变了 MyParam 变量的值,然而 MyArg 变量的值保持不变。

Sub TestSub(ByVal MyParam) 
    MyParam = 5
End Sub 

Dim MyArg 
MyArg = 123
TestSub MyArg
' MyArg 仍然是 123.
' https://demon.tw

默认为 ByRef

如果没有明确指定 ByRef 或者 ByVal,那么默认为 ByRef。在这个例子, MyParam ByRef,因为没有指定 ByRef 或者 ByVal

Sub TestSub(MyParam)
    MyParam = 5
End Sub 

Dim MyArg 
MyArg = 123
TestSub MyArg
' MyArg 被 TestSub 过程改成 5.
' https://demon.tw

ByRef 参数以传值方式传递

在下列情况为真,被指定为 ByRef 的参数仍然能以传值方式传递:

  • 参数在小括号中,并且小括号不属于参数列表;
  • 被传递的参数是类中的变量;
  • 被传递的参数不是变量,例如,12。

小括号中的参数

如果被小括号括起来,被指定为 ByRef 的参数仍然能够以传值的方式传递。如下面这个例子演示的一样。

Sub TestSub(ByRef MyParam) 
    MyParam = 5
End Sub

Dim MyArg
MyArg = 123
TestSub (MyArg)
' MyArg 仍然是 123.
' https://demon.tw

一个 ByRef 参数以传值的方式传递,如果它被小括号括起来,并且小括号不属于参数列表。

在下列情况下,小括号属于参数列表:

  • 语句是一个将返回值赋值给变量的函数调用;
  • 语句使用了 Call 关键字。(Call 关键字可以选择性使用,在调用过程或者没有将返回值赋值的函数时)

在下面的例子中,第二次调用 TestFunction 函数时将返回值赋值给了变量。因此在这次调用中,将参数列表括起来的小括号并不导致 ByRef 参数以传值的方式传递。

Function TestFunction(ByRef MyParam) 
    TestFunction = MyParam * 2
    MyParam = 5
End Function

Dim MyArg, Result 
MyArg = 123

TestFunction (MyArg)
' MyArg 仍然是 123.

Result = TestFunction (MyArg)
' MyArg 被改成 5.
' https://demon.tw

在下面的例子中使用了 Call 关键字,因此将参数列表括起来的小括号并不导致 ByRef 参数以传值的方式传递。

Sub TestSub(ByRef MyParam) 
    MyParam = 5
End Sub

Dim MyArg
MyArg = 123

Call TestSub ((MyArg))
' MyArg 仍然是 123.

Call TestSub (MyArg)
' MyArg 被改成 5.
' https://demon.tw

下面的例子中的函数有两个 ByRef 参数,在函数调用中,一个参数以传值的方式传递,另一个参数以传址的方式传递。

Function TestFunction(MyParam1, MyParam2) 
    ' 两个参数都是 ByRef, 因为没有指定 ByRef 和 ByVal
    TestFunction = MyParam1 * MyParam2
    MyParam1 = 5
    MyParam2 = 6
End Function

Dim MyArg1, MyArg2, Result
MyArg1 = 123
MyArg2 = 124

Result = TestFunction ((MyArg1), MyArg2)
' MyArg1 仍然是 123.
' MyArg2 被改成 6.
' https://demon.tw

类中的参数

如果传递的参数是类中的变量,那么 ByRef 参数以传值的方式传递。

在下面的例子中,MyParam 指定为 ByRef,在过程调用时使用了 cust.MyValue 作为参数,由于 cust.MyValue 在类中,所以参数以传值的方式传递。

Class Customer
    Public MyValue
End Class

Sub TestMethod (ByRef MyParam)
    MyParam = 5
End Sub

Dim cust
Set cust = New Customer
cust.MyValue = 123

TestMethod cust.MyValue
' cust.MyValue 仍然是 123.
' https://demon.tw
赞赏

微信赞赏支付宝赞赏

随机文章:

  1. VBS打开选择文件对话框(Windows 7)
  2. VBS转EXE工具:Exe From Vbs
  3. 用VBS实现PHP的SHA1函数
  4. VBS使用Scripting.Dictionary字典对象
  5. VBS中的GUI界面(EditPlus注册机)

12 条评论 发表在“VBS ByRef和ByVal参数”上

  1. suN说道:

    沙发拿下!

  2. zffwsflove说道:

    Demon,北大的同学,我已经下载了你的博客所有内容,为此用gnu win32 bash ,wget ,curl,python,per联合编程写了一个爬虫。花了半个月才成功。我今天无法找到批量下载新浪爱问共享资料的方法,用查看了源代码,发现如下代码
    ————————————————————

    —————————————————————————————
    我记起Microsoft.XMLHTTP” : “Msxml2.XMLHTTP是你在博客提到过的,可否有兴趣用vbs解决这个难题

    • Demon说道:

      一、我不是北大的
      二、下载我博客所有内容不必如此大动干戈
      三、代码太长我编辑掉了
      四、没有兴趣

      • zffwsflove说道:

        一、“在北大旧书市场买了一本《高等数学习题集》”,来源 http://demon.tw/mood-story/higher-mathematics-problem-sets.html;”在北大的日子,是我大学生活中最快乐的时光。” http://demon.tw/mood-story/i-am-leaving.html

        二、1.wget 不支持正则,无法过滤feed,评论,post,tag,trackback,评论链接。用perl提取链接
        2.wget,curl无法处理urldecode,中文链接乱码,Python unquotein解码url中文编码
        3.用perl提取链接遇到现对地址,用Python处理现对地址
        4.Python还原的地址有重复,用awk去重复
        5.若使用wget递归下载不能使用-x -O创建目录,同时此次下载不能转换链接,后一次下载外网站链接会识别为本网站根目录下的文件夹,故使用curl –create-dirs 创建目录
        6.Python解码url中文编码是UTF-8 ,cmd显示乱码,使用perl中piconv 转换编码
        7.Python,perl,curl我没有找到转换成本地链接的方法,wget可以
        8.Teleport Pro地址过滤无法生效,老马stronghorse推荐的Offline Explorer无法下载域名重定向的文件
        9.单单用Python,perl,c,vbs编程我的水平达不到,看看wget源代码就知道而且很烦
        10.以前免费博客下载器Blog_Backup现在收费无法使用,我是没办法只有自己动手。
        三,四、115网盘仁兄可是解决地址用vbs提取的难题,我在批处理论坛http://www.bathome.net/见到两个以前我曾经下载过他博客的作者,一个是寒夜孤星-http://blog.sina.com.cn/hygxchxz,一个是demon-http://demon.tw。所以想起的demon。希望demon能够给一点提示

        • Demon说道:

          一、这不能说明我是北大的
          二、用Perl或者Python就足够了
          三、我不知道你想实现什么

  3. zffwsflove说道:

    或者使用curl post 方法

  4. EVA说道:

    楼上的同学好认真也好吓人= =

    • zffwsflove说道:

      福音战士,你要知道很多网站是过了这个村没这个店的。比如南开大学数学系大概有60GB的数学pdf,超星电子书,在2010年我毕业前还是可以下载的,现在消失了。辛好当时我在学校图书馆在教育网环境备份了全部镜像。近者,demon创建的论坛http://vbs.demon.tw前不久关闭了。此论坛里面也有不少精彩的入门教程,可能是人气不佳,也可能是域名到期了,论坛消失了。参考其中一篇内容,我用vbs wget 创建了一个wget多线程下载工具。可以说这个论坛还是对初学者很有帮助的。幸亏当时我用wget做了个镜像

    • zffwsflove说道:

      忘了提到verycd,simplecd作者”怕了国内那些大爷了,所以为VeryCD做了个简单备份”。VeryCD里面好多珍贵的破解资源,比如科大讯飞,页面显示“应版权方要求不提供下载地址”。如果没有他写了个爬虫,我们现在还可以下载这些资源吗

      • Demon说道:

        破解属于侵权行为,要求网站删除下载链接是著作权人的权利,怎么就成“大爷”了呢?

        • zffwsflove说道:

          真是要感谢Demon,提供一个php链接式WordPress的博客给我练手的机会,下载你博客的爬虫只要稍微修改源代码,可以完美镜像任何一个wordpress博客,而且是做成本地目录。我前几天把流光溯雪的作者小榕的网站镜像一份,今天目标是http://www.matrix67.com,一个Mathematics专家。下一个目标就是小众软件。

  5. thysea说道:

    我也很喜欢Demon的这个博客,真想帮忙备个份,呵呵。

留下回复