Let Property passing argument

tiredofit

Well-known Member
Joined
Apr 11, 2013
Messages
1,913
Office Version
  1. 365
  2. 2019
Platform
  1. Windows
I seem to be confused with regard to ByRef and ByVal.

Here, regardless of ByRef or ByVal, the result in the immediate window is 100. I though ByVal DOESN'T change things.

Code:
Option Explicit


    Dim pabc As Long


Sub Test()


    abc = 10
    
    Debug.Print pabc
    
End Sub


Property Let abc(ByVal a)


    a = 100
    
    pabc = a
    
End Property
 
Last edited:
Yes, exactly. That's how you can tell it is being passed ByVal no matter what you specify.

But why would Msgbox x show anything other than xxx?

It's never been changed or have I missed something?
 
Last edited:
Upvote 0

Excel Facts

What is the fastest way to copy a formula?
If A2:A50000 contain data. Enter a formula in B2. Select B2. Double-click the Fill Handle and Excel will shoot the formula down to B50000.
When you call this line:

Code:
aThing.Smith = x

it calls this:

Code:
Property Let Smith(ByRef a As String)
    a = "some other string"

where x is passed as the a variable. If x were passed ByRef, then the second line there would alter it.
 
Upvote 0
Sorry but I'm a bit thick on this one.

The Let Property expects an arg to be passed into it.

Code:
Property Let Smith(ByRef a As String)

We pass it xxx.

Then it is immediately changed in the next line to "someotherstring":

Code:
a = "some other string"

The following line assigns msmith to "someotherstring":

Code:
msSmith = a

so that when you retrieve it via the Get Property, it returns "someotherstring", as expected.

But where does x come into all this?

It's never changed, so the messagebox shows xxx, as expected.
 
Last edited:
Upvote 0
OK, I think I get your point.

We pass it x and this line ought to change it (because we're passing ByRef):

Code:
a = "someotherstring"

but doesn't.

Thanks
 
Last edited:
Upvote 0
Forget about properties for the moment.

Let's look at two subs, both take one argument and add 1 to it. But one passes it ByVal and the other ByRef


Code:
Sub One(ByVal Arg as Double)
    Arg = Arg + 1
    MsgBox "one: " & Arg
End Sub

Sub Other(ByRef Arg as Double)
    Arg = Arg +1
    MsgBox "other: " & Arg
End Sub

Lets look at two testing subs

Code:
Sub testOne()
   Dim x as Double
   x = 4.5

   MsgBox "before: " & x
   Call One (x)
   MsgBox "after: " & x
End Sub

Sub testOther()
   Dim x as Double
   x = 4.5

   MsgBox "before: " & x
   Call Other (x)
   MsgBox "after: " & x
End Sub
testOne (which uses ByVal) returns "start: 4.5" "one: 5.5" "after: 4.5"

testOther returns "start: 4.5" "other: 5.5" "after: 5.5"

When you pass an argument ByRef, anything that the called procedure does to the argument is also done to the variable in the calling routine.
"ByRef" doesn't pass the number 4.5, it passes "the variable x" so the first line of Other adds 1 to it.
"ByVal" doesn't pass the variable x, it calculates what x is at the moment and passes that value. (4.5 in this example)

That's the difference between ByVal and ByRef.
 
Upvote 0
Forget about properties for the moment.

Let's look at two subs, both take one argument and add 1 to it. But one passes it ByVal and the other ByRef


Code:
Sub One(ByVal Arg as Double)
    Arg = Arg + 1
    MsgBox "one: " & Arg
End Sub

Sub Other(ByRef Arg as Double)
    Arg = Arg +1
    MsgBox "other: " & Arg
End Sub

Lets look at two testing subs

Code:
Sub testOne()
   Dim x as Double
   x = 4.5

   MsgBox "before: " & x
   Call One (x)
   MsgBox "after: " & x
End Sub

Sub testOther()
   Dim x as Double
   x = 4.5

   MsgBox "before: " & x
   Call Other (x)
   MsgBox "after: " & x
End Sub
testOne (which uses ByVal) returns "start: 4.5" "one: 5.5" "after: 4.5"

testOther returns "start: 4.5" "other: 5.5" "after: 5.5"

When you pass an argument ByRef, anything that the called procedure does to the argument is also done to the variable in the calling routine.
"ByRef" doesn't pass the number 4.5, it passes "the variable x" so the first line of Other adds 1 to it.
"ByVal" doesn't pass the variable x, it calculates what x is at the moment and passes that value. (4.5 in this example)

That's the difference between ByVal and ByRef.

Sure, that's the textbook definition of ByRef and ByVal but as RoryA stated, when you throw Properties (Get, Let and Set) into the equation, Let and Set don't conform to the rule.
 
Upvote 0
We pass it x and this line ought to change it (because we're passing ByRef):
Code:
a = "someotherstring"
but doesn't.

Yes, that's exactly it.

It's not just that Property Let/Set default to using ByVal, but that they won't use anything else no matter what you specify. Mind you, I can't think of a good reason why a property Let/Set procedure should be able to affect the input value, so it shouldn't be a big deal.

Edit: On further testing, it is only the argument that you pass on the right hand side of the = that is always passed ByVal. If you have other arguments in a property Let/Set, they are passed as normal either ByRef or ByVal. So I've learned something new today!
 
Last edited:
Upvote 0
VBA seems to have a lot of exceptions, eg transposing arrays greater than 255 elements, passing args with () and without (), etc.
 
Upvote 0

Forum statistics

Threads
1,223,214
Messages
6,170,771
Members
452,353
Latest member
strainu

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