Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ByVal vs ByRef VBA

Tags:

excel

vba

I've tried to attempt something that was answered by JaredPar ByRef vs ByVal Clarification

ByVal in VB.NET means that a copy of the provided value will be sent to the function. For value types (Integer, Single, etc.) this will provide a shallow copy of the value. With larger types this can be inefficient. For reference types though (String, class instances) a copy of the reference is passed. Because a copy is passed in mutations to the parameter via = it won't be visible to the calling function.

ByRef in VB.NET means that a reference to the original value will be sent to the function (1). It's almost like the original value is being directly used within the function. Operations like = will affect the original value and be immediately visible in the calling function.

And I've tried to test it with the following code and I can't seem to get it to work use the ByRef to change the value of the cell to 0 if it's 1

Here's my below code that I'm testing with, what am I doing wrong? The value of Range("A1") is still 1

Sub test1()

    Dim trythis As Boolean

    trythis = False

    If (Sheets("TESTING").Range("A1").value = 1) Then
        testingRoutine (trythis)
        If (trythis) Then
            Debug.Print "Value changed to 0"
            Sheets("TESTING").Range("A1").value = 0
        End If
    End If

End Sub

Private Function testingRoutine(ByRef trythis As Boolean)

    Debug.Print "Ran Function"
    trythis = True

End Function
like image 257
Maldred Avatar asked Oct 26 '17 17:10

Maldred


People also ask

Is ByRef faster than ByVal?

If value types are large, passing ByRef may be much faster. Note that even very large value types (thousands of bytes) can be very performant if one can avoid passing them by value or copying them unnecessarily. With a large Byte() array, ByVal is faster than ByRef , but it's also negligible.

What is the difference between ByVal and ByRef and which is default?

ByRef = You give your friend your term paper (the original) he marks it up and can return it to you. ByVal = You give him a copy of the term paper and he give you back his changes but you have to put them back in your original yourself.

What is ByVal in Excel VBA?

ByVal prevents the code in the procedures from changing the underlying value of the reference argument, c1 , but does not protect the accessible fields and properties of c1 .

What is ByRef in VBA?

ByRef in VBA is a function called as by reference where we provide a reference to any arguments in our code. When we make custom functions and want to use the value of any variable defined earlier before the function, we use the ByRef function. The syntax is simple as Function-Name(ByRef Variable as Data Type).


2 Answers

VB subroutines don't require braces around the argument list. However, if you pass a single argument and you enclose that in braces, you are passing an expression . Expressions cannot be passed by reference. They are evaluated and their result is passed. Therefore you must remove the braces in the call testingRoutine (trythis) and write testingRoutine trythis

Note: if you call a function without using its return value, it must be written as a procedure call (without braces around the argument list). As an example:

myVal = myFunction (trythis)   ' trythis will be passed by reference
myFunction (trythis)           ' trythis will be seen as an expression
myFunction trythis             ' trythis will be passed by reference

myVal = mySub (trythis)        ' invalid: mySub is not a function
mySub (trythis)                ' trythis will be seen as an expression
mySub trythis                  ' trythis will be passed by reference

Of course, the problem will be clear immediately when a function or sub has more than one parameter because a comma cannot appear in an expression.

like image 174
Paul Ogilvie Avatar answered Oct 13 '22 03:10

Paul Ogilvie


Change this:

testingRoutine (trythis)

to this:

testingRoutine trythis

then try it.

Also, look what happens if I change it to this, where the function is being used as a function (returning something)

Sub test1()

    Dim trythis As Boolean
    Dim testit As Boolean

    trythis = False

    If (Sheets("Sheet1").Range("A1").Value = 1) Then
        testit = testingRoutine(trythis)
        If (trythis) Then
            Debug.Print "Value changed to 0"
            Sheets("TESTING").Range("A1").Value = 0
        End If
    End If

End Sub

Private Function testingRoutine(ByRef trythis As Boolean) As Boolean

    Debug.Print "Ran Function"
    trythis = True

End Function
like image 26
braX Avatar answered Oct 13 '22 02:10

braX