2017-06-02 114 views
2

我已经将一个变量作为参数传递给VBA函数,但只引用了函数中的参数,而不是原始变量。看来原始变量正在被函数修改,这意味着它共享相同的地址空间?这里发生了什么,我如何防止它发生?传递给函数的VBA变量被修改

下面是函数:(单位,数十,数百,数千的全局整型变量)

Function Components(qty As Integer, stringSize As Integer) 

If qty < stringSize Then 
    units = qty 

ElseIf qty >= stringSize * 100 Then 
    thousands = qty \ (stringSize * 100) 
    qty = qty - (thousands * stringSize * 100) 
    Components qty, stringSize 


ElseIf qty >= stringSize * 10 Then 
    hundreds = qty \ (stringSize * 10) 
    qty = qty - (hundreds * stringSize * 10) 
    Components qty, stringSize 

ElseIf qty >= stringSize Then 
    tens = qty \ (stringSize) 
    qty = qty - (tens * stringSize) 
    Components qty, stringSize 

End If 

End Function 

我这样称呼它使用其他功能

Components charQty, 26 

其中charQty = 565时,作为参数传递给组件,并且在组件完成后charQty = 19。我通过在函数调用之前和之后立即打印值来确定这一点。

我对VBA相当陌生。任何帮助将不胜感激。

+0

的参数隐式[通过由参考](VBA中的“ByRef”)(https://stackoverflow.com/documentation/vba/7363/passing-arguments-byref-or-byval/24427/byref#t=201706020439138540139)。考虑[按值传递](https://stackoverflow.com/documentation/vba/7363/passing-arguments-byref-or-byval/28511/byval#t=201706020440066200781)。 –

回答

5

与大多数其他语言不同,VBA中参数的默认行为是通过ByRef - 这意味着会传递对原始对象/变量的引用,因此原始对象/变量可以被调用的函数修改。

另一种方法是使用ByVal,在这种情况下,该值的临时副本被传递给被调用的函数。因为这是暂时的,所以当功能结束时,所做的任何更改都会丢失。

Function Components(ByVal qty As Integer, ByVal stringSize As Integer) 

有一两件事要小心......因为对象是通过对象的引用总是提到,该引用的临时副本仍然会指向原来的对象。因此,即使您指定ByVal,几乎*就好像一个对象正在通过ByRef一样。 (*除了如果功能是执行该参数的一些其它物体的Set,原始对象仍然会被指向到所述功能的外部。)

MSDN documentation

+1

除非被传递的变量是一个对象。然后,'ByVal'变量只是引用变量的一个副本,但它指向* same *对象。也值得指出的是,大多数其他语言默认为By By而不是By Reference。 – ThunderFrame

+0

@ThunderFrame - 我试图包含一些关于对象的东西,但是这很容易让人感到困惑。 (如果您认为需要进一步更改,请随时编辑答案 - 当我开始详细描述这类内容时,通常最终会让人感到困惑。) – YowE3K