Passing Objects ByRef And ByVal

alexba

Board Regular
Joined
Nov 20, 2015
Messages
88
Hi Everyone

I have got this codes as below from the web. but I don't quite understand it. can someone explain please?
i thought the output should be:

BEFORE CALL::Range1: A1 = 123
BEFORE CALL::Range2: A2 = 456
AFTER CALL::Range1: A3 = 321
AFTER CALL::Range2: A2 = 456


my understanding is Byref the output going to change but ByVal the output stay the same. but i am wrong.

the correct output is as below.





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



correct output :

BEFORE CALL::Range1: A1 = 123
BEFORE CALL::Range2: A2 = 456
AFTER CALL::Range1: A3 =
AFTER CALL::Range2: A2 = 654



Kind regards

Alex
 

Excel Facts

Excel Joke
Why can't spreadsheets drive cars? They crash too often!
Greetings Alex,

Just to suggest: It is awfully hard to read the code quickly without using the code tags like:

[code=rich]'Your code goes here...[/code]

Anyways, I am heading out, so if this doesn't make sense, hopefully you will get a more articulate answer - but in gist:

You are passing Ranges, which are Objects. This is different than passing a simple variable such as a String or Numeric value. When passing Objects, what you are really passing is a Pointer to the Object in memory. So when you pass the pointer ByVal, the copy of the Pointer is lost on the way back and the original Pointer still exists. When you passed the Pointer ByRef, the Pointer was changed and the change came back to the calling procedure.

Does that make sense?

Mark
 
Upvote 0
When you pass an object ByVal, you pass a copy of the pointer to the object. That means you can still affect all its properties and call all its methods. The only thing you can't do is change which object the original pointer refers to. That's why the last output line doesn't refer to A4, but does show the changed value in A2.
 
Upvote 0
Greetings Alex,

Just to suggest: It is awfully hard to read the code quickly without using the code tags like:

[code=rich]'Your code goes here...[/code]

Anyways, I am heading out, so if this doesn't make sense, hopefully you will get a more articulate answer - but in gist:

You are passing Ranges, which are Objects. This is different than passing a simple variable such as a String or Numeric value. When passing Objects, what you are really passing is a Pointer to the Object in memory. So when you pass the pointer ByVal, the copy of the Pointer is lost on the way back and the original Pointer still exists. When you passed the Pointer ByRef, the Pointer was changed and the change came back to the calling procedure.

Does that make sense?

Mark


Hi Mark

Thanks for quick answer. I will follow your suggestion to post the code properly. as I am still new to VBA. Can you please answer my question below?


you said
When you passed the Pointer ByRef, the Pointer was changed and the change came back to the calling procedure.[


why the output is
AFTER CALL::Range1: A3 =

is there a value 123 or 321 to be assigned to A3.


when you pass the pointer ByVal, the copy of the Pointer is lost on the way back and the original Pointer still exists.


why the output is

AFTER CALL::Range2: A2 = 654 not 456


Kind regards

Alex

 
Upvote 0
Hi,

I have just started VBA and I don't have IT background . seems to me it is quite hard to understanding passinng the Pointer ByRef or ByVal . can anyone explain

When you passed the Pointer ByRef, the Pointer was changed and the change came back to the calling procedure.[




why the output is
AFTER CALL::Range1: A3 =

is there a value 123 or 321 to be assigned to A3.



when you pass the pointer ByVal, the copy of the Pointer is lost on the way back and the original Pointer still exists.




why the output is

AFTER CALL::Range2: A2 = 654 not 456
When you passed the Pointer ByRef, the Pointer was changed and the change came back to the calling procedure.[


Kind regards

Alex

 
Upvote 0
Slightly simplified: When you pass an object to a routine, you actually pass a variable containing the memory address where the object is located.

If you pass ByRef then, as with other variables, the called routine can change the variable to point to another memory location (i.e. a different object) and that change is reflected in the calling procedure; if you pass ByVal, you pass a copy of the variable so any changes made to the variable (i.e. assigning a different memory address) by the called routine are not reflected in the calling procedure.

That is the only difference between the two. Passing either ByVal or ByRef, the called routine has the memory address of the object and can call its properties and methods. So either way, the called routine can affect the object in question - changing the value of a cell for instance.

You can think of it like this:

There's a set of pigeonholes (memory locations) which have different things in them. You can't change the locations of those things.

I have the location of an object written on a piece of paper.

Now, in order to get you to do something to an object, I have to tell you where it is.

If I pass it ByRef, I give you my piece of paper. That allows you to find the object and do whatever is needed to it. It also allows you to change the location written on the paper and give it back to me. So I could now have the location of a different object.

If I pass it ByVal, I copy the piece of paper and hand you the copy. You can still find the object and do whatever is necessary to it. You can even change the location written on the copy, but I never ask for it back as I still have my original paper, with the location of the original object.

Does that help?
 
Last edited:
Upvote 0
Slightly simplified: When you pass an object to a routine, you actually pass a variable containing the memory address where the object is located.

If you pass ByRef then, as with other variables, the called routine can change the variable to point to another memory location (i.e. a different object) and that change is reflected in the calling procedure; if you pass ByVal, you pass a copy of the variable so any changes made to the variable (i.e. assigning a different memory address) by the called routine are not reflected in the calling procedure.

That is the only difference between the two. Passing either ByVal or ByRef, the called routine has the memory address of the object and can call its properties and methods. So either way, the called routine can affect the object in question - changing the value of a cell for instance.

You can think of it like this:

There's a set of pigeonholes (memory locations) which have different things in them. You can't change the locations of those things.

I have the location of an object written on a piece of paper.

Now, in order to get you to do something to an object, I have to tell you where it is.

If I pass it ByRef, I give you my piece of paper. That allows you to find the object and do whatever is needed to it. It also allows you to change the location written on the paper and give it back to me. So I could now have the location of a different object.

If I pass it ByVal, I copy the piece of paper and hand you the copy. You can still find the object and do whatever is necessary to it. You can even change the location written on the copy, but I never ask for it back as I still have my original paper, with the location of the original object.

Does that help?


Hi,

This is best explanation I have had .

Appreciate your help very much. you have a great day! :)


Kind regards

Alex
 
Upvote 0

Forum statistics

Threads
1,215,425
Messages
6,124,825
Members
449,190
Latest member
rscraig11

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top