Global Variables, Passing Arguments By Value (ByVal) or By Reference (ByRef)

In the example program illustrating Performing Computations, Data Types, Functions, variables are passed to a subroutine (function), where they are used in further computations. By default, variables are passed to subroutines and functions by value. In a sense, this means that the value of the variable is passed into the subroutine and not the variable itself. In practical terms, when the value of a variable that was passed into a subroutine by value is changed, then it will not change in the calling routine (which called the respective subroutine). To reiterate, this is the default "behavior" of arguments passed to subroutines or functions; you can also explicitly declare arguments as passed by value, via the ByVal statement (illustrated in the example program below).

If the subroutine or function should be able to change particular values (in the routine from which it was called), pass them by reference (use the ByRef statement). When a variable is passed into a subroutine or function by reference, then the variable itself is passed, and when the value of the variable inside the subroutine changes, then the value in the calling routine (which called the respective routine) changes as well. For example, consider the following program:

' Variable Global_Y is accessible and can be
 ' set (changed in all subroutines and functions
 ' in this program.
 Dim Global_Y As Integer
 Sub Main
 ' Variable Local_Y is accessible and can be
 ' set only in this subroutine (Main); however,
 ' if passed by reference, then the respective
 ' subroutine can also change this value.
 Dim Local_Y As Integer

Global_Y=0
 Local_Y=0

' Here we pass Local_Y to a subroutine
 ' by value; note that on return, Local_Y
 ' is unchanged, and equal to 0

SetByValue(Local_Y)
 MsgBox "Local_Y="+Str(Local_Y)

' Here we pass Local_Y to a subroutine
 ' by reference; note that on return,
 ' Local_Y is changed, and equal to 2.

SetByReference(Local_Y)
 MsgBox "Local_Y="+Str(Local_Y)

' Here we pass no arguments, and variable
 ' Global_Y is set inside the SetGlobalY
 ' routine

SetGlobalY
 MsgBox "Global_Y="+Str(Global_Y)

End Sub
 ' Y is passed (received) by value, so y
 ' can be changed inside this routine, but
 ' the results are not passed back to the
 ' calling routine (Sub Main in this case).
 Sub SetByValue(ByVal Y As Integer)

Y=1

End Sub
 ' Y is passed (received) by reference, y
 ' can be changed inside this routine, and
 ' the results are passed back to the
 ' calling routine (Sub Main in this case).
 Sub SetByReference(ByRef Y As Integer)

Y=2

End Sub
 ' This subroutine has no arguments, but sets
 ' the global variable Global_Y.
 Sub SetGlobalY

Global_Y=3

End Sub

To summarize, when arguments that are passed to a subroutine by value are changed inside the subroutine, the changes are not passed back to the calling routine. To change the values, variables must be declared in the header statement of the subroutine as ByRef, i.e., as passed by reference.

Passing arrays
Instead of individual variables, Visual Basic subroutines and functions can also be called with array arguments. When an array is passed to a subroutine or function, then the elements of the array can be modified in the respective subroutine or function, and the changes will persist (will be passed back) to the calling routine. In a sense, array arguments are always passed by reference. For example:

Sub Main

Dim X(1 To 10) As Integer

' Pass the integer array X to FillX

FillX X

' This message box should display 10

MsgBox Str(X(1))

End Sub
 ' This subroutine fills array X
 Sub FillX(X() As Integer)

Dim i As Integer
 For i=1 To 10

X(i)=11-i

Next i

End Sub

See also Statistica Visual Basic Syntax Reference - User-Defined Functions and Subroutines (Arguments).