Variables

ByRef and ByVal

When getting the value of a variable from a procedure or function parameter you have two ways to request it. Either you can request for it to be passed ByRef (default), or ByVal.

Passing ByVal
Private Sub TestSub(ByVal strPath As String)

Passing ByRef
Private Sub TestSub(ByRef strPath As String) ' or just
Private Sub TestSub(strPath As String)

When you pass ByVal, Visual Basic passes a copy of the variable to the procedure. This way the procedure gets the value, but any changes it makes will not affect the original variable. 

When you pass ByRef, Visual Basic passes a pointer to the procedure. This is a reference so that the procedure knows where to find the variable in the memory. Any changes the procedure makes to this variable will effect the original one, as they are the same thing, however the variable does not need to be declared as public if you were wanting the procedure to access the variabl any other way. The following example shows the differences:

Sub Form_Load()
    Dim strTest As String
    '// fill the variable
    strTest = "Hello from Form_Load"
    '// call the procedure
    Call TestSub(strTest)
    '// display a message box containing the value of strTest
    Msgbox strTest
End Sub

'// TestSub procedure when passing ByVal
Sub TestSub(ByVal strString As String)
    strString = "Hello from TestSub"
    '// when control returns to Form_Load, no changes will have
    '// been made to strTest
End Sub

'// TestSub procedure when passing ByRef
Sub TestSub(ByRef strString As String)
    strString = "Hello from TestSub"
    '// when control returns to Form_Load, the value of
    '// strTest will have changed to Hello from TestSub
End Sub

Note that when you are passing a variable ByRef, it must be declared as a specific datatype (ie string). Otherwise, VB cannot pass a pointer to it. If you do not do this, you will get a compile error:

ByRef Argument Type Mismatch.

This does not occur when passing ByVal. For example, the code below will produce a compile error when you press Command1:

Private Function TestFunction(ByRef sString As String)
    sString = sString & vbCrLf
End Function

Private Sub Command1_Click()
    Dim sTestString
    TestFunction sTestString
End Sub

while, the code below would not, as you have explicitly declared sTestString As String.

Private Function TestFunction(ByRef sString As String)
    sString = sString & vbCrLf
End Function

Private Sub Command2_Click()
    Dim sTestString As String
    TestFunction sTestString
End Sub

You might also like...

Comments

About the author

James Crowley

James Crowley United Kingdom

James first started this website when learning Visual Basic back in 1999 whilst studying his GCSEs. The site grew steadily over the years while being run as a hobby - to a regular monthly audien...

Interested in writing for us? Find out more.

Contribute

Why not write for us? Or you could submit an event or a user group in your area. Alternatively just tell us what you think!

Our tools

We've got automatic conversion tools to convert C# to VB.NET, VB.NET to C#. Also you can compress javascript and compress css and generate sql connection strings.

“In order to understand recursion, one must first understand recursion.”