VBcoders Guest



Don't have an account yet? Register
 


Forgot Password?



Subs, Functions, and Parameters...A beginner's guide.

by Matthew Roberts (26 Submissions)
Category: Coding Standards
Compatability: Visual Basic 3.0
Difficulty: Beginner
Date Added: Wed 3rd February 2021
Rating: (4 Votes)

Explains the concepts of Subs, Functions, and Parameters. If you are a little fuzzy on the difference, take a look.

Rate Subs, Functions, and Parameters...A beginner's guide.

xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns="http://www.w3.org/TR/REC-html40">





href="./Sometimes%20we%20miss%20the%20obvious_files/filelist.xml">
Sometimes we miss the obvious




Using Subs and Functions in VB


 


Sometimes we miss the obvious. I know there are a lot of
things I was doing in Visual Basic that I thought were not only right, but
extremely clever. What I eventually discovered was that the reason I was having
to dream up such clever “work abounds” was that I was basing my code on
incorrect assumptions about how VB works. 


 


One area that I had trouble with, as have several people I
have taught coding to is parameters and return values. This article is in the
Beginner category, but  I didn’t learn
some of this stuff until long after I was working as a VB programmer and
considered myself a “professional”. If there is one thing I have learned about
programming, it is that you NEVER know everything, and there is always another
way to do something. My goal is to show programmers the correct way to use
these features before they go off and invent ways that will cause problems
later. Nothing is worse than realizing that you have been doing something the
wrong way for the last three years.


 


Is this tutorial for you? Let’s find out. Consider the
following questions:


 


tab-stops:list .5in'>·style='font:7.0pt "Times New Roman"'>         
Can you explain the difference between a Sub and a
Function in one sentence?


tab-stops:list .5in'>·style='font:7.0pt "Times New Roman"'>         
Can you explain the difference between a PUBLIC Sub and
a PRIVATE sub?


tab-stops:list .5in'>·style='font:7.0pt "Times New Roman"'>         
Do you know how to get a return value from a procedure without
using global variables?


 


 


If you answered “Yes” to all of
the questions above, you probably don’t need this tutorial. But before you
close it out, you should be sure you really understand how to do these
things. Why? Because these skills are fundamental to good coding. You simply
cannot write good complex code without them. 


 


If the questions above left you
scratching your head in confusion, hang in there. You are not alone. If you read
this entire tutorial, I promise they will be answered in a way that you can
understand them (or your money back!)


 


normal'>Subs and Functions- What is the difference?


 


To understand what a sub or
function is and why we need them, we should go back a few years. For the
moment, we will concentrate on Subs, since they are easier to understand. I
will then show you how Functions extend the capability of Subs.


 


If there are any old line
programmers out there, you may remember what we now call “spaghetti code”. Of course,
when we were writing it, we didn’t call it that. We called it sheer genius. The
term “spaghetti code” refers to the logic path of an application written in a
language such as BASIC or BASICA. In these languages, each line had a line
number, and you controlled program flow by referring to the associated line
number of the command you wanted to execute. (Boy, I am suddenly feeling old
here!)


 


For example:


 


10 CLSyes">                                                                          style="mso-spacerun: yes">   ‘Clears the screen…we are talking DOS here.


20 LN$=INPUT$ “What is your last
name?:”


30 FN$=INPUT$ “What is your first
name?


40 IF LN$=”” Then style='mso-bidi-font-weight:normal'>GOTO normal'>20


50 IF FN$=”” THEN style='mso-bidi-font-weight:normal'>GOTO 30


60 PRINT “You entered “ + LN$ + “
“ + FN$


70 END


 


This is a complete (albeit simple)
program for BASIC. It prompts for a last name and a first name, then forces you
to re-enter it if you didn’t enter a value for one or the other.style="mso-spacerun: yes">  The part I would like you to notice is the
GOTO statement. You may have seen this command used in VB in error handling,
and if you have been around any VB programmers very long, you have heard them
harp on how evil the GOTO command is. 


 


