5. De functies en procedures
5.1. De vooraf gedefinieerde functies van VBScript
De rijkdom van een taal is grotendeels af te leiden uit de functiebibliotheek; deze functies kunnen in objecten worden ingekapseld onder de naam methoden. In dit opzicht kan men stellen dat VBScript vrij beperkt is.
De volgende tabel geeft een overzicht van de functies van VBScript buiten objecten om. We zullen hier niet in detail op ingaan. Hun naam geeft doorgaans al een indicatie van hun functie. De lezer kan de documentatie raadplegen voor meer informatie over een bepaalde functie.
Abs | Array | Asc | Atn |
CBool | CByte | CCur | CDate |
CDbl | Chr | CInt | CLng |
Omzettingen | Cos | CreateObject | CSng |
Datum | DateAdd | DateDiff | DatePart |
DateSerial | DateValue | Dag | Afgeleide wiskunde |
Eval | Exp | Filter | FormatCurrency |
FormatDateTime | FormatNumber | FormatPercent | GetLocale |
GetObject | GetRef | Hex | Uur |
InputBox | InStr | InStrRev | Int, Fixs |
IsArray | IsDate | IsEmpty | IsNull |
IsNumeric | IsObject | Join | LBound |
LCase | Links | Len | LoadPicture |
Log | LTrim; RTrim; en Trims | Wiskunde | Mid |
Minute | Maand | MonthName | MsgBox |
Nu | okt | Vervangen | RGB |
Rechts | Rnd | Rond | ScriptEngine |
ScriptEngineBuildVersion | ScriptEngineMajorVersion | ScriptEngineMinorVersion | Tweede |
SetLocale | Sgn | Sin | Spatie |
Split | Sqr | StrComp | String |
Tan | Tijd | Timer | TimeSerial |
TimeValue | TypeName | UBound | UCase |
VarType | Weekdag | WeekdayName | Jaar |
5.2. Modulaire programmering
Het beschrijven van de geprogrammeerde oplossing voor een probleem houdt in dat men de reeks elementaire handelingen beschrijft die door de computer kunnen worden uitgevoerd en waarmee het probleem kan worden opgelost. Afhankelijk van de programmeertaal zijn deze elementaire handelingen meer of minder geavanceerd. Voorbeelden hiervan zijn:
- gegevens van het toetsenbord of de schijf inlezen
- gegevens weergeven op het scherm, afdrukken, opslaan op schijf, enz.
- uitdrukkingen berekenen
- door een bestand navigeren
- ...
Het beschrijven van een complex probleem kan duizenden van deze elementaire instructies of zelfs meer vereisen. Het is dan voor de menselijke geest erg moeilijk om een totaalbeeld van een programma te krijgen. Gezien deze moeilijkheid om het probleem in zijn geheel te begrijpen, wordt het daarom opgesplitst in deelproblemen die eenvoudiger op te lossen zijn. Laten we het volgende probleem eens bekijken: een lijst met numerieke waarden die via het toetsenbord zijn ingevoerd, sorteren en de gesorteerde lijst op het scherm weergeven.
In eerste instantie kan de oplossing als volgt worden beschreven:
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 hebben het probleem opgesplitst in drie deelproblemen, die eenvoudiger op te lossen zijn. De algoritmische notatie is vaak formeler dan de vorige en het algoritme ziet er dan als volgt uit:
waarbij T een array vertegenwoordigt. De bewerkingen
zijn niet-elementaire bewerkingen die op hun beurt moeten worden beschreven door elementaire bewerkingen. Dit gebeurt in zogenaamde modules. De gegevens T worden een parameter van de module genoemd. Dit is informatie die het aanroepende programma doorgeeft aan de aangeroepen module (invoerparameter) of ontvangt van de aangeroepen module (uitvoerparameter). De parameters van een module zijn dus de gegevens die worden uitgewisseld tussen het aanroepende programma en de aangeroepen module.
module lire_tableau(T) | ![]() |
module trier_tableau(T) | ![]() |
module écrire_tableau(T) | ![]() |
De module lire_tableau(T) zou als volgt kunnen worden beschreven:
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
Hier hebben we de module lire_tableau voldoende beschreven. De drie benodigde acties kunnen namelijk direct in VBScript worden omgezet. Voor de laatste actie is het gebruik van de functie split vereist. Als VBScript deze functie niet zou hebben, zou actie 3 op haar beurt moeten worden opgesplitst in elementaire acties die een direct equivalent in VBScript hebben.
De module écrire_tableau(T) zou als volgt kunnen worden beschreven:
début
construire chaîne texte "valeur1,valeur2,...." à partir du tableau T
écrire texte
fin
De module écrire_tableau(T) zou als volgt kunnen worden beschreven (ervan uitgaande dat de indices van de elementen van T bij 0 beginnen):
début
N<-- indice dernier élément du tableau T
pour IFIN variant de N à 1
faire
//we zoeken de index IMAX van het grootste element van T
// IFIN is de index van het laatste element van T
chercher_max(T, IFIN, IMAX)
// het grootste element van T wordt verwisseld met het laatste element van T
échanger (T, IMAX, IFIN)
finfaire
FIN
Hier maakt het algoritme opnieuw gebruik van niet-elementaire acties:
. chercher_max(T, IFIN, IMAX)
. échanger(T, IMAX, IFIN)
chercher_max(T, IFIN, IMAX) is de index IMAX van het grootste element in de array T, waarvan de index van het laatste element IFIN is.
![]() |
uitwisselen(T, IMAX, IFIN) wisselt twee elementen van de array T uit, namelijk die met index IMAX en IFIN.
![]() |
De nieuwe niet-elementaire bewerkingen moeten dus worden beschreven.
module chercher_max(A, IFIN, IMAX) | |
module uitwisselen(T IMAX, IFIN) |
Het oorspronkelijke probleem is volledig beschreven aan de hand van elementaire VBScript-bewerkingen en kan nu dus in deze taal worden vertaald. Opgemerkt moet worden dat elementaire bewerkingen van taal tot taal kunnen verschillen en dat bij de analyse van een probleem dus op een bepaald moment rekening moet worden gehouden met de gebruikte programmeertaal. Een object dat in de ene taal bestaat, hoeft in een andere taal niet te bestaan, wat dan weer gevolgen heeft voor het gebruikte algoritme. Als een taal bijvoorbeeld een sorteerfunctie heeft, zou het hier absurd zijn om daar geen gebruik van te maken.
Het principe dat hier wordt toegepast, is dat van de zogenaamde top-down-analyse. Als we de structuur van de oplossing weergeven, krijgen we het volgende:
![]() |
We hebben een boomstructuur.
5.3. De VBScript-functies en -procedures
Zodra de modulaire analyse is uitgevoerd, kan de programmeur de modules van zijn algoritme vertalen naar VBScript-code zoals fonctions of procédures. Zowel fonctions als procédures accepteren invoer- en uitvoerparameters, maar fonction levert een resultaat op dat in uitdrukkingen kan worden gebruikt, terwijl procédure dat niet doet.
5.3.1. Declaratie van VBScript-functies en -procedures
De declaratie van een VBScript-procedure is als volgt
en die van een functie
Om het resultaat weer te geven, moet de functie een toewijzingsinstructie bevatten waarmee het resultaat wordt toegewezen aan een variabele met de naam van de functie:
functienaam=resultaat
De uitvoering van een functie of procedure wordt op twee manieren beëindigd:
- bij het tegenkomen van de instructie voor het einde van de functie (end function) of het einde van de procedure (end sub)
- bij het tegenkomen van de instructie voor het verlaten van de functie (exit function) of procedure (exit sub)
Voor de functie geldt dat het resultaat moet zijn toegewezen aan een variabele met de naam van de functie voordat deze wordt beëindigd met een end function of exit function.
5.3.2. Manieren om parameters door te geven aan een functie of procedure
Bij de declaratie van de invoer- en uitvoerparameters van een functie of procedure wordt de wijze (byRef, byVal) gespecificeerd waarop de parameter van het aanroepende programma naar het aangeroepen programma wordt doorgegeven:
sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)
function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)
Wanneer de overdrachtsmodus byRef of byVal niet is gespecificeerd, wordt de modus byRef gebruikt.
Effectieve parameters, formele parameters
Stel dat er een VBScript-functie is gedefinieerd door
De parameters parmamFormi die in de definitie van de functie of procedure worden gebruikt, worden formele parameters genoemd. De bovenstaande functie kan vanuit het hoofdprogramma of vanuit een andere module worden aangeroepen met een instructie zoals:
De parameters parmamEffi die bij het aanroepen van de functie of procedure worden gebruikt, worden effectieve parameters genoemd. Wanneer de uitvoering van de functie nomFonction begint, krijgen de formele parameters de waarden van de bijbehorende effectieve parameters. De sleutelwoorden byRef en byVal bepalen de wijze waarop deze waarden worden doorgegeven.
Overdracht per waarde (byVal)
Wanneer een formele parameter deze overdrachtswijze specificeert, zijn de formele parameter en de effectieve parameter twee verschillende variabelen. De waarde van de effectieve parameter wordt vóór de uitvoering van de functie of procedure naar de formele parameter gekopieerd. Als de functie of procedure tijdens de uitvoering de waarde van de formele parameter wijzigt, heeft dit geen invloed op de waarde van de bijbehorende effectieve parameter. Deze overdrachtswijze is zeer geschikt voor invoerparameters van de functie of procedure.
![]() |
Overdrachtswijze via verwijzing (byRef)
Deze overdrachtswijze is de standaardwijze als er geen overdrachtswijze voor de parameter is opgegeven. Wanneer een formele parameter deze overdrachtswijze specificeert, zijn de formele parameter en de bijbehorende effectieve parameter één en dezelfde variabele. Als de functie dus de formele parameter wijzigt, wordt ook de effectieve parameter gewijzigd. Deze overdrachtswijze is zeer geschikt voor:
- uitvoerparameters, omdat de waarde daarvan moet worden doorgegeven aan het aanroepende programma
- voor invoerparameters die moeilijk te kopiëren zijn, zoals tabellen
![]() |
Het volgende programma toont voorbeelden van parameterdoorgave:
Programma |
|
Resultaten |
Opmerkingen
- In een VBScript-script is er geen specifieke plaats voor functies en procedures. Ze kunnen overal in de brontekst staan. Over het algemeen worden ze aan het begin of aan het einde gegroepeerd en zorgt men ervoor dat het hoofdprogramma een aaneengesloten blok vormt.
5.3.3. Syntaxis voor het aanroepen van functies en procedures
Stel dat er een procedure p is die formele parameters pf1, pf2, ... accepteert
- dan gebeurt de aanroep van procedure p in de vorm
zonder haakjes rond de parameters
- als de procedure p geen parameters accepteert, kan men naar keuze de aanroep p of p() gebruiken en de declaratie sub p of sub p()
Stel dat een functie f de formele parameters pf1, pf2, ... accepteert
- de aanroep van de functie f gebeurt in de vorm
De haakjes rond de parameters zijn verplicht. Als de functie f geen parameters heeft, kan men naar keuze de aanroep f of f() gebruiken, evenals de declaratie function f of function f().
- Het resultaat van de functie f kan door het aanroepende programma worden genegeerd. De functie f wordt dan beschouwd als een procedure en volgt de regels voor het aanroepen van procedures. Men schrijft dan f pe1, pe2, ... (zonder haakjes) om de functie f aan te roepen.
Als de functie of procedure een objectmethode is, lijken de regels enigszins af te wijken en niet uniform te zijn.
- Zo kan men bijvoorbeeld MyFile.WriteLine "Dit is een test." of MyFile.WriteLine("Dit is een test.") schrijven
- maar hoewel men wscript.echo 4 kan schrijven, kan men niet wscript.echo(4) schrijven.
We houden ons aan de volgende regels:
- geen haakjes rond de parameters van een procedure of een functie die als procedure wordt gebruikt
- haakjes rond de parameters van een functie
5.3.4. Enkele voorbeelden van functies
Hieronder volgen enkele voorbeelden van definities en toepassingen van functies:
Programma |
|
Resultaten |
Opmerkingen
- De functie rendUnTableau laat zien dat een functie meerdere resultaten kan retourneren in plaats van slechts één. Het volstaat om deze in een array-variant te plaatsen en deze variant als resultaat te retourneren.
- Omgekeerd laat de functie argumentsVariables zien dat men een functie kan schrijven die een variabel aantal argumenten accepteert. Ook hier volstaat het om deze in een array-variant te plaatsen en deze variant als parameter van de functie te gebruiken.
5.3.5. Uitvoerparameter of resultaat van een functie
Stel dat uit de analyse van een toepassing is gebleken dat er behoefte is aan een module M met invoerparameters Ei en uitvoerparameters Sj. Laten we niet vergeten dat invoerparameters informatie zijn die het aanroepende programma aan het aangeroepen programma doorgeeft, en dat omgekeerd uitvoerparameters informatie zijn die het aangeroepen programma aan het aanroepende programma doorgeeft. In VBScript zijn er verschillende oplossingen voor uitvoerparameters:
- als er slechts één uitgangsparameter is, kan deze als het resultaat van een functie worden gebruikt. Er is dan geen uitgangsparameter meer, maar gewoon een functie-resultaat.
- Als er n uitvoerparameters zijn, kan één daarvan dienen als functie-resultaat, terwijl de overige n-1 uitvoerparameters blijven. Men kan ook geen functie gebruiken, maar een procedure met n uitvoerparameters. Men kan tevens een functie gebruiken die een array retourneert waarin de n waarden zijn geplaatst die aan het aanroepende programma moeten worden teruggegeven. We herinneren eraan dat het aangeroepen programma zijn resultaten aan het aanroepende programma teruggeeft door waarden te kopiëren. Deze kopieerbewerking wordt vermeden in het geval van uitgangsparameters die bij verwijzing worden doorgegeven. Deze laatste oplossing levert dus een tijdwinst op.
5.4. Het VBScript-programma voor het sorteren van waarden
We zijn de bespreking van modulair programmeren begonnen met de algoritmische analyse van het sorteren van numerieke waarden die via het toetsenbord zijn ingevoerd. Hier volgt de vertaling VBScript die hiervan gemaakt zou kunnen worden:
Opmerkingen:
- de module échanger, die in het oorspronkelijke algoritme was geïdentificeerd, is hier niet als VBScript-module geïmplementeerd omdat deze te eenvoudig werd geacht om een aparte module te rechtvaardigen.
5.5. Het programma IMPOTS in modulaire vorm
We nemen het programma voor de belastingberekening opnieuw op, ditmaal geschreven in modulaire vorm
Opmerkingen
- Met de functie getArguments kan informatie (echtgenote, kinderen, salaris) van de belastingplichtige worden opgehaald. Hier worden deze gegevens als argumenten doorgegeven aan het VBScript-programma. Mocht dit veranderen, bijvoorbeeld als deze argumenten afkomstig zouden zijn van een grafische interface, dan hoeft alleen de procedure getArguments te worden herschreven en niet de andere.
- De functie getArguments kan fouten in de argumenten detecteren. Wanneer dit gebeurt, had men kunnen besluiten de uitvoering van het programma in de functie getArguments te stoppen met een instructie wscript.quit. Dit mag nooit in een functie of procedure worden gedaan. Als een functie of procedure een fout detecteert, moet deze dit op de een of andere manier melden aan het aanroepende programma. Het is aan het aanroepende programma om te beslissen of de uitvoering al dan niet wordt gestopt, niet aan de procedure. In ons voorbeeld zou het aanroepende programma kunnen besluiten om de gebruiker te vragen de foutieve gegevens opnieuw via het toetsenbord in te voeren, in plaats van de uitvoering te stoppen.
- Hier retourneert de functie getArguments een arrayvariant waarvan het eerste element een foutcode is (0 als er geen fout is) en het tweede element een foutmelding als er een fout is opgetreden. Door het verkregen resultaat te controleren, kan het aanroepende programma vaststellen of er al dan niet een fout is opgetreden.
- Met de procedure getData kunnen de gegevens worden verkregen die nodig zijn voor de berekening van de belasting. Hier worden deze gegevens rechtstreeks gedefinieerd in de procedure getData. Als deze gegevens uit een andere bron zouden moeten komen, bijvoorbeeld uit een bestand of een database, zou alleen de procedure getData herschreven moeten worden en niet de andere.
- Met de functie calculerImpot kan de belasting worden berekend zodra alle gegevens zijn verkregen, ongeacht de manier waarop deze zijn verkregen.
- Er zij dus opgemerkt dat een modulaire opzet het (her)gebruik van bepaalde modules in verschillende contexten mogelijk maakt. Dit concept is de afgelopen twintig jaar sterk verder ontwikkeld binnen het objectgeoriënteerde denken.







