Visual Basic/Procedures and Functions

Functions are named blocks of program code that perform a specific task and return a result. The task can be as simple as adding two numbers or as complex as launching a spacecraft. A subroutine is like a function, just that it does not return a result.

Defining procedures edit

An example function definition:

  Public Function Sum(ByRef Number1 As Double, ByRef Number2 As Double) As Double
    'Return the result by writing it to a variable having the same name as the function
    Sum = Number1 + Number2
  End Function

An example subroutine definition:

  Public Sub Tell(ByVal MyString1 as String, ByVal MyString2 as String)
    MsgBox MyString1 & MyString2
  End Sub

Note the following:

  • The arguments to the function are declared as ByRef which requires the compiler to make sure that only arguments of the specified type are used, in this case Double.
  • The function returns a value by assigning it to the function name as though the function were a variable. This contrasts with the use of the keyword return in many other languages.

Calling procedures edit

You can use or call the two procedures defined in the previous sections as follows:

  'On the next line, argument order matters
  Tell "Hello there.", ""
  'On the next line, names of arguments are used and argument order does not matter.  
  Tell MyString1:="Hello there,", MyString2:=" again."
  'Tell ("Hello there.","") -- syntax error

  MySum = Sum(123.456, 234)
  MySum2 = Sum(Number2:=8, Number1:=6)
  'MySum3 = Sum Number2:=8, Number1:=6 -- syntax error

Note the following:

  • The arguments (argument list) passed to a function must be enclosed in round brackets, whereas those supplied to a subroutine need not.

Procedure parts edit

Each function and subroutine has the following parts, some of the optional:

Visibility
Public, Friend or Private
Procedure Type
Sub, Function, Property Let, Property Get, Property Set
Name
A freely chosen name that starts with a letter and contains only letters, numbers and underscores.
Argument List
A list of the items of data that the procedure reads or writes into.
Return Type
For a Function or Property Get, the data type returned, such as Double or String.
Body
All the statements that do the work.

Only the Name and the Procedure Type are mandatory. Of course, a procedure without a body doesn't do anything.

Visibility edit

This seems like a very unimportant part of a procedure declaration to most people but in fact it is a very helpful feature. With it you can show that some procedures are just for use inside a module (Private), some only for use in this component (Friend) or available for the whole world (Public). You should mark procedures Private unless they will be called from outside the module. this will encourage you, and anyone who edits your program, to place related procedures in the same module which obviously makes maintenance easier.

Marking a procedure Private also means that you can have another procedure with exactly the same name in another module.

Early Termination edit

Use Exit Function or Exit Sub to terminate a procedure in the middle, like this:

  Sub LengthyComputation(fat, n)
    If n = 0 Or n = 1 Then
      fat = 1
      ' Now terminate
      Exit Sub
    End If
    ' Now compute fat ...
  End Sub

Procedure type edit

All procedures are either functions that return a result as the value of the function, or subroutines that are called for their side effects. To return a value, you can use both, but with subroutine, you need to do it via an argument:

  Private Function FunctionHalf(ByRef y as Double) as Double
    FunctionHalf = y / 2
  End Function

  Private Sub SubroutineHalf(ByRef y As Double, ByRef Result As Double)
    Result = y / 2
  End Sub

The two procedures do essentially the same thing, that is, divide a number by two. The Function version does it by assigning the new value to the name of the function while the Sub version assigns it to the name of one of the arguments. This affects how you use them.

The function version can be used in an expression as follows:

Debug.Print FunctionHalf(10) 'Prints 5

To use the subroutine to return value, you need to store the value in a variable, like this:

  Dim nHalf as Double
  SubroutineHalf 10, nHalf
  Debug.Print nHalf

Generally, you use a Function when the result is a single thing (number, string, object) and a Sub when you either want to return several distinct things or nothing at all.

Properties are also a form of procedure. Property Get is a function; Property Let and Property Set are subroutines. For more discussion of Properties, see the Object Oriented Programming chapter.

Optional arguments edit

You can specify optional arguments and default values:

Function MySum(i1, i2, Optional i3)
  If IsMissing(i3) Then
    MySum = i1 + i2
  Else
    MySum = i1 + i2 + i3
  End If
End Function

Function MyConcatenate(String1, String2, Optional Separator = " ")
  'Default value for Separator specified
  MyConcatenate = String1 & Separator & String2
End Function

Sub Test()
  Debug.Print MySum(1, 2) * MySum(1, 2, 3)
  Debug.Print MyConcatenate("Hello", "World")
  Debug.Print MyConcatenate("Hello", "World", ", ")
End Sub

Once an argument is declared optional, all arguments at the right of it have to be declared optional as well.

Links:

Previous: Data Types Contents Next: Windows_Dialogs