In BASIC, GOTO redirected program
flow to a specific line number. Otherwise, programs started at line 0 (or 10 in
most cases) and executed sequentially until they met an END statement, which
terminated the program. The problem with this concept was that once you got
about 2000 lines of code, it became difficult to track where the program would
jump to in any situation. For example, the statement GOTO 20150 meant that to
track execution, you had to scroll all the way down to line 20150. Of course,
it may contain an IF THEN statement that sent it back to line number 1220. It
isn’t hard to imagine why this type of code earned its nickname. Eventually it
reached “critical mass” and became unmanageable.


 


Most BASIC programmers eventually
discovered the GOSUB statement. This was a pretty big leap in program control.
Like GOTO, it redirected program execution to a line number somewhere in the
thousands of lines of code, but unlike GOTO, GOSUB knew where it was redirected
from and could return to that point in the program when it completed its
task. It told BASIC “GOTO A BLOCK OF SUB-CODE”. Here is how it was used:style='mso-special-character:line-break'>


10 CLS


20 X$=INPUT$ “Choose a Menu Item”


30 IF X$=”A” THEN style='mso-bidi-font-weight:normal'>GOSUB normal'>2000


40 IF X$=”B” THEN style='mso-bidi-font-weight:normal'>GOSUB 3000


50 IF X$=”C” THEN END


60 ’ 5'>                                                                                style="mso-spacerun: yes">  END OF MENU CODE


normal'> 


normal'>…


normal'> 


2000 CLS


2010 …..DO STUFF….



2520 normal'>RETURN


 


3000 CLS


3010 …..DO STUFF….



3520 normal'>RETURN


normal'> 


normal'> 


In this example, we not only use
the GOSUB keyword, but we also use
the RETURN keyword. What this told
BASIC was “Go back to the last GOSUB statement that you executed. “ To
programmers, this was pure gold. It allowed recursion (calling a piece of code
within the same piece of code) and much better program flow control. In
essence, this is the origin of the Visual Basic “Sub” procedure. 


 


OK…enough nostalgia for now. Back
to VB. What this history lesson has shown you is that things could be much
worse. But with Visual Basic, some obvious improvements have been made. Line
numbers have been dropped (a tough concept for us old timers…QuickBasic helped
ease us into this concept). This allowed the programmer to name blocks of code
with a name instead of a number. Now instead of GOSUB 2000, we can say “Call
GetCustomerID” to call a piece of code that will find a customer ID for us.


 


normal'>Here is how the VB Sub works:


 


First, you need to know what your
sub will be doing. There are some basic criteria to determine whether or not
you need to place code into a sub. They are:


 


tab-stops:list .75in'>1.                  
Is this code used in more than one place (are you writing
duplicate code in your application)?


tab-stops:list .75in'>2.                  
Does this code perform a specialized function independent of
the rest of the code?


tab-stops:list .75in'>3.                  
Can you effectively create this as a “stand-alone” piece of
code?


 


Of the three criteria above,
number three is the toughest. For example, if you have a piece of code to find
state that a customer is located in based on their zip code, do you write that
same piece of code for every customer? Obviously, that would be impractical if
not impossible. What you need is a way to find the state any zip code.
Here is the way most beginners handle this problem:


 


First, create public variables to
hold the values we will be working with:


 


Public
ZIP As String


Public
State As String


 


Public
Sub GetState()


 


style="mso-spacerun: yes">      If ZIP > 32501 AND ZIPstyle="mso-spacerun: yes">  <34205 Then


style="mso-spacerun: yes">          yes"> State = “MS”


style="mso-spacerun: yes">      ElseIf ZIP >45102 AND ZIP < 53210
Then


style="mso-spacerun: yes">            State = “TN”


style="mso-spacerun: yes">      ……


 


End Sub


 


This code works. Using this
method, you can get the state of any of the zip codes contained in the GetState
sub. But there are problems with this code as well. The main one is that you
are now relying on public variables. This is because you have to be able to
access the values in from your form or calling code normal'>and within your sub. This can get real messy real quick when you
consider that you may need to use the name “state” for a variable many times in
an application. You are then forced to create MANY public variables with odd
names like GetStateFromZip_State and GetStateFromZip_Zip to insure that you
don’t accidentally overwrite your values from other places in your program.
This is just a really bad way to code. The solution? normal'>Parameters (finally!).


 


