VBA:使用带括号和不带括号调用Sub或Function的根本区别在哪里?

3

我遇到了一个问题,即将数组作为引用传递给子程序,但实际上数组并没有被修改。我设法修复了这个问题,但我想知道原因。

以下是示例:

Private Function fCountArray(ByRef arrayVar As Variant)
    arrayVar(0) = 333
End Function

Sub Test1()
      Dim changedArr As Variant
      Dim notChangedArr As Variant

    ' create 2 quick array
      changedArr = Array(1, 2, 33, 56, 76, 89, 10)
      notChangedArr = Array(1, 2, 33, 56, 76, 89, 10)

    'intest = Array(3, 1, 2)
     fCountArray (notChangedArr)
     Debug.Print notChangedArr(0) 'Print Out 1

     fCountArray changedArr
     Debug.Print changedArr(0) 'Print Out 333
End Sub

那么,fCountArray(notChangedArr)fCountArray(changedArr)之间的基本区别是什么?

为什么fCountArray(notChangedArr)不是通过引用传递的?

1个回答

4

好问题!我认为括号会导致一个计算,所以即使函数使用了ByRef参数,你实际上并没有传递调用过程中的本地数组,而是传递了它的副本。

为了避免歧义,我倾向于将所有不明确返回值的过程定义为Sub。我只使用Function来返回值/计算表达式,永远不会用来操作对象等。

所以我会这样做:

Sub fCountArray(ByRef arrayVar As Variant)
    arrayVar(0) = 333
End Sub

然后你可以简单地调用那个子程序,如下所示:
fCountArray notChangedArr

(由于至少需要一个必需参数,因此您可能不需要将其设置为 Private ,它不会在宏对话框中向用户公开。)

我还使用 String 进行了测试,并观察到了相同的行为。

更新

这似乎证实了我的怀疑,即传递的是计算表达式的副本/临时实例,而不是 ByRef 变量实例。

http://msdn.microsoft.com/en-us/library/office/gg251769(v=office.15).aspx

将参数置于其自己的一组括号中会强制将其作为表达式进行评估...评估的结果将放置在临时位置,并由过程接收对临时位置的引用。因此,原始的MyVar保留其值。


1
我想你的意思是End Sub。很好的答案。 - NYCdotNet
+1,这是我最喜欢的关于这个话题的讨论:http://dailydoseofexcel.com/archives/2012/05/01/quick-vba-tip-parentheses/ - Doug Glancy
@DavidZemens 很棒的回答。非常有帮助。谢谢。 - LeY

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