by reference (1 Viewer)

conception_native_0123

Well-known member
Local time
Yesterday, 20:51
Joined
Mar 13, 2021
Messages
1,923
I was looking at byref but I do not understand what is. Can someone explain this? Thank you
 
Byref is the default declaration of a parameter when you did not specify.
meaning when the function/sub changes the value, the original variable is changed also.

Byval, the function/sub makes a Copy of the variable being passed.
so even if you change the value on the sub/function, the original value
is untouched.
 
when you say byref changes value of variable passed to it, does that mean that all of this is true?
Code:
sub g1
  dim s as string
  s = "value"
  call g2(byref s as string)
  's is now = "value2"?
end sub

sub g2(s2 as string)
  s2 = "value2"
end sub
 
you run:
Code:
Sub g1()
  Dim s As String
  s = "value"
  Call g2(s)
  's is now = "value2"?
  Debug.Print "new value of s", s

  Call g3(s)
  Debug.Print "new value of s", s
End Sub

Sub g2(s2 As String)
  s2 = "value2"
End Sub

sub g3(Byval s3 As String)
s3 = "will not change here"
end sub
 
Arnel...I have tried to apply a "real world" understanding of the difference between ByRef and ByVal on many occasions but never got there until your example.

Thanks for the quick tutorial!
 
I'll answer that same question from the "techie" viewpoint. When you talk about variables in other programming languages, you can talk about pointers to the desired variable. Passing "ByRef" passes a POINTER (address) of the desired value. Passing "ByVal" makes a COPY of the desired value.

If you use a pointer (ByRef), you are pointing to "the real thing" and changes you make through the pointer will change "the real thing" into "some other real thing."

If you use a copy (ByVal), "the real thing" is no longer involved. Like all the Las Vegas commercials, anything that happens to that copy in the subroutine STAYS in the subroutine. (And vanishes on exit from it.)

And as a side note, if you get involved in a 64-bit machine, those ByRef pointers are the things that require you to warn Access's VBA compiler to keep the pointers safe (i.e. PtrSafe declarations). On such machines, formal addresses are 64 bits long, whereas on older machines that are 32-bit boxes, addresses are 32 bits long. You have to warn Access because if you are using an external routine that was built on 32-bit architectures, you can still use it on a 64-bit machine. The data types (BYTE, WORD, LONG) are also on the 64-bit boxes, so a ByVal argument of those sizes will not go bad. But a ByRef might fail because the 32-bit routine's logic will expect short addresses, not long ones, so the compiler has to compensate for that in the call.

And the final part of this is that an Object variable in Access is ALWAYS some kind of pointer - an address - because it points to an auxiliary data structure elsewhere in memory that was built when you declared the object in the first place.
 
I have a bugbear about byref being the default.

It probably comes from learning pascal many years ago. I just feel byval should be the default, and byref should be a conscious decision. fwiw, I hardly ever change parameters/arguments within a sub, for this reason.
 
The problem with ByVal being a default is that for objects, you start replicating things that are expensive to replicate AND the "instantiators" for the object don't necessarily replicate the values in those structure.

I was fighting tooth-and-nail with Excel and was sloppy about ByVal vs ByRef. I can tell you that Excel app objects REALLY don't like ByVal for anything other than the simplest variables.

And for that matter, Word simply WILL NOT BEHAVE if you use ByVal for things that aren't true scalar variables. If it COULD be a structure, ByRef is the ONLY way for it to work right.
 
The problem with ByVal being a default is that for objects, you start replicating things that are expensive to replicate AND the "instantiators" for the object don't necessarily replicate the values in those structure.

I was fighting tooth-and-nail with Excel and was sloppy about ByVal vs ByRef. I can tell you that Excel app objects REALLY don't like ByVal for anything other than the simplest variables.

And for that matter, Word simply WILL NOT BEHAVE if you use ByVal for things that aren't true scalar variables. If it COULD be a structure, ByRef is the ONLY way for it to work right.
Sorry, but none of that is true. Can you show a single example of this or a reference supporting what you are saying? There is not replication of objects like you suggest. The truth in VBA is as follows. The difference in passing an object byref or by val is basically negligible.
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 an copy of the reference (address) of the object is passed.
This is the same in Access, Excel, or Word or any vba object.
 
I can tell you that Excel app objects REALLY don't like ByVal for anything other than the simplest variables.

why do you say this doc man? what does simplest mean? i run into very problems using vba in all the office programs because it seems to break really a lot for no reason.
 
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 an copy of the reference (address) of the object is passed.

so majp, are you saying docman is wrong? last sentence which i quote you on, show above is that byval passes an address of the object, not a copy of the object. so 2 people here say 2 different things. right?
 