In order to get your values safely
to your Sub without having to create public variables, you can instead create
Sub Parameters. These are really just variables that only your calling code and
your sub can see.  They look like this:


 


mso-bidi-font-size:12.0pt;color:navy'>Public Sub GetState(ZIP As String)


mso-bidi-font-size:12.0pt;color:navy'> 


mso-bidi-font-size:12.0pt;color:navy'>     
If ZIP > 32501 AND ZIP 
<34205 Then


mso-bidi-font-size:12.0pt;color:navy'>yes">           State = “MS”


mso-bidi-font-size:12.0pt;color:navy'>     
ElseIf ZIP >45102 AND ZIP < 53210 Then


mso-bidi-font-size:12.0pt;color:navy'>yes">            State = “TN”


mso-bidi-font-size:12.0pt;color:navy'>     
……


color:navy'>              End If


mso-bidi-font-size:12.0pt;color:navy'>End Sub


 


Now this code does the exact same thing, but without
having to rely on the public variable ZIP. You can also pass multiple
parameters:


 


mso-bidi-font-size:12.0pt;color:navy'>Public Sub AverageNumbers(Number1 As
Integer, Number2 As Integer, Number3 As Integer)


mso-bidi-font-size:12.0pt;color:navy'>        …


mso-bidi-font-size:12.0pt;color:navy'>End Sub


 


All three of these values will be
available from within your sub, but will not exist outside of it. Getting
pretty neat, isn’t it?


 


But we still have a problem. We passed the variable
IN , but how do we get a value back OUT of a sub? I mean, it’s nice that we
averaged these numbers, but we still have to use a public variable to get the
return value, right? Wrong. 


 


There are three ways to get return
values from a piece of code:


 


tab-stops:list .75in'>1.      
Public Variables (ugly!)


tab-stops:list .75in'>2.      
By making a “return value” parameter.


tab-stops:list .75in'>3.      
By making your sub into a function.


 


We have already established that public variables
are not the answer we are seeking, so lets examine option #2. This is more of a
“hack” than a feature of VB. It takes advantage of the fact that both the
calling code and the sub code have access to parameter values. You could do
this to get a return value:


 


mso-bidi-font-size:12.0pt;color:navy'>Public Sub AverageNumbers(Number1 As
Integer, Number2 As Integer, Number3 As Integer, ReturnValue As Integer)


mso-bidi-font-size:12.0pt;color:navy'>        


mso-bidi-font-size:12.0pt;color:navy'>    
ReturnValue = (Number1 + Number2 + Number3) /3


mso-bidi-font-size:12.0pt;color:navy'> 


mso-bidi-font-size:12.0pt;color:navy'>End Sub


 


 Again, this would
work. But it creates problems on the calling side now. In order to use it, you
have to use code similar to this:


color:navy'>      Call
AverageNumbers(10, 20, 50,0)


color:navy'>      Msgbox “Average =
  & ReturnValuestyle='color:navy'>


 


It is technically returning a value, but it looks (and is) rather
clunky. You have to pass in a “0” for the return value or you will get an
error.  Then, to make matters worse, you
have to then refer to that variable when the sub completes. What would be nice
is if you could use it just like a VB command. 
Consider the Ucase() command in Visual Basic. It is
straightforward:


color:navy'> 


color:navy'>       MsgBox Ucase(“this is
a test”)


 


      Results is a
message box being displayed with the words “THIS IS A TEST” in it.


 


So how does Microsoft do that? How do they get a return
value from the Ucase command? Surely it is some secret code that you don’t have
the power to duplicate. Wrong! The
way they do it is by making the command Ucase() into a normal'>Function instead of a Sub. What is the difference? Simple:


 


A function can return
a value through its name variable. yes"> A sub cannot. 


 


What does that mean “through its name variable”?


 


Let’s look at a function declaration:


 


color:navy'>Public Function AverageNumbers(Number1 As Integer, Number2 As
Integer, Number3 As Integer) style='font-size:8.0pt;mso-bidi-font-size:12.0pt;color:navy'>As Integerstyle='font-size:8.0pt;mso-bidi-font-size:12.0pt;color:navy'>


color:navy'> 


color:navy'> 


color:navy'>End Function


 


 


You should notice two things different about this
declaration compared to the sub declaration:


