2017-06-02 116 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