so majp, are you saying docman is wrong? last sentence which i quote you on, show above is that byval passes an address of the object, not a copy of the object. so 2 people here say 2 different things. right?
Yes pretty much everything he said in that post is wrong. I can quote multiple sources. The one I provided is by Chip Pearson.
I am fully open to be proven wrong with an example where passing an object by val causes an issue. It really does nothing, but does not cause any issue.
 
By the way you could test this yourself. Pass a reference type (object) like a control by value. If it was true and you create a replica
The problem with ByVal being a default is that for objects, you start replicating things that are expensive to replicate AND the "instantiators" for the object don't necessarily replicate the values in those structure.
then you should be able to modify properties of the replica without effecting the original. But if you pass a reference to say a control by value and modify it (change it backcolor or value), I guarantee the original control changes.
 
@MajP,

The default for objects IS ByRef and if I misspoke on that point, I apologize - for that statement only. Perhaps I mistyped that line about "ByVal being a default" - it is not a default for VBA, and I am not sure what I was thinking then.

When you say "Sorry, but none of that is true" regarding my post #9, I tell you that YOU are wrong in this one. FLAT OUT WRONG. I have ONE and ONLY one statement in that post to which you could object, and I commented about that in the the paragraph above.

I stand by at least part of what I said in post #9, based on actual experience. Something is somehow different if you pass Objects ByVal vs. ByRef. Absolutely by personal experience I have seen Excel and Word BARF when you use ByVal passage when you should have been using ByRef.

Something is not right for an Application Object passed ByVal. Sometimes the effect can be innocuous. Sometimes it is a total train-wreck. The non-Access Application Object "knows" that the ByVal argument isn't the one that you are linked to with other things. The app detects it almost every time if, for example, you pass a range ByVal to something that was itself passed in to the same routine as ByRef. VBA for that object acts as though it is not instantiated correctly. You start getting the Excel catch-all error 1004, which is technically the "application-defined" error that crops up when the app thinks something is wrong but doesn't have a more specific error message for it.

In a Word-generating app, I fought with this for days until I got the ByVal/ByRef cases resolved - and for recursive code, this is EXTREMELY important because you need to be able to distinguish between an "instance" of a recursion variable vs. one that is shared among all recursive instances of that routine.

My genealogy project used both Excel AND Word to generate presentations and I can tell you, it is supremely important to get those right, in particular for the family tree generation, which involves recursion.

@conception_native_0123 - As to what I meant by "simple variables" - non-object variables like strings and integers and dates and currencies and SINGLE/DOUBLE variables - and Booleans (Y/N variables) are all simple, scalar variables. Anything that isn't any kind of application object for any application including but not limited to Access, Excel, Word, PowerPoint, Outlook, etc. That is what I mean by "simple variables." Some references I have seen will use the term "Value Variables" to mean simple variables that have a single value.
 
@conception_native_0123[/USER] - As to what I meant by "simple variables" - non-object variables like strings and integers and dates and currencies and SINGLE/DOUBLE variables - and Booleans (Y/N variables) are all simple, scalar variables. Anything that isn't any kind of application object for any application including but not limited to Access, Excel, Word, PowerPoint, Outlook, etc. That is what I mean by "simple variables." Some references I have seen will use the term "Value Variables" to mean simple variables that have a single value.

do you have an example of what you say below? not behave

And for that matter, Word simply WILL NOT BEHAVE if you use ByVal for things that aren't true scalar variables. If it COULD be a structure, ByRef is the ONLY way for it to work right.
 
@The_Doc_Man
No idea what you are saying. Can you make your point in less than 1000 words? But as i said everything you stated is wrong. If not prove it. Do not give an example that no one can see.z
 
@MajP - I can't easily give an example of the Excel case. The code in question was when I was working on a recursive routine in my genealogy project that involved Excel being called from that recursive routine and having a context to be preserved that, because of the recursion, HAD to be ByVal. I had to restructure the code completely because my attempts for the recursive calls were not working right. I trashed the failing code that didn't work and it was more than a year ago. Not sure I can recreate it from memory. Since you are going to argue, I will just drop that line for now.

However: Here is a link to a thread where the problem originally came up though it wasn't the first case.

@conception_native_0123 - Here is as short a summary as I can make: I was building something in an object passed in by reference, but because of recursion requirements I had to build a part of that object with something passed by value. Except that when the defining value was used, it appeared to work until the routine exited. The object I was building suddenly ceased to exist because the ByVal object gets deleted on subroutine exit. Basically, it was a case of App.X.Y.Z, and when the thing that defined Y (byVal) exited, Z ceased to exist. I had to rethink the entire method of doing that build in order to make it work.
 

Users who are viewing this thread

Back
Top Bottom