Passing Objects ByRef And ByVal
Objects are always passed by reference. The ByRef and ByVal modifers indicate how the reference is passed to the called procedure. When you pass an object type variable to a procedure, the reference or address to the object is passed -- you never really pass the object itself.
When you pass an object ByRef the reference is passed by reference and the called procedure can change the object to which that reference refers to. When an object is passed ByVal a copy of the reference (address) of the object is passed.
As is so often the case, an example will serve well to illustrate this
Sub CallingProcedure()
Dim Range1 As Range
Dim Range2 As Range
Set Range1 = Range("A1")
Set Range2 = Range("A2")
Range1.Value = 123
Range2.Value = 456
'''''''''''''''
' Debug Group 1
'''''''''''''''
Debug.Print "BEFORE CALL::Range1: " & Range1.Address(False, False) & " = " & Range1.Value
Debug.Print "BEFORE CALL::Range2: " & Range2.Address(False, False) & " = " & Range2.Value
CalledProcedure R1:=Range1, R2:=Range2
'''''''''''''''
' Debug Group 2
'''''''''''''''
Debug.Print "AFTER CALL::Range1: " & Range1.Address(False, False) & " = " & Range1.Value
Debug.Print "AFTER CALL::Range2: " & Range2.Address(False, False) & " = " & Range2.Value
End Sub
Sub CalledProcedure(ByRef R1 As Range, ByVal R2 As Range)
R1.Value = 321
R2.Value = 654
Set R1 = Range("A3")
Set R2 = Range("A4")
End Sub
In the CallingProcedure, the variable Range1 is set to Range("A1") and the variable Range2 is set to Range("A2"). Then CalledProcedure is called, passing ByRef R1 and ByVal R2. The CalledProcedure sets the values of these ranges to new values and then changes the ranges to which R1 and R2 refer. Since R1 was passed ByRef, the CalledProcedure can change the cell to which Range1 in CallingProcedure refers to. As is confirmed by the second group of Debug.Print statements, the variable Range1 now refers to (points to) Range("A3"), not Range("A1"). However, since R2 was passed ByVal, the CalledProcedure cannot change the range to which Range2 refers to in CallingProcedure.