PassingByVal / ByRef

dugdugdug

Active Member
Joined
May 11, 2012
Messages
342
We know the default to pass simple variable args is ByRef, so you never need to write ByRef, unless you want to be specific.

What about object variables?

According to this article by Chip Pearson, he states objects are ALWAYS passed ByRef:

Passing Variable ByRef And ByVal

Does he mean the DEFAULT is ByRef or does he mean it can ONLY be passed ByRef?

In a class, if you inserted a property using Insert - Procedure - Property, you get the following:

Code:
Public Let Property (ByVal MyVar) As SomeType

But some books omit the keyword ByVal, so are they he same, ie the default is ByVal? (If you added ByRef instead, does it make a difference)?

Similarly for the Set Property, if you added ByVal, or ByRef or omitted it altogether, what's the difference?

Thanks
 
Last edited:

Excel Facts

What did Pito Salas invent?
Pito Salas, working for Lotus, popularized what would become to be pivot tables. It was released as Lotus Improv in 1989.
The default of passing an object is ByRef. So, if you don't explicitly state it - it's byRef. But for clarity, you should never depend on the default or that another person reviewing your code will know. You should always state how you're passing it so there is no question about it. Yes, you can pass an object ByVal if you don't want it being changed.

As for pertaining to classes.. I can't imagine using ByRef... I'm trying to figure out why you'd want to pass byRef. And as to the default.. I honestly don't care because I would never skip out on stating it. To me, that's just bad coding...

It is possible that the Class procedures are explicitly ByVal because the default even in Classes is ByRef. I think when passing, whether regular sub or class - the default in VBA is ByRef.
 
Upvote 0
According to this article by Chip Pearson, he states objects are ALWAYS passed ByRef:

Actually, no he doesn't. He says they are passed by reference, not ByRef. Objects are always passed as a pointer, but when you pass ByVal, a copy of the original pointer is created and that is passed.
 
Upvote 0
ah - that clarifies the line where he says the actual object is not passed.
 
Upvote 0
So are we saying that the following three statements would yield DIFFERENT results:

Code:
Property Let MyVar(ByVal MyVa As SomeType)

Property Let MyVar(ByRef MyVa As SomeType)

Property Let MyVar(MyVa As SomeType)

and likewise:

Code:
Property Set MyVar(ByVal MyVa As SomeType)

Property Set MyVar(ByRef MyVa As SomeType)

Property Set MyVar(MyVa As SomeType)
 
Last edited:
Upvote 0
The last two of each are the same.
 
Upvote 0
Thanks for the clarification.

So if I understand it correctly, essentially it's like passing a simple variable, in that the default is ByRef but you CAN insist on passing ByVal.

My gut feeling (with regard to the Let Property within a class) is VBA "wants" you to pass ByVal because it automatically adds the ByVal keyword if you create a Let Property by choosing Insert -> Procedure -> Property.

Unfortunately you cannot do the same for the Set Property, (ie you cannot go to Insert -> Procedure -> Property to create the Set Property) so I have no idea what VBA "prefers" as the default.
 
Upvote 0
It doesn't really matter what VBA "wants" - you should always use what is appropriate. I can't really think of any occasion when a property procedure should take an object variable and make it point to a different object, so ByVal would be appropriate (just as for value types).
 
Upvote 0
In that case, books that omit the keyword ByVal are either sloppy or downright wrong?

Readers of the book, "VBA And Macros for MS Excel by Jelen and Syrstad" may recall the following:

"If EmpNormalHrs and EmpOverTimeHrs are going to be read-only, they must have values assigned somehow. Their values are a calculation of the EmpWeeklyHrs. Because EmpWeeklyHrs is going to be used to set the property values of these two object properties, it can no longer be a public variable. There are two Private variables. These private variables, NormalHrs and OverHrs, are used within the confines of the class module:"

Rich (BB code):
   Public EmpName As String
    Public EmpID As String
    Public EmpRate As Double
    Private NormalHrs As Double
    Private OverHrs As Double


"A Property Let procedure is created for EmpWeeklyHrs to break the hours down into normal and overtime hours:"

Rich (BB code):
Property Let EmpWeeklyHrs(Hrs As Double)
   NormalHrs = WorksheetFunction.Min(40, Hrs)
    OverHrs = WorksheetFunction.Max(0, Hrs - 40)
End Property


 
Last edited:
Upvote 0
Actually no. I should drink more coffee before I start posting - I had forgotten that property procedures always pass ByVal, even if you specify ByRef. So in fact all three of your code lines work identically.

Apologies for the confusion!
 
Upvote 0

Forum statistics

Threads
1,215,409
Messages
6,124,733
Members
449,185
Latest member
hopkinsr

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