5. Functions and Procedures
5.1. VBScript's predefined functions
The richness of a language derives largely from its function library, as these functions can be encapsulated in objects under the name of methods. In this regard, VBScript can be considered rather limited.
The following table lists VBScript functions outside of objects. We will not go into detail about them. Their names generally indicate their purpose. Readers should consult the documentation for details on a specific function.
Abs | Array | Asc | Atn |
CBool | CByte | CCur | CDate |
CDbl | Chr | CInt | CLng |
Conversions | Cos | CreateObject | CSng |
Date | DateAdd | DateDiff | DatePart |
DateSerial | DateValue | Day | Derived Maths |
Eval | Exp | Filter | Currency Format |
FormatDateTime | Number Format | Percentage Format | GetLocale |
GetObject | GetRef | Hex | Hour |
InputBox | InStr | InStrRev | Int, Fixs |
IsArray | IsDate | IsEmpty | IsNull |
IsNumeric | IsObject | Join | LBound |
LCase | Left | Len | LoadPicture |
Log | LTrim; RTrim; and Trims | Maths | Mid |
Minute | Month | MonthName | MsgBox |
Now | Oct | Replace | RGB |
Right | Rnd | Round | ScriptEngine |
ScriptEngineBuildVersion | ScriptEngineMajorVersion | ScriptEngineMinorVersion | Second |
SetLocale | Sgn | Sin | Space |
Split | Sqr | StrComp | String |
Tan | Time | Timer | TimeSerial |
TimeValue | TypeName | UBound | UCase |
VarType | Weekday | WeekdayName | Year |
5.2. Modular Programming
Describing the programmed solution to a problem means describing the sequence of basic operations that can be executed by the computer and are capable of solving the problem. Depending on the programming language, these basic operations vary in complexity. Examples include:
- reading data from the keyboard or disk
- writing data to the screen, a printer, a disk, etc.
- calculating expressions
- navigating through a file
- ...
Describing a complex problem may require several thousand of these basic instructions or more. It is therefore very difficult for the human mind to grasp the big picture of a program. Faced with this difficulty in grasping the problem as a whole, we break it down into subproblems that are easier to solve. Consider the following problem: Sort a list of numerical values entered via the keyboard and display the sorted list on the screen.
We can initially describe the solution in the following form:
début
lire les valeurs et les mettre dans un tableau T
trier le tableau T
écrire les valeurs triées du tableau T à l'écran
fin
We have broken the problem down into 3 subproblems, which are easier to solve. The algorithmic notation is often more formalized than the previous one, and the algorithm would be written as follows:
where T represents an array. The operations
are non-elementary operations that must in turn be described by elementary operations. This is done in what are called modules. The data T is called a module parameter. It is information that the calling program passes to the called module (input parameter) or receives from the called module (output parameter). The parameters of a module are therefore the information exchanged between the calling program and the called module.
module read_array(T) | ![]() |
module sort_array(T) | ![]() |
module read_array(T) | ![]() |
The module read_array(T) could be described as follows:
début
écrire "Tapez la suite de valeurs à trier sous la forme val1 val2 ... : "
lire valeurs
construire tableau T à partir de la chaîne valeurs
fin
Here, we have sufficiently described the read_array module. Indeed, the three necessary actions have an immediate translation into VBScript. The last one will require the use of the Split function. If VBScript did not have this function, action 3 would in turn have to be broken down into elementary actions having an immediate equivalent in VBScript.
The write_array(T) module could be described as follows:
début
construire chaîne texte "valeur1,valeur2,...." à partir du tableau T
écrire texte
fin
The write_array(T) module could be described as follows (assuming that the indices of the elements of T start at 0):
début
N<-- indice dernier élément du tableau T
pour IFIN variant de N à 1
faire
//on recherche l'indice IMAX du plus gd élément de T
// IFIN est l'indice du dernier élément de T
chercher_max(T, IFIN, IMAX)
// on échange l'élément le plus grand de T avec le dernier élément de T
échanger (T, IMAX, IFIN)
finfaire
FIN
Here, the algorithm again uses non-elementary actions:
. chercher_max(T, IFIN, IMAX)
. échanger(T, IMAX, IFIN)
find_max(T, IFIN, IMAX) returns the index IMAX of the largest element in array T whose last element has index IFIN.
![]() |
swap(T, IMAX, IFIN) swaps two elements of the array T, those at indices IMAX and IFIN.
![]() |
We must therefore describe the new non-elementary operations.
module find_max(A, IFIN, IMAX) | |
exchange module(T IMAX, IFIN) | |
The initial problem has been fully described using basic VBScript operations and can therefore now be translated into this language. Note that basic operations may differ from one language to another, and therefore the analysis of a problem must at some point take into account the programming language being used. An object that exists in one language may not exist in another, thereby altering the algorithm used. Thus, if a language had a sorting function, it would be absurd not to use it here.
The principle applied here is known as top-down analysis. If we outline the framework of the solution, we have the following:
![]() |
We have a tree structure.
5.3. VBScript Functions and Procedures
Once the modular analysis has been performed, the programmer can translate the modules of their algorithm into VBScript functions or procedures. Both functions and procedures accept input/output parameters, but a function returns a result that allows it to be used in expressions, whereas a procedure does not.
5.3.1. Declaration of VBScript functions and procedures
The declaration of a VBScript procedure is as follows
and that of a function
To return its result, the function must include an assignment statement that assigns the result to a variable with the same name as the function:
functionName=result
The execution of a function or procedure ends in two ways:
- upon encountering the end function or end sub statement
- upon encountering the exit function or exit sub statement
For a function, note that the result must have been assigned to a variable with the function’s name before the function ends with an end function or exit function.
5.3.2. Parameter Passing Modes for a Function or Procedure
In the declaration of the input-output parameters of a function or procedure, the mode (byRef, byVal) of parameter passing from the calling program to the called program is specified:
sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)
function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)
When the byRef or byVal mode is not specified, the byRef mode is used.
Actual parameters, formal parameters
Consider a VBScript function defined as
The parameters paramForm1 used in the definition of the function or procedure are called formal parameters. The preceding function can be called from the main program or another module using a statement such as:
The parameters paramEffi used in the call to the function or procedure are called actual parameters. When the execution of the function functionName begins, the formal parameters receive the values of the corresponding actual parameters. The keywords byRef and byVal determine the mode of transmission for these values.
Pass-by-value mode (byVal)
When a formal parameter specifies this mode of passing, the formal parameter and the actual parameter are two different variables. The value of the actual parameter is copied into the formal parameter before the function or procedure is executed. If the function or procedure modifies the value of the formal parameter during execution, this does not affect the value of the corresponding actual parameter. This passing method is well-suited for the input parameters of a function or procedure.
![]() |
Pass-by-reference mode (byRef)
This passing mode is the default if no parameter passing mode is specified. When a formal parameter specifies this passing mode, the formal parameter and the corresponding actual parameter are one and the same variable. Thus, if the function modifies the formal parameter, the actual parameter is also modified. This passing mode is well-suited for:
- output parameters, since their values must be passed back to the calling program
- input parameters that are costly to copy, such as arrays
![]() |
The following program shows examples of parameter passing:
Program
Sub proc1(byval i, ByRef j, k)
' i is passed by value (byval) - the effective parameter and the formal parameter are then different
' j is passed by value (byref) - the effective parameter and the formal parameter are then identical
' the k passage mode is not specified. The default is by reference
i=i+1
j=j+1
k=k+1
affiche "dans proc1",i,j,k
End Sub
Sub affiche(byval msg, ByVal i, ByVal j, ByVal k)
' displays the values of i and j and k
wscript.echo msg & " i=" & i & " j=" & j & " k=" & k
End Sub
' ------------- calls to functions and procedures
' init i and j
i=4:j=5 : k=6
' check
affiche "dans programme principal, avant l'appel à proc1 :",i,j,k
' call proc1 procedure
proc1 i,j,k
' check
affiche "dans programme principal, après l'appel à proc1 :",i,j,k
' end
wscript.quit 0
Results
dans programme principal, avant l'appel à proc1 : i=4 j=5 k=6
dans proc1 i=5 j=6 k=7
dans programme principal, après l'appel à proc1 : i=4 j=6 k=7
Comments
- In a VBScript script, there is no specific place for functions and procedures. They can be anywhere in the source code. Generally, they are grouped either at the beginning or at the end, and the main program is structured as a continuous block.
5.3.3. Syntax for calling functions and procedures
Let p be a procedure accepting formal parameters pf1, pf2, ...
- the call to procedure p takes the form
without parentheses around the parameters
- if procedure p accepts no parameters, one may use either the call p or p() and the declaration sub p or sub p()
Let f be a function that accepts formal parameters pf1, pf2, ...
- The function f is called in the form
Parentheses around the parameters are mandatory. If the function f takes no parameters, one can use either the call f or f() and the declaration function f or function f().
- The result of function f may be ignored by the calling program. Function f is then considered a procedure and follows the rules for calling procedures. We then write f pe1, pe2, ... (without parentheses) to call function f.
If the function or procedure is an object method, the rules appear to be somewhat different and inconsistent.
- Thus, we can write MyFile.WriteLine "This is a test." or MyFile.WriteLine("This is a test.")
- but while we can write wscript.echo 4, we cannot write wscript.echo(4).
We will adhere to the following rules:
- no parentheses around the parameters of a procedure or function used as a procedure
- parentheses around the parameters of a function
5.3.4. Some examples of functions
Below are some examples of function definitions and uses:
Program
Function plusgrandque(byval i, ByVal j)
' returns boolean true if i>j, boolean false otherwise
' data verification
If isnumeric(i) And isnumeric(j) Then
If i>j Then
plusgrandque=true
Else
plusgrandque=false
End If
Else
wscript.echo "Arguments (" & i & "," & j & ") erronés"
plusgrandque=false
End If
Exit Function
End Function
Function rendUnTableau(byval n)
' makes an array of n elements
tableau=array()
' check validity of parameter n
If isnumeric(n) And n>=1 Then
ReDim Preserve tableau(n)
For i= 0 To n-1
tableau(i)=i
Next
Else
wscript.echo "Argument [" & n & "] erroné"
End If
' we return the result
rendUnTableau=tableau
End Function
Function argumentsVariables(byref arguments)
' arguments is an array of numbers whose sum is returned
somme=0
For i=0 To ubound(arguments)
somme=somme+arguments(i)
Next
argumentsVariables=somme
End Function
' two parameter-free functions declared in 2 different ways
Function sansParametres1
sansParametres=4
End Function
Function sansParametres2()
sansParametres=4
End Function
' ------------- calls to functions and procedures
' calls function plusgrandque
wscript.echo "plusgrandque(10,6)=" & plusgrandque(10,6)
wscript.echo "plusgrandque(6,10)=" & plusgrandque(6,10)
wscript.echo "plusgrandque(6,6)=" & plusgrandque(6,6)
wscript.echo "plusgrandque(6,'a')=" & plusgrandque(6,"a")
' calls to the rendUnTableau function
monTableau=rendUnTableau(10)
For i=0 To ubound(monTableau)
wscript.echo monTableau(i)
Next
monTableau=rendUnTableau(-6)
For i=0 To ubound(monTableau)
wscript.echo monTableau(i)
Next
' calls to the argumentsVariables function
wscript.echo "somme=" & argumentsVariables(array(-1,2,7,8))
wscript.echo "somme=" & argumentsVariables(array(-1,10,12))
' function calls without parameters
res=sansParametres1
res=sansParametres1()
sansParametres1
sansParametres1()
res=sansParametres2
res=sansParametres2()
sansParametres2
sansParametres2()
' end
wscript.quit 0
Results
plusgrandque(10,6)=Vrai
plusgrandque(6,10)=Faux
plusgrandque(6,6)=Faux
Arguments (6,a) erronés
plusgrandque(6,'a')=Faux
0
1
2
3
4
5
6
7
8
9
Argument [-6] erroné
somme=16
somme=21
somme=10
Comments
- The `rendUnTableau` function demonstrates that a function can return multiple results rather than just one. It simply needs to place them in an array variant and return that variant as the result.
- Conversely, the argumentsVariables function demonstrates that you can write a function that accepts a variable number of arguments. Here, too, you simply need to place them in an array variant and make this variant a function parameter.
5.3.5. Output parameter or function result
Suppose that the analysis of an application has shown the need for a module M with input parameters Ei and output parameters Sj. Recall that input parameters are information that the calling program provides to the called program, and conversely, output parameters are information that the called program provides to the calling program. In VBScript, there are several solutions for output parameters:
- If there is only one output parameter, it can be made the result of a function. There is then no longer an output parameter, but simply a function result.
- If there are n output parameters, one of them can serve as the function result, with the remaining n-1 acting as output parameters. Alternatively, instead of a function, one can use a procedure with n output parameters. One can also use a function that returns an array containing the n values to be returned to the calling program. Recall that the called program returns its results to the calling program by value. This copying is avoided when output parameters are passed by reference. This latter solution therefore saves time.
5.4. The VBScript program for sorting values
We began our discussion of modular programming with an algorithmic study of sorting numerical values entered via the keyboard. Here is the VBScript implementation that could be used:
Program
' main program
Option Explicit
Dim T ' the table of values to be sorted
' reading values
T=lire_tableau
' value sorting
trier_tableau T
' display of sorted values
ecrire_tableau T
' end
wscript.quit 0
' ---------- functions & procedures
' -------- lire_tableau
Function lire_tableau
' values are requested
wscript.stdout.write "Tapez les valeurs à trier sous la forme val1 val2 ... valn : "
' we read them
Dim valeurs
valeurs=wscript.stdin.readLine
' we put them in a table
lire_tableau=split(valeurs," ")
End Function
' -------- ecrire_tableau
Sub ecrire_tableau(byref T)
' displays the contents of table T
wscript.echo join(T," ")
End Sub
' -------- trier_tableau
Sub trier_tableau (byref T)
' sorts array T in ascending order
' find the imax index of the T[0..ifin] array
' to exchange T[imax] with the last element of array T[0..ifin]
' then start again with an array with 1 fewer element
Dim ifin, imax, temp
For ifin=ubound(T) To 1 Step -1
' find the imax index of the T[0..ifin] array
imax=chercher_max(T,ifin)
' we exchange the max with the last element of array T[0..ifin]
temp=T(ifin):T(ifin)=T(imax):T(imax)=temp
Next
End Sub
' -------- chercher_max
Function chercher_max(byRef T, ByVal ifin)
' find the imax index of the T[0..ifin] array
Dim i, imax
imax=0
For i=1 To ifin
If cdbl(T(i))>cdbl(T(imax)) Then imax=i
Next
' We return the result
chercher_max=imax
End Function
Results
Comments:
- The swap module identified in the initial algorithm was not implemented as a VBScript module here because it was deemed too simple to warrant a separate module.
5.5. The TAX program in modular form
We revisit the tax calculation program, this time written in a modular form
Program
' calculating a taxpayer's tax liability
' the program must be called with three parameters: married children salary
' married: character Y if married, N if unmarried
' children: number of children
' salary: annual salary without cents
' mandatory variable declaration
Option Explicit
Dim erreur
' retrieve arguments and check their validity
Dim marie, enfants, salaire
erreur=getArguments(marie,enfants,salaire)
' mistake?
If erreur(0)<>0 Then wscript.echo erreur(1) : wscript.quit erreur(0)
' retrieve the data needed to calculate taxes
Dim limites, coeffR, coeffN
getData limites,coeffR,coeffN
' the result is displayed
wscript.echo "impôt=" & calculerImpot(marie,enfants,salaire,limites,coeffR,coeffN)
' leave without error
wscript.quit 0
' ------------ functions and procedures
' ----------- getArguments
Function getArguments(byref marie, ByRef enfants, ByRef salaire)
' must retrieve three values passed as arguments to the main program
' an argument is passed to the program without spaces in front and behind it
' use regular expressions to check data validity
' returns an error array variant with 2 values
' error(0): error code, 0 if no error
' error(1): error message if error otherwise empty string
Dim syntaxe
syntaxe= _
"Syntaxe : pg marié enfants salaire" & vbCRLF & _
"marié : caractère O si marié, N si non marié" & vbCRLF & _
"enfants : nombre d'enfants (entier >=0)" & vbCRLF & _
"salaire : salaire annuel sans les centimes (entier >=0)"
' we check that there are 3 arguments
Dim nbArguments
nbArguments=wscript.arguments.count
If nbArguments<>3 Then
' error msg
getArguments= array(1,syntaxe & vbCRLF & vbCRLF & "erreur : nombre d'arguments incorrect")
' end
Exit Function
End If
Dim modele, correspondances
Set modele=new regexp
' marital status must be among the characters oOnN
modele.pattern="^[oOnN]$"
Set correspondances=modele.execute(wscript.arguments(0))
If correspondances.count=0 Then
' error msg
getArguments=array(2,syntaxe & vbCRLF & vbCRLF & "erreur : argument marie incorrect")
' we leave
Exit Function
End If
' the value
If lcase(wscript.arguments(0)) = "o"Then
marie=true
Else
marie=false
End If
' children must be an integer >=0
modele.pattern="^\d{1,2}$"
Set correspondances=modele.execute(wscript.arguments(1))
If correspondances.count=0 Then
' error
getArguments= array(3,syntaxe & vbCRLF & vbCRLF & "erreur : argument enfants incorrect")
' we leave
Exit Function
End If
' the value
enfants=cint(wscript.arguments(1))
' salary must be an integer >=0
modele.pattern="^\d{1,9}$"
Set correspondances=modele.execute(wscript.arguments(2))
If correspondances.count=0 Then
' error
getArguments= array(4,syntaxe & vbCRLF & vbCRLF & "erreur : argument salaire incorrect")
' we leave
Exit Function
End If
' the value
salaire=clng(wscript.arguments(2))
' finished without error
getArguments=array(0,"")
End Function
' ----------- getData
Sub getData(byref limites, ByRef coeffR, ByRef coeffN)
' we define the data needed to calculate the tax in 3 tables
limites=array(12620,13190,15640,24740,31810,39970,48360, _
55790,92970,127860,151250,172040,195000,0)
coeffr=array(0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45, _
0.5,0.55,0.6,0.65)
coeffn=array(0,631,1290.5,2072.5,3309.5,4900,6898.5,9316.5, _
12106,16754.5,23147.5,30710,39312,49062)
End Sub
' ----------- calculerImpot
Function calculerImpot(byval marie,ByVal enfants,ByVal salaire, ByRef limites, ByRef coeffR, ByRef coeffN)
' the number of shares is calculated
Dim nbParts
If marie=true Then
nbParts=(enfants/2)+2
Else
nbParts=(enfants/2)+1
End If
If enfants>=3 Then nbParts=nbParts+0.5
' we calculate the family quotient and taxable income
Dim revenu, qf
revenu=0.72*salaire
qf=revenu/nbParts
' tax calculation
Dim i, impot
i=0
Do While i<ubound(limites) And qf>limites(i)
i=i+1
Loop
calculerImpot=int(revenu*coeffr(i)-nbParts*coeffn(i))
End Function
Comments
- The getArguments function retrieves the taxpayer's information (spouse, children, salary). Here, they are passed as arguments to the VBScript program. If this were to change—for example, if these arguments came from a graphical user interface—only the getArguments procedure would need to be rewritten, not the others.
- The getArguments function can detect errors in the arguments. When this happens, one could have decided to stop the program’s execution within the getArguments function using a wscript.quit statement. This should never be done within a function or procedure. If a function or procedure detects an error, it must signal this in some way to the calling program. It is up to the calling program to decide whether to stop execution or not, not the procedure. In our example, the calling program might decide to ask the user to re-enter the incorrect data via the keyboard rather than stopping execution.
- Here, the getArguments function returns an array variant where the first element is an error code (0 if no error) and the second is an error message if an error occurred. By checking the returned result, the calling program can determine whether an error occurred or not.
- The getData procedure retrieves the data needed to calculate the tax. Here, this data is defined directly within the getData procedure. If this data were to come from another source—such as a file or a database—only the getData procedure would need to be rewritten, not the others.
- The `calculerImpot` function calculates the tax once all the data has been obtained, regardless of how it was obtained.
- Note, therefore, that modular coding allows for the (re)use of certain modules in different contexts. This concept has been heavily developed over the past twenty years within the concept of objects.







