Passing Arguments by Reference and by Value

In some procedures, when you pass arguments as variables, Visual Basic can suddenly change the value of the variables. To ensure that the called function procedure does not alter the value of the passed arguments, you should precede the name of the argument in the function's declaration line with the keyword ByVal. Let's look at the following example.

1. Add a new module to the MyFunctions (Chap04.xls) project and change the module's name to Sample4.

2. Activate the Sample4 module and type the procedures shown below:

Sub ThreeNumbers()

Dim num1 As Integer, num2 As Integer, num3 As Integer num1 = 10 num2 = 20 num3 = 30

MsgBox MyAverage(num1,num2,num3) MsgBox num1 MsgBox num2 MsgBox num3 End Sub

Function MyAverage(ByVal num1, ByVal num2, ByVal num3) num1 = num1 + 1

To prevent the function from altering values of arguments, use the keyword ByVal before the arguments' names.

The ThreeNumbers subroutine assigns values to three variables and then calls the MyAverage function to calculate and return the average of the numbers stored in these variables. The function's arguments are the names of variables num1, num2, and num3. Notice that all variable names are preceded with the keyword ByVal. Also, notice that prior to the calculation of the average, the MyAverage function changes the value of the num1 variable. Inside the function procedure, the num1 variable equals 11 (10 + 1). Therefore, when the function passes the calculated average to the ThreeNumbers procedure, the MsgBox function displays the result as 20.3333333333333 and not 20, as expected. The next three functions show the contents of each of the variables. The values stored in these variables are the same as the original values assigned to them—10, 20, and 30.

What will happen if you omit the keyword ByVal in front of the num1 argument in the MyAverage function's declaration line? The function's result will still be the same, but the contents of the num1 variable displayed by MsgBox num1 is now 11. The MyAverage function has not only returned the unexpected result (20.3333333333333, instead of 20) but has also modified the original data stored in the num1 variable. To prevent Visual Basic from permanently changing the values supplied to the function, use the ByVal keyword.

Tip 4-9: Know Your Keywords: ByRef and ByVal

Because any of the variables passed to a function procedure (or a subroutine) can be changed by the receiving procedure, it is important to know how to protect the original value of a variable. Visual Basic has two keywords that give or deny permission to change the contents of a variable—ByRef and ByVal.

By default, Visual Basic passes information into a function procedure (or a subroutine) by reference (ByRef keyword), referring to the original data specified in the function's argument at the time the function is called. So, if the function alters the value of the argument, the original value is changed. You will get this result if you omit the ByVal keyword in front of the num1

argument in the MyAverage function's declaration line. If you want the function procedure to change the original value, you don't need to explicitly insert the ByRef keyword, since passed variables default to ByRef.

When you use the ByVal keyword in front of an argument name, Visual Basic passes the argument by value. It means that Visual Basic makes a copy of the original data. This copy is then passed to a function. If the function changes the value of an argument passed by value, the original data does not change—only the copy changes. That's why when the MyAverage function changed the value of the num1 argument, the original value of the num1 variable remained the same.

0 0

Post a comment