SomeSub (Me.somecontrol)
In my experience in Access, declaring an Object or Array as ByVal is ignored because they are always ByRef.
Sub tryArray()
Dim r(2, 10) As Integer
Dim x As Long
Dim s As String
r(1, 1) = 1
r(1, 2) = 2
r(1, 3) = 3
doublearray r
showArray r, "Original after processing"
End Sub
Function doublearray(ByVal r)
Dim x As Long
For x = 0 To 10
r(1, x) = r(1, x) * 2
Next
showArray r, "Byval Function"
End Function
Sub showArray(r, description As String)
Dim s As String
Dim x As Long
s = description & vbCrLf & vbCrLf
For x = 0 To 10
s = s & r(1, x) & vbCrLf
Next
MsgBox s
End Sub
what you mean that you hardly ever change arguments? chage what?
function square (x as long) as long
square = x * x
end function
function square (x as long)
'x is by passed ref, so you can change it directly
x = x * x
end function
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.Passing Variable ByRef And ByVal
www.cpearson.com
We are confusing Value types and Reference Types. The @The_Doc_Man specifically called out objects and no mention of Arrays. Apples and Oranges. In VBA arrays are Value Types. So yes they are copied, that is not the same as reference types (objects).
![]()
Togel Hongkong, Data Keluaran HK, Pengeluaran HK, Togel Hari Ini
Togel hongkong sudah menghadirkan data hk berisi hasil pengeluaran hk dan keluaran hk hari ini yang wajib disaksikan oleh pemain togel hari inibytecomb.com
Passing Arrays
Arrays are always passed by reference. You will receive a compiler error if you attempt to pass an array by value. See Passing And Returning Arrays With Functions for details about passing and returning array for VBA procedures.
Public Sub TestByVal()
Dim Arr(2) As Integer
Arr(0) = 10
Arr(1) = 20
Arr(2) = 30
AddArr Arr, 5
Debug.Print "byval"
PrintArr Arr
AddArr2 Arr, 5
Debug.Print "by ref"
PrintArr Arr
End Sub
Public Sub PrintArr(Arr() As Integer)
Dim i As Integer
For i = 0 To UBound(Arr)
Debug.Print Arr(i)
Next i
End Sub
Public Sub AddArr(ByVal Arr, val As Integer)
Dim i As Integer
For i = 0 To UBound(Arr)
Arr(i) = Arr(i) + val
Next i
End Sub
Public Sub AddArr2(Arr() As Integer, val As Integer)
Dim i As Integer
For i = 0 To UBound(Arr)
Arr(i) = Arr(i) + val
Next i
End Sub
Public Sub AddArr2(Byval Arr() As Integer, val As Integer)
Dim i As Integer
For i = 0 To UBound(Arr)
Arr(i) = Arr(i) + val
Next i
End Sub
I agree with you, but that is not the default. As @gemma-the-husky pointed out you have to force yourself to specify byval (or be careful) so as not to change the value inadvertently in the called procedure.Simply put, I never want a variable passed into a procedure to actually change its value and then continue its lifespan somewhere else. I use a regular function, then assign the result of the function back to some variable in the calling procedure
Gotcha. Ok, then my erroneous implication stands corrected. Thanks for clarifying.@Isaac
What you said is actually contradictory
I agree with you, but that is not the default. As @gemma-the-husky pointed out you have to force yourself to specify byval (or be careful) so as not to change the value inadvertently in the called procedure.
The good news is that vb.net defaults to byval. I guessed they learned, because as pointed out calling a reference type byval really has not impact since you are just copying a pointer.
If I want to test something and get a return value based on logic, I use a regular function, then assign the result of the function back to some variable in the calling procedure. I just don't get why there would be a whole lot of usefulness in doing the other.
This is one of those areas where if you do not see it, you will drive yourself crazy trying to debug. It does not happen that often, but when it does it can be hard to see. Here is a silly example.This, then is a situation where I should do a better job of following my own oft-given advice, which is not to overly rely on 'defaults' but be explicit - if I had followed this advice, which helps people better understand what is happening in their code, I myself would have better understood what was happening in my code. LOL
Public Function BadCheck(dtmDate As Date, daysOut) As Boolean
dtmDate = dtmDate - daysOut
BadCheck = (dtmDate = Date)
End Function
Public Sub TestBadFunction()
Dim OriginalDate As Date
OriginalDate = #4/23/2021#
Debug.Print "Original date " & OriginalDate
Debug.Print "Is the date two days out? " & BadCheck(OriginalDate, 2)
'Debug.Print "Original date " & OriginalDate
Debug.Print "Is the date two days out? " & BadCheck(OriginalDate, 2)
End Sub
Nearly 4 years later...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.
Like I said previously, the Default, implicitly, is Byref.why in the world would you send an integer as an address of an integer, in order to refer to it?
Public function fnX(x As Integer)
..
..
End Function
The compiler "determines" nothing of the kind. Why would it? It's your job to define the function and with it the types and passing mechanisms for its arguments. - Which is the default behavior I don't know. I acquired the habit of explicitly stating the passing mechanism in the method declaration so I do not need to care about the default.Just for the sake of the argument, as far as I remember C language, when passing an argument the value is copied, and the compiler determines weather the value is of an address (pointer, reference) or a 'regular' value.
You always pass the address of an object. If you want to pass a copy of an object, you must create the copy and then pass the address of the copy.When sending an object you send by default an address (pointer, reference), unless you want to send a copy,
Here is a prime example where this construct is useful, because there is really no other way to do it.why in the world would you send an integer as an address of an integer, in order to refer to it?
Private Sub SomeObject_BeforeUpdate(Cancel As Integer)
End Sub