Parece que chamar uma função com um array como parâmetro não atualiza o array (chamada por ref) se um valor de retorno não for usado. Isso é um bug ou estou esquecendo de algo aqui? Uma pequena macro de teste com a saída gerada abaixo:
Sub Makro1()
'
' Makro1 Makro
'
' Kortkommando: Ctrl+t
'
Dim xyzArray() As Double
ReDim xyzArray(1 To 3)
xyzArray(1) = 1
xyzArray(2) = 2
xyzArray(3) = 3
Range("D2:F2").Value = xyzArray
TestFunction (xyzArray)
Range("D3:F3").Value = xyzArray
newXYZ = TestFunction(xyzArray)
Range("D4:F4").Value = xyzArray
TestSub xyzArray
Range("D5:F5").Value = xyzArray
TestFunction (xyzArray)
Range("D6:F6").Value = xyzArray
TestFunctionNoReturn (xyzArray)
Range("D7:F7").Value = xyzArray
End Sub
Private Function TestFunction(XYZ) As Double()
XYZ(1) = XYZ(1) + 1
XYZ(2) = XYZ(2) + 1
XYZ(3) = XYZ(3) + 1
TestFunction = XYZ
End Function
Private Sub TestSub(XYZ)
XYZ(1) = XYZ(1) + 1
XYZ(2) = XYZ(2) + 1
XYZ(3) = XYZ(3) + 1
End Sub
Private Function TestFunctionNoReturn(XYZ) As Double()
XYZ(1) = XYZ(1) + 1
XYZ(2) = XYZ(2) + 1
XYZ(3) = XYZ(3) + 1
End Function
Seu problema é um mal-entendido sobre quando usar parênteses em argumentos e quando não.
Se você chamar uma função e ler o resultado, precisará colocar o(s) argumento(s) entre parênteses:
Para chamar um sub, há 2 maneiras diferentes: Ou você omite os parênteses, ou usa o
Call
comando. Ambas as 2 linhas a seguir estão fazendo a mesma coisa:Não é bem sabido que você pode fazer isso também com funções (quando não estiver interessado no resultado):
Entretanto, os parênteses nas seguintes afirmações têm um significado completamente diferente:
Como você pode ver, agora há um espaço entre o nome da rotina e o argumento. Isso ocorre porque o parêntese sinaliza que você quer avaliar o termo dentro (similar a um termo como
3*(4+5)
) do parêntese antes que a chamada da rotina aconteça.O tempo de execução do VBA irá "avaliar"
xyzArray
. Não há nada a fazer, mas avaliar significa sempre que um novo espaço de memória é alocado para armazenar o resultado. Em um termo como3*(4+5)
este é óbvio, você precisa de um espaço em algum lugar para armazenar o resultado27
, mas o mesmo é verdade paraxyzArray
: Uma cópia dos dados é criada. Agora você passa a cópia por referência, esta cópia é modificada de dentro da sua rotina, mas após a chamada esta cópia desaparece, pois não é mais usada. O conteúdo original dexyzArray
permanece intocado , e esse é o seu problema.A sintaxe é algumas vezes (muito raramente) usada para evitar que um argumento que é passado por referência possa ser modificado pela rotina. No entanto, em quase todos os casos, isso é feito simplesmente por engano.
Para provar que os parênteses não são usados para definir os argumentos, tente o seguinte:
Isso gerará um erro do compilador porque o termo
(xyzArray, "Hello World")
não pode ser avaliado.