When a value is passed ByVal
, the procedure receives a copy of the value.
Public Sub Test()
Dim foo As Long
foo = 42
DoSomething foo
Debug.Print foo
End Sub
Private Sub DoSomething(ByVal foo As Long)
foo = foo * 2
End Sub
Calling the above Test
procedure outputs 42. DoSomething
is given foo
and receives a copy of the value. The copy is multiplied by 2, and then discarded when the procedure exits; the caller's copy was never altered.
When a reference is passed ByVal
, the procedure receives a copy of the pointer.
Public Sub Test()
Dim foo As Collection
Set foo = New Collection
DoSomething foo
Debug.Print foo.Count
End Sub
Private Sub DoSomething(ByVal foo As Collection)
foo.Add 42
Set foo = Nothing
End Sub
Calling the above Test
procedure outputs 1. DoSomething
is given foo
and receives a copy of the pointer to the Collection
object. Because the foo
object variable in the Test
scope points to the same object, adding an item in DoSomething
adds the item to the same object. Because it's a copy of the pointer, setting its reference to Nothing
does not affect the caller's own copy.