VBA В чем основная разница между вызовом Sub или Function с круглыми скобками или без них?

У меня была проблема с передачей массива в Sub By Reference, но массив фактически не изменялся. Мне удалось это исправить, но я хочу знать, почему.

Вот пример.

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 updatedArr

Почему fCountArray (notChangedArr) не передается по ссылке?

1 ответ

Решение

Отличный вопрос! Я считаю, что круглые скобки вызывают оценку, поэтому даже если функция принимает аргумент ByRefвы на самом деле не передаете ему массив, локальный для вызывающей процедуры, вы, по сути, передаете его копию.

Чтобы избежать двусмысленности, я склонен делать Sub все процедуры, которые явно не возвращают значение. И я пользуюсь Function только чтобы вернуть значения / оценить выражение, никогда не манипулировать объектами и т. д.

Так что я бы сделал:

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

И тогда вы можете просто назвать этот саб, как:

fCountArray notChangedArr

(Возможно, вам не нужно делать это Private, поскольку он принимает хотя бы один обязательный аргумент, он не будет отображаться пользователю в диалоге макросов.)

Я проверил это также с String и наблюдать за тем же поведением.

Обновить

Это, кажется, подтверждает мое подозрение, что экземпляр copy / temp оцененного выражения передан, а не ByRef экземпляр переменной.

http://msdn.microsoft.com/en-us/library/office/gg251769%28v=office.15%29.aspx

Помещение аргумента в его собственный набор скобок вынуждает его оценивать как выражение... Результат оценки помещается во временное местоположение, и процедура получает ссылку на временное местоположение. Таким образом, оригинальный MyVar сохраняет свою ценность.

Другие вопросы по тегам