tab-stops:list .5in'>·style='font:7.0pt "Times New Roman"'>         
It has no return parameter.


tab-stops:list .5in'>·style='font:7.0pt "Times New Roman"'>         
It has “As Integer” stuck on the end. What is style='mso-bidi-font-weight:normal'>that all about?


 


So how in the world does the value of Ucase() (or
AverageNumbers for that matter), find its way back to the calling code “MsgBoxstyle="mso-spacerun: yes">  = “?


 


Well, that is the difference between Subs and
Functions. Functions act as a return value normal'>variableThat is why it was declared “style='mso-bidi-font-weight:normal'>As Integer”. You can now call the
AverageNumber function exactly as you would the Ucase() function:


 


          style='color:navy'>MsgBox “Average =” & AverageNumbers(10,20,50)


 


 Here is the complete
function:


 


color:navy'>Public Function AverageNumbers(Number1 As Integer, Number2 As
Integer, Number3 As Integer) As Integer


color:navy'> 


mso-bidi-font-size:12.0pt;color:navy'>   
AverageNumbers = (Number1 + Number2 + Number3) /3


color:navy'> 


color:navy'>End Function


 


 


Notice that the line:


 


mso-bidi-font-size:12.0pt;color:navy'>    
ReturnValue = (Number1 + Number2 + Number3) /3


 


has now been
modified to read:


 


mso-bidi-font-size:12.0pt;color:navy'>   
AverageNumbers = (Number1 + Number2 + Number3) /3


 


This is where the “magic” happens. VB performs the
calculations, and when it gets the results, it pipes it back into the
AverageNumbers variable which was created when this function was
declared. From there, it can be assigned back to a variable in the calling
code. So to see the whole picture:


 


   


color:navy'>Private Sub Command1_Click()


color:navy'>      MsgBox “Average =” &
AverageNumbers(10,20,50)


color:navy'>End Sub


 


 


color:navy'>Public Function AverageNumbers(Number1 As Integer, Number2 As
Integer, Number3 As Integer) As Integer


color:navy'> 


mso-bidi-font-size:12.0pt;color:navy'>   
AverageNumbers = (Number1 + Number2 + Number3) /3


color:navy'> 


color:navy'>End Function


 


 


So now you can start to see how return values work with
functions. Once you fully grasp this concept, you will begin to realize that VB
commands are nothing but functions written by the Microsoft VB team.
Conceptually, yours are no different. You can actually normal'>create your own commands to us in your application, just by
creating them as functions!


 


This is big!


 


 


There is one more concept I want to touch on before wrapping
up:


 


 normal'>The difference between Public and Private Subs and Functions


 


To fully understand the implications of making a function or
sub public or private, you will need to study up on the topic of SCOPE in VB.
This basically is the level at which something is “visible” to the rest of the
application. As you have seen through earlier examples, Public variables are
not a good thing. Public Functions, on the other hand, are a VERY good thing.
This makes them accessible from anywhere in your application…so if you want to
average a number from three different forms, you can still call the same
AverageNumbers function. 


 


With Private subs and functions, you will only be able to
call them from within the object that they are declared in. Why would
you want to do this? Well, you may have noticed that VB creates all Form Subs
as Private. This is because if you created them as Public, you would have many
Form_Load() subs, many  Command1_Click
() subs, etc. This would make your application crash instantly, so by using
private scope, you effectively “hide” these subs from other forms.


 


ONE NOTE: You cannot declare a Public variable, sub, or
function from within a form. YOU MUST
DECLARE ALL PUBLIC ITEMS FROM WITHIN A MODULE. You can add a module to your
project by going to the Project menu and clicking “Add Module”.


 


I sincerely hope this tutorial has helped you in grasping
how and why to use subs and functions. This is such a vital topic to good
programming and so little is published about it. Please let me know if you need
more information on any of the topics covered in this tutorial.


 


M@





Download this snippet    Add to My Saved Code

Subs, Functions, and Parameters...A beginner's guide. Comments

No comments have been posted about Subs, Functions, and Parameters...A beginner's guide.. Why not be the first to post a comment about Subs, Functions, and Parameters...A beginner's guide..

Post your comment

Subject:
Message:
0/1000 characters