VB .NET Chapter 10 Functions and Subs

An Introduction to Functions and Subs

So far, the code you have been writing in these tutorials has mostly been lumped together under one button. The problem with this approach is that your code can get quite long and complex, making it difficult to read, and difficult to put right if something goes wrong. Another approach is to separate some of this code into its own routine. This is where functions and subs come in.

Segements of Code to do a Particular Job

The two terms refer to segments of code that are separate from your main code. You've already met some string functions - Equals() and Substring(), for example. These functions are built into Visual Basic. But if you could see under the hood, what you'd find is some code to do these jobs for you. All you have to do is to specify, for the Substring() function, what the string is, where you want to start, and how many characters you want to grab. You don't have to worry about how Visual Basic gets your answer, because the code is all wrapped up in a function, ready for you to use over and over again.
And that's the point about Functions and Subs: it's code that you might want to use over and over again. You don't have to keep writing the same code every time you want a specific job doing. Just write the code once, and then when you want to use it, just let Visual Basic know.

Write a Function or Sub to do the Job

Think about error checking when people are entering data on your Forms. You'd probably have a lot of Text Boxes, and want to check that the user was entering the correct data. You don't want people entering numbers in your First Name text box, for instance. To check that the user has entered the correct data, you write some error checking code. Except you might have lots of text boxes on the form. If you want to check all the text boxes, you'd have to write the same "checking" code for each text box. Instead of doing that, you can write your own Function or Sub. You only have to write it once. Then when you want to use it, you just refer to it by name, and the code will get executed. We'll soon write a Sub that we can use over and over again.

The difference between Functions and Subs

First, though, in case you are wondering what the difference is between a Function and a Sub, it's this: Functions return a value, and Subs don't.
Substring() is a Function, because you want some sort of answer back, and an answer that you can then use elsewhere. You assign the answer to the Substring() function to a variable.
A Sub is some code or job that you want VB to get on with and execute. An example is closing a form down and unloading it with Me.Close(). You don't need to return a value, here; you just want VB to close your form down.

Create your Own Subs in VB .NET

In the previous part, you learnt what a Sub is, and that it doesn't return a value, unlike a Function. In this part, you'll learn how to create your own Subs in VB .NET. Sub, by the way, is short for Subroutine
Here’s what we’re going to do. We’ll set up a text box on a form. The text box will be a First Name text box, and we’ll be checking that the user has actually entered something into it.
So, do this:
  • Start a new project, and put a Text Box on your new Form.
  • Put a button on the Form, too.
  • Double lick your button to see the coding window
  • Add the following code for the button:
Dim TextBoxData As String
TextBoxData = Trim(TextBox1.Text)
If TextBoxData = "" Then
MsgBox("Please Enter your First Name")
End If
Run the programme and test it out. Don’t enter anything in your textbox, but just click your button. Your message box should display.
Now, all that code is inside the button. More likely than not, we'd be writing more code for that button. In fact, we could be writing lots of code. The code we write could get a bit long and complex. Do we have to have that error checking code in there? And wouldn't we have to type it out all over again, if we wanted to check another textbox from a different button?
The answer to our two questions are, Not at all, and Yes we would!
To solve the problem, we'll chop that code from the button, and write a Sub for it. To write your own Sub, your cursor needs to be outside of the button code, and on a new line. But before the "End Class". So, on a new line outside the button code type the following:
Private Sub ErrorCheck()
When you've typed that, hit the enter key on your keyboard. Visual Basic will add the End Sub for you. The name "ErrorCheck" is entirely our own, and we could have called it almost anything we liked. But it's better to stick to something descriptive.
Your code window will then look like this one:
What your coding window should look like
Now, cut the code from your button and paste it between these two new lines, where the cursor is in the image above.
You have just created your own Subroutine!

How to use your new Sub

But the Sub is not doing much good where it is. We need a way to use that code. To use our new Sub, we have to tell Visual Basic to execute the code. We do that simply by referring to the Sub by name.
So click inside the button code, just before the End Sub of the button. Type the following:
Call ErrorCheck()
You don't have to use the "Call" word. Try taking that word out altogether, and then testing the programme again. The programme should run exactly the same. But using the "Call" word makes your code easier to read, and tells you that you are executing your own Subroutine on this line.
Your coding window should now look like this:
The Sub is being Called from the button
Run your programme and test it out. You should get the Message Box again, when nothing is in the Textbox.
Add another button to your form. Double click the new button to get at the code. Then type Call ErrorCheck() as the code for it. Run your programme again, and click your new button. You should get the Message box popping up, when nothing is entered into the Textbox.
The point about this is that you have created your own code segment. You can use this segment of code whenever you like, just by referring to it by name. Of course, you can have your code check more than one Textbox. You can check as many as you like. And for whatever you like. You can include the code you wrote to check for a correct email address, as well. But all that error checking code is no longer clogging up your button code.

Using Parameters in your Subs

In this lessons, we're going to be exploring Parameters. let's get straight to it.
Add two more textboxes to the form you created in the previous part. then do the following:
  • Set the Name property of the first Textbox to txtFirstNumber
  • Set the Name property of the second Textbox to txtSecondNumber
  • Add a new button to your Form and set the Text property to "Get Answer"
The two textboxes will contain numbers, one for each box. We'll write code to add the two numbers together, but in our own Sub. When the button is clicked, a Message Box will pop up revealing the answer to the sum of the numbers in the textboxes.
Double click your new button to bring up the code window. Click outside of the button code, just after End Sub, but before End Class. Type the following code:
Private Sub AddNumbers()
Dim first As Integer
Dim second As Integer
Dim answer As Integer
first = Val(txtFirstNumber.Text)
second = Val(txtSecondNumber.Text)
answer = first + second
MsgBox("The total is " & answer)
End Sub
We have created a Sub to add together the two numbers from the Textboxes. The code is very simple, and you should be able to follow it without any problems.
Now add this line to the code for your "Get Answer" button:
Call AddNumbers()
Run your programme. Type a number in each of the two Textboxes, and click your button to make sure your programme works (did the Message Box display?) Stop the programme and return to the design environment.
Chop the two lines of code for the Textboxes from the Sub and put them into the button. Your two sections of code should now look like this:
You coding window
The reason why there are two wiggly lines under first and Second is that the AddNumbers Sub knows nothing about these two variables. We've only declared one variable inside the Subroutine -answer. To get rid of the wiggly lines, we can set up something called a Parameter. Well, two parameters.
To put it simply, a Parameter is a value that we want to pass from one code section to another. What we want to do is to pass the values we gathered from our button code and hand them over to our AddNumbers Sub. So how do we do that?
Change the Private Sub AddNumbers() line to this:
Private Sub AddNumbers( first As Integersecond As Integer )
When you press your return key, VB changes the part in round brackets to this in versions of VB Express 2010 or less:
( ByVal first As Integer, ByVal second As Integer )
It's added a curious term - ByVal. (For 2012 users, the ByVal is hidden.) We'll explain what that is in a moment. For now, concentrate on the Parameters. The parameters are what we want to hand to our Subroutine. We want to hand an integer variable called first, and an integer variable calledsecond. Whatever values are currently stored in these two variables will be handed to our Sub.


But we need to change our Calling line, the one from our button. This line now has a wiggly line under it, signifying that something is wrong. Remember, it was this:
Call AddNumbers()
If you hold your mouse over the AddNumbers() you might see this tip appear:
Hold your mouse over AddNumbers
What this is telling you is that your AddNumbers Sub takes some Parameters (They are called Arguments when you pass them, and Parameters when they are received. Because this is somewhat confusing, we'll stick to calling them Parameters.) In other words, you don't have any option: if you want to call this Sub, you have to add values for the parameters you set up.
So change you Calling line to this:
Call AddNumbers( firstsecond )
(If the second inside your Sub has changed to Second(). Delete the round brackets.)
Again, we use the parentheses. And in between the parentheses are our two variables. They don't have to have the same names. Whatever you call your variables in the AddNumbers Sub does not have to be the same names as the calling line. The variable names can be entirely different. But the values in the variables get passed in the order you set them up. In our case the value in the variable first will get passed to the first variable in our AddNumbers Sub; the value in the variablesecond will get passed to the next variable we set up in our AddNumbers Sub.
Run your programme and check that it is working properly, now that you have changed the calling line. When you are done, change the variable names for your AddNumbers Sub to this (2012 users don't need to add ByVal.):
Private Sub AddNumbers(ByVal first2 As Integer, ByVal second2 As Integer)
Dim answer As Integer
answer = first2 + second2
MsgBox "The total is " & answer
End Sub
Here, we have changed the names in our Sub. The variable names are now different from the ones in the calling line They are now first2 and second2. But will it still work? Test your programme out and check it. You should find that it does.
So to sum up, we can use a Sub to create our own code segment. We use this Sub just by referring to it by name. If we want to pass any values to our Sub, we can set up Parameters in between the parentheses.

Exercise M

Create a Sub to check a Textbox for a valid email address, or adapt the one you already have. Pass whatever is entered in the Textbox to a variable called "email". Pass the value from this variable to your Sub by using a Parameter. When a button is clicked, a message box should pop up telling the user if the email address was wrong.

ByVal and ByRef in VB .NET

The word ByVal is short for "By Value". What it means is that you are passing a copy of a variable to your Subroutine. You can make changes to the copy and the original will not be altered. If you have 2012/13 of VB NET Express then ByVal is hidden. It's hidden because ByVal is the default when you're passing variables over to a function or Sub.
ByRef is the alternative. This is short for By Reference. This means that you are not handing over a copy of the original variable but pointing to the original variable. Let's see a coding example.
Add a new button the form you created in the previous section. Double click the button and add the following code:
Dim Number1 As Integer
Number1 = 10
Call IncrementVariable(Number1)
MsgBox(Number1)
You'll get a wiggly line under IncrementVariable(Number1). To get rid of it, add the following Subroutine to your code (again, 2012 users don't need to add the ByVal):
Private Sub IncrementVariable(ByVal Number1 As Integer)
Number1 = Number1 + 1
End Sub
When you're done, run the programme and click your new button. What answer was displayed in the message box?
It should have been 10. But hold on. Didn't we increment the variable Number1 with this line?
Number1 = Number1 + 1
So Number1 started out having a value of 10. After our Sub got called, we added 1 to Number1. So we should have 11 in the message box, right?
The reason Number1 didn't get incremented was because we specified ByVal in the Sub:
ByVal Number1 As Integer
This means that only a copy of the original variable got passed over. When we incremented the variable, only the copy got 1 added to it. The original stayed the same - 10.
Change the parameter to the this (2012/13 users should add ByRef, as well):
ByRef Number1 As Integer
Run your programme again. Click the button and see what happens.
This time, you should see 11 displayed in the message box. The variable has now been incremented!
It was incremented because we used ByRef. We're referencing the original variable. So when we add 1 to it, the original will change.
The default is ByVal - which means a copy of the original variable. If you need to refer to the original variable, use ByRef.

How to Create a Function in VB .NET

function is more or less the same thing as a Sub - a segment of code you create yourself, and that can be used whenever you want it. The difference is that a Function returns a value, while a Sub doesn't. When you Called a Sub you did this:
Call AddNumbers( first, second )
Visual Basic will go off and execute that code for you, and then drop down to the next line. The Sub AddNumbers is not a value, it's not equal to anything. It's not like a normal variable where you assign something to it. It's just the name of your Subroutine.
A Function is different. It is a value, will be equal to something, and you do have to assign a value to it. You create a Function in the same way you did a Sub, but this time your code will be like this:
Private Function ErrorCheck () As Boolean
End Function
First, we've changed the word "Sub" to "Function"; second we've added "As" something, in this case "As Boolean". The name we called our Function is ErrorCheck, and ErrorCheck is now just like a variable. And just like a variable, we use one of the Types. We can use "As Integer", "As Long", "As Double", "As String", or any of the variable types.
Let's write some code, and try an example.
Add a new button and a textbox to your form. Change the Name of the textbox to txtFunction. Double click your button and add the following code to it (add it after the End Sub of the button, but before the End Class):
Private Function ErrorCheck () As Boolean
Dim TextBoxData As String
TextBoxData = Trim(txtFunction.Text)
If TextBoxData = "" Then
MsgBox("Blank Text Box detected")
ErrorCheck = True
End If
End Function
This is almost the same code from our Sub called ErrorCheck, in a previous section. The difference is the one added line - ErrorCheck = True. Remember that ErrorCheck is now like a variable. In this case it was a Boolean variable. So if there's nothing in the Textbox, we have setErrorCheck to True.
An Else part can also be added to The IF Statement to set ErrorCheck to False, otherwise you may get a green underline in the code editor for End Function :
Else
ErrorCheck = False
End If
Again, this code is not doing much good by itself. We need a way to use it. This time, because we've set up a Function, we have to assign the value of the function to a variable. Like this:
Dim IsError As Boolean
IsError = ErrorCheck()
Here, we are saying "Run the function called ErrorCheck. When you have finished, assign the value of ErrorCheck to the variable called IsError".
Once that code is executed we can then use the variable IsError and test its value. If it's true, then we know that the user did not enter anything into the Textbox; if it's False, then we know that they did. The benefit of using a Function to check for our errors is that we can halt the programme if IsError = True. Like this:
If IsError = True then
Exit Sub
End If
So double click your button and add the following:
Dim IsError As Boolean
IsError = ErrorCheck()
If IsError = True then
Exit Sub
Else
MsgBox("IsError = False")
End If
Run your programme again. Click the button when the textbox is blank, and see what happens. Then enter some text into the textbox, and click your button again.
To sum up, then. A function will return a value. You put this value into the name of your Function. You then assign the value of the Function to a variable. You can then test the variable to see what's in it.

How to use Parameters with Functions

In the previous section, you learned how to set up a simple function. Let's set up another Function, as a further example. This time we'll add some Parameters to our Function. You use the Parameters in exactly the same way as you did for a Sub.
  • So add another button to your Form
  • Set its Text property to Get Function Answer
  • Add two Textboxes to your Form
  • Set the Name Property of the first Textbox to txtNumber1
  • Set the Name Property of the second Textbox to txtNumber2
  • Set up the following Function in your code window (The first line might be spread over two lines here. You can keep yours on one line. 2012 users can miss out the ByVal.)
Private Function AddTwoNumbers(ByVal first As Integer, ByVal second As Integer) As Integer
Dim answer As Integer
answer = first + second
AddTwoNumbers = answer
End Function
So the name of this Function is AddTwoNumbers, and we've set it up to return an Integer value. The two parameters we're passing in are also Integers. The code inside the Function simply adds up whatever is inside the variables first and second. The result is passed to another variable,answer. We then pass whatever is inside answer to the name of our Function. SoAddTwoNumbers will be equal to whatever is in the variable answer.
Instead of saying AddTwoNumbers = answer you can use the Return keyword. You use it like this:
Return answer
The result is the same: the value inside the variable answer is now the value of the function.
Open up the code for your "Get Answer" button, and add the following code to it:
Dim first As Integer
Dim second As Integer
Dim result As Integer
first = Val(txtNumber1.Text)
second = Val(txtNumber2.Text)
result = AddTwoNumbers(first, second)
If result = 0 Then
MsgBox("Please try again ")
Else
MsgBox("The answer is " & result)
End If
So we're telling Visual Basic to execute our Function on this line:
result = AddTwoNumbers( firstsecond )
We're saying, "Run the Function called AddTwoNumbers. Hand it the values from the two variables. When you've finished running the function, pass whatever the value ofAddTwoNumbers is to the variable called result."
The next few lines are just testing what is inside the variable result. Remember: the variable resultwill hold whatever the value of AddTwoNumbers was.
When you've finished typing your code, run your programme and test it out. Type a number in the first text box, and one in the other. Then click the "Get Function Answer" button. Try typing two zeros into the textboxes and see what happens.
Setting up and using functions can be quite tricky at first, but it's well worth your while persevering: they can vastly improve your coding skills.

Standard Modules in VB .NET

The Subs and Functions worked perfectly well where they were - inside the two lines "Public Class Form1" and "End Class". If you tried to put them on a line underneath End Class you would get lots of blue wiggly lines under your code.
That's because the code all belongs to Form1. But it doesn't have to. In fact, it's better to separate all your Functions and Subs and put them somewhere else - in something called a Module. We'll explore the Standard Module, and see how to move our Functions and Subs outside of Form1. That way, we can use them in other projects.
So start a new project. Add a button to you new form. To add a Module to your project in version 2008 and 2012/13,, click Project from the menu bar. From the menu, click on Add Module:
The Add Module menu
In VB .NET Express version 2010, just click Project > Add New Item.
When you click Add Module (or Add New Item), you'll see something like this dialogue box popping up (2008 version of the software):
The Add New Item dialogue box
Or this one, in the 2010 edition (the 2012/13 edition has a less colourful version of the one below):
Add a Module to a VB NET project
Select Module from the Templates window. Type a name for your new module - modVerify.vb. When you've typed a name, click the Open button.
You'll should see a blank window, with this code in it:
The Module code window
If you take a look at the Solutions Explorer on the right, you should see that your new module is listed:
Your Module is now in the Solutions Explorer
In between Module modVerify and End Module, type the following Subroutine:
Private Sub AddNumbers(ByVal num1 As Integer)
Dim answer As Integer
answer = num1 + 10
MsgBox(answer)
End Sub
Your coding window should now look like this:
The Module code
Now click back on your form and double click the button you added. This will bring up the code window for the Form, and the cursor will be flashing inside of the button code.


Add the following code for your button:
Call AddNumbers(10)
When you press the return key, you'll see a blue wiggly line under the Sub name. If you hold your mouse over AddNumbers, you might see this:
The code for the Button

VB placed a blue wiggly line under the name of our Sub:
VB has a problem with the code
What VB is saying is that it can't see your new Subroutine from the inside of the button code. It thinks you haven't got a Sub called AddNumbers. The reason it can't see it is we made the SubPrivate. Only code inside of the modVerify Module can see a Private Sub. If you want the Sub or Function to be available to all the code in your project, including the button, you have to make then Public. This involves nothing more than changing the word Private to Public. Amend your Sub to this:
Change Private to Public
When you make the change from Private to Public, the blue wiggly line should disappear from the Button code
Run your programme and test it out. Click your Button. You should get a message box saying "20".
We'll now add a Function to our new Module.
So bring up the code for your module. When you have your new Module displayed, type in the following Function:
Public Function VerifyPostcode(ByVal postcode As String) As String
postcode = StrConv(postcode, VbStrConv.UpperCase)
Return postcode
End Function
When you're finished, your coding window should look like this:
A Sub and a Function have been added to the Module


All the function does is to check a Postcode to see if the letters in it are all in capitals. That's because, quite often, people will enter a postcode as this:
ci1 4ty
What you want is a Postcode that reads:
CI1 4TY
The new function will convert a postcode handed to it, and make sure the letters are all capitals.
The inbuilt function that does the converting is worth exploring. It's this:
StrConv( )
This is short for String Conversion. In between the round brackets, VB needs you to put two things: the string you want to convert, and what sort of conversion you want. As soon as you type a comma after the string you want to convert, VB pops up a box of available conversion types:
Conversion Types in VB NET
A lot on the list are rather baffling. But the one we used was the UpperCase one. Simple double click an item to add it to your code. This gave us the following:
StrConv( postcode, VbStrConv.UpperCase )
The function will then convert all the letters in postcode to capitals.
Another useful one on the list is ProperCase. What this will do is take a string and convert all the letters of the first word (or words) to capitals. This is useful for addresses. So if somebody entered this as an address:
49 high street
The VbStrConv.ProperCase item would convert it to this:
49 High Street
But back to our code.
Select your Form again. Then add a new Button, and a Textbox to it. Change the Text property of the Textbox to ci1 4ty. Double click the button, and add the following code for it:
Dim CheckPostcode As String
Dim ConvertPostcode As String
CheckPostcode = Trim(TextBox1.Text)
ConvertPostcode = VerifyPostcode(CheckPostcode)
TextBox1.Text = ConvertPostcode
The first thing we do is get the Text from the textbox. This is passed to a variable called CheckPostcode. The next line calls our new function. We hand it the postcode we got from the textbox:
ConvertPostcode = VerifyPostcode( CheckPostcode )
When our function has finished the conversion, it will hand back (Return) the result and put it in the variable ConvertPostcode. This is then placed back inside the textbox.
Run your programme, and click the new button. You should find that the letters in the postcode are converted to capitals.
The point about creating a Module to house all your Subs and Functions is that they are in a separate file. You could write more Subs and Functions for your Module, ones that validate text coming from a textbox (an email checker, for example, or one that uses the ProperCase string conversion). You would then have all this code in one file that you could add to totally different projects. If the Subs and Functions were in the same code for the Form, you would have to import the whole Form before you could use the very useful Subs and Functions you created.
But that's enough about Modules. We'll move on to a new section.


Comments