Visual Basic Functions and Sub-Procedures

Welcome back to our exploration of the wonderful world that’s called Visual Basic. Last time, we looked at arrays, and as promised, this week we’ll check out functions and sub procedures. First of all, let’s take a look at sub procedures.

Sub procedures

The definition of a sub procedures is a set of instructions that can be performed as a unit. (Those of you who remember DOS, think of it as a Batch-file. I.e. a list of commands to be executed after one another). This might surprise you, but you’ve already seen (and used) sub procedures.

Remember the article where we discussed Events? If we were to define what would happen if a user clicked our button, we’d code the button’s click event. The click-event is being handled by a sub procedure. Hence the fact your code will show this:

Private Sub cmdPlus_Click()
txtInput.Text = txtInput.Text + Val(txtInput.Text)
End Sub

Notice how it says ‘sub’? That’s because the event is handled by the cmdPlus_Click sub procedure. The event itself is when the user clicks the button. The sub procedure stores the code that makes sure something happens.

You’re not limited to using the sub procedures used by the events of the controls you use. In fact, you can create your very own sub procedures like so:

[Private / Public] [Static] Sub subname [(Variables)]

Everything between the square brackets is optional. The only thing really required to declare a sub procedure is the ‘Sub’ keyword, and the name for the sub.

We’ve seen Public and Static before, but we haven’t seen Private. Private (in relation to sub procedures) usually means that the sub procedure is associated with an event. It’s actually a little more tricky than that, but for now, let’s leave it at that. We’ll mostly be using the Private way for declaring sub procedures for now.

Sub procedures do not return any values. Instead, they just run silently on the background, doing whatever you wanted them to do. An example could be writing a sub routine to loop through a text file and replace certain words with other words.

Creating this sub procedure would be done like this:

Private Sub ReplaceWords(strTextFile As String, strWordToReplace As String)

As you see, we demand two variables in this example. The first being the text file to use and the second being the string to search for. We declare the variable types as well, in order to save a few bytes of memory.

A way to run this sub procedure would be this:

Call ReplaceWords (“C:\test.txt”, “word”)

Functions

Functions are almost identical to Sub procedures, but differ in the fact that they do return a value.

Functions are declared like this:

[Private / Public] [Static] Sub subname [Variables] [As Type]

As an example, let’s write a function that accepts a value in Fahrenheit, and converts it to Celsius. The calculation for that would be Celsius = 5 * (Fahrenheit – 32) / 9:

Private Function Fah2Cel(ByVal Fahrenheit As Double) As Double
Fah2Cel = 5 * (Fahrenheit – 32) / 9
End Function

We would call this procedure the following way:

txtCelsius.Text = Fah2Cel(Val(txtFahrenheit))

As you can see, we assign the value of whatever is in our Fahrenheit TextBox as a parameter to the Fah2Cel function. The function then assigns the value of the converted Fahrenheit value to itself. finally, we assign that returned value to the TextBox txtCelsius.

Passing arguments

All right, so we saw we can pass parameters to functions and sub procedures. This can be done in two ways: By Value, or by Reference.

By Value means that a copy of the actual variable is passed. The variable itself will not change within the procedure or function.

By Reference means that the memory-address itself is passed. The variable will change if it is altered within the procedure or function it’s being passed to. By Reference is the VB standard.

Create a new standard Exe project. Now double click the form. This brings us into the Form_Load() sub procedure. We start by declaring two integer variables:

Dim intValue as Integer
Dim intReference as Integer

Next, we assign the two variables a value:

intValue = 10
intreference = 100

We’ll create a new procedure now:

Private sub AddTen (ByVal int1 As integer, ByRef int2 As Integer)
int1 = int1 + int1
int2 = int2 + int2

To show the values in between, we’re going to call in help from a debugging tool within VB (I’ll discuss debugging in a few weeks), the Immediate Window. We can use the Immediate window (among other things) to display values while an application is running. Type the following code within the procedure:

Debug.Print “Values of int1 in procedure: “; int1
Debug.Print “Values of int2 in procedure: “; int2

This will show us what the value of the two integers is after we multiplied the numbers within the procedure. Back to the Form_Load sub. Under the part where you set their values, insert the following code:

Call AddTen(intValue, intReference)

Debug.Print “Values of intValue after procedure: “; intValue
Debug.Print “Values of intReference after procedure: “; intReference

First we call the sub procedure, specifying the two parameters. intValue being the first one is passed by Value (See declaration of the function earlier. intValue is being passed as int1 to the procedure), while intReference is passed By Reference (int2)).

The second part is to show that the variables indeed changed. If you run the project now, the Immediate Window will show this:

Values of int1 in procedure: 20
Values of int2 in procedure: 200
Values of intValue after procedure: 10
Values of intReference after procedure: 200

Since intValue was passed by Value, the function altered a copy, and the actual variable itself remained the same. The intReference variable though changed not only within the sub procedure, but in the rest of the application as well.

Remember, if you want to pass variables to sub routines or functions, they become mandatory. Someone can’t call the function and not specify parameters. You can test this by substituting the code where we call the sub:

Call AddTen(intValue)

Run the program again, and you’ll get an error: “Compile Error; Argument not optional”. If you aren’t sure whether or not a user is going to give your function all the parameters it can take, you can make one or more of the arguments optional. To test this, add the Optional-keyword before the parameter you want to make optional (In our case, we just removed the second parameter to the function. Let’s make the second parameter optional):

Private sub AddTen (ByVal int1 As integer, Optional ByRef int2 As Integer)

Run the program again. The Immediate Window will show these values (above the old values. The Immediate Window keeps a ‘history’; it doesn’t empty itself every time):

Values of int1 in procedure: 20
Values of int2 in procedure: 0
Values of intValue after procedure: 10
Values of intReference after procedure: 100

As you can see, the value of int2 in the procedure is 0. That’s because we never specified a second parameter. One note about using the Optional keyword. If you have multiple parameters, first specify the mandatory parameters, and then the optional ones. As soon as you use the Optional keyword, VB demands all following parameters to also be Optional.

Lastly, we can also give an optional parameter a default value. This is a value that will be used if no parameter value is passed to the function. Let’s set one of those as well:

Private Sub AddTen(ByVal int1 As Integer, Optional ByRef int2 As Integer = 500)

Run the program again. The Immediate Window now shows:

Values of int1 in procedure: 20
Values of int2 in procedure: 1000
Values of intValue after procedure: 10
Values of intReference after procedure: 100