5. Funkcje i procedury
5.1. Wbudowane funkcje języka VBScript
Bogactwo języka wynika w dużej mierze z biblioteki funkcji, które mogą być enkapsulowane w obiektach pod nazwą metod. Pod tym względem można uznać, że VBScript jest raczej ubogi.
Poniższa tabela przedstawia funkcje VBScript poza obiektami. Nie będziemy ich szczegółowo omawiać. Ich nazwy zazwyczaj wskazują na ich przeznaczenie. Czytelnik powinien zapoznać się z dokumentacją, aby uzyskać szczegółowe informacje na temat konkretnej funkcji.
Abs | Array | Asc | Atn |
CBool | CByte | CCur | CDate |
CDbl | Chr | CInt | CLng |
Konwersje | Cos | CreateObject | CSng |
Data | DateAdd | DateDiff | DatePart |
DateSerial | DateValue | Dzień | Matematyka pochodna |
Ocena | Wykładnik | Filtr | FormatCurrency |
FormatDateTime | FormatNumber | FormatPercent | GetLocale |
GetObject | GetRef | Hex | Godzina |
InputBox | InStr | InStrRev | Międzynarodowe, Stałe |
IsArray | IsDate | IsEmpty | IsNull |
IsNumeric | IsObject | Dołącz | LBound |
LCase | W lewo | Len | LoadPicture |
Log | LTrim; RTrim; oraz wykończenia | Matematyka | Średnia |
Minuta | Miesiąc | MonthName | MsgBox |
Teraz | Październik | Zastąp | RGB |
Right | Rnd | Okrągły | ScriptEngine |
ScriptEngineBuildVersion | ScriptEngineMajorVersion | ScriptEngineMinorVersion | Drugi |
SetLocale | Sgn | Sin | Spacja |
Split | Sqr | StrComp | String |
Tan | Czas | Timer | TimeSerial |
TimeValue | TypeName | UBound | UCase |
VarType | Dzień tygodnia | WeekdayName | Rok |
5.2. Programowanie modułowe
Opisanie zaprogramowanego rozwiązania problemu oznacza opisanie sekwencji podstawowych czynności, które może wykonać komputer i które pozwalają rozwiązać ten problem. W zależności od języka programowania te podstawowe operacje są mniej lub bardziej złożone. Można tu wymienić na przykład:
- odczyt danych z klawiatury lub dysku
- zapis danych na ekranie, na drukarce, na dysku itp.
- obliczanie wyrażeń
- poruszanie się po pliku
- ...
Opisanie złożonego problemu może wymagać kilku tysięcy takich podstawowych instrukcji, a nawet więcej. W takiej sytuacji bardzo trudno jest ludzkiemu umysłowi uzyskać całościowy obraz programu. W obliczu tej trudności w ogarnięciu problemu w całości, dzielimy go na podproblemy, które łatwiej rozwiązać. Rozważmy następujący problem: posortowanie listy wartości liczbowych wpisanych z klawiatury i wyświetlenie posortowanej listy na ekranie.
W pierwszej kolejności rozwiązanie można opisać w następującej postaci:
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
Problem podzielono na trzy podproblemy, które są łatwiejsze do rozwiązania. Zapis algorytmiczny jest często bardziej sformalizowany niż poprzedni, a algorytm będzie wyglądał raczej następująco:
gdzie T oznacza tablicę. Operacje
są operacjami nieelementarnymi, które z kolei muszą być opisane za pomocą operacji elementarnych. Odbywa się to w tak zwanych modułach. Dane T nazywane są parametrem modułu. Jest to informacja, którą program wywołujący przekazuje do modułu wywoływanego (parametr wejściowy) lub otrzymuje od modułu wywoływanego (parametr wyjściowy). Parametry modułu to zatem informacje wymieniane między programem wywołującym a modułem wywoływanym.
moduł lire_tableau(T) | ![]() |
moduł trier_tableau(T) | ![]() |
moduł écrire_tableau(T) | ![]() |
Moduł lire_tableau(T) można opisać w następujący sposób:
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
W tym miejscu wystarczająco szczegółowo opisaliśmy moduł lire_tableau. Trzy niezbędne czynności mają bowiem bezpośredni odpowiednik w języku VBScript. Ostatnia z nich będzie wymagała użycia funkcji split. Gdyby język VBScript nie posiadał tej funkcji, czynność 3 musiałaby zostać z kolei podzielona na podstawowe czynności, które mają bezpośredni odpowiednik w języku VBScript.
Moduł écrire_tableau(T) można opisać w następujący sposób:
début
construire chaîne texte "valeur1,valeur2,...." à partir du tableau T
écrire texte
fin
Moduł écrire_tableau(T) można opisać w następujący sposób (zakładając, że indeksy elementów T zaczynają się od 0):
début
N<-- indice dernier élément du tableau T
pour IFIN variant de N à 1
faire
//szukamy indeksu IMAX największego elementu z T
// IFIN to indeks ostatniego elementu T
chercher_max(T, IFIN, IMAX)
// zamieniamy największy element z T na ostatni element z T
échanger (T, IMAX, IFIN)
finfaire
FIN
W tym miejscu algorytm ponownie wykorzystuje operacje nieelementarne:
. chercher_max(T, IFIN, IMAX)
. échanger(T, IMAX, IFIN)
chercher_max(T, IFIN, IMAX) zwraca indeks IMAX największego elementu tablicy T, której indeks ostatniego elementu wynosi IFIN.
![]() |
zamień(T, IMAX, IFIN) zamienia dwa elementy tablicy T o indeksach IMAX i IFIN.
![]() |
Należy zatem opisać nowe operacje nieelementarne.
moduł chercher_max(A, IFIN, IMAX) | |
moduł wymiany (T IMAX, IFIN) |
Pierwotny problem został w pełni opisany za pomocą podstawowych operacji języka VBScript i może zatem zostać przetłumaczony na ten język. Należy zauważyć, że podstawowe operacje mogą się różnić w zależności od języka programowania, dlatego analiza problemu musi w pewnym momencie uwzględniać używany język. Obiekt istniejący w jednym języku może nie istnieć w innym, co w konsekwencji może wpłynąć na zastosowany algorytm. Tak więc, gdyby dany język posiadał funkcję sortowania, nie wykorzystanie jej w tym przypadku byłoby absurdalne.
Zastosowana tutaj zasada to tzw. analiza z góry na dół. Jeśli przedstawimy szkielet rozwiązania, otrzymamy następujący obraz:
![]() |
Mamy strukturę drzewa.
5.3. Funkcje i procedury VBScript
Po przeprowadzeniu analizy modułowej programista może przełożyć moduły swojego algorytmu na kod VBScript, np. fonctions lub procédures. Zarówno fonctions, jak i procédures akceptują parametry wejściowe/wyjściowe, ale fonction zwraca wynik, który pozwala na wykorzystanie go w wyrażeniach, podczas gdy procédure takiego wyniku nie zwraca.
5.3.1. Deklaracja funkcji i procedur w VBScript
Deklaracja procedury VBScript wygląda następująco
a deklaracja funkcji wygląda następująco
Aby zwrócić wynik, funkcja musi zawierać instrukcję przypisania wyniku do zmiennej o nazwie funkcji:
nazwa_funkcji = wynik
Wykonanie funkcji lub procedury kończy się na dwa sposoby:
- po napotkaniu instrukcji zakończenia funkcji (end function) lub zakończenia procedury (end sub)
- po napotkaniu instrukcji wyjścia z funkcji (exit function) lub procedury (exit sub)
W przypadku funkcji należy pamiętać, że wynik musi zostać przypisany do zmiennej o nazwie funkcji, zanim funkcja zakończy się instrukcją end function lub exit function.
5.3.2. Sposoby przekazywania parametrów funkcji lub procedury
W deklaracji parametrów wejściowych i wyjściowych funkcji lub procedury określa się tryb (byRef, byVal) przekazywania parametru z programu wywołującego do programu wywoływanego:
sub nomProcédure([Byref/Byval] param1, [Byref/Byval] param2, ...)
function nomFonction([Byref/Byval] param1, [Byref/Byval] param2, ...)
Jeśli nie określono trybu przesyłania byRef lub byVal, stosowany jest tryb byRef.
Parametry rzeczywiste, parametry formalne
Niech vbscriptową funkcję zdefiniowano jako
Parametry parmamFormi użyte w definicji funkcji lub procedury nazywane są parametrami formalnymi. Powyższą funkcję można wywołać z programu głównego lub innego modułu za pomocą instrukcji typu:
Parametry parmamEffi używane w wywołaniu funkcji lub procedury nazywane są parametrami rzeczywistymi. Gdy rozpoczyna się wykonywanie funkcji nomFonction, parametry formalne przyjmują wartości odpowiadających im parametrów rzeczywistych. Słowa kluczowe byRef i byVal określają tryb przekazywania tych wartości.
Tryb przekazywania wartości (byVal)
Gdy parametr formalny określa ten tryb przekazywania, parametr formalny i parametr rzeczywisty są wówczas dwiema różnymi zmiennymi. Wartość parametru rzeczywistego jest kopiowana do parametru formalnego przed wykonaniem funkcji lub procedury. Jeśli funkcja lub procedura zmieni wartość parametru formalnego w trakcie swojego wykonywania, nie ma to żadnego wpływu na wartość odpowiadającego mu parametru rzeczywistego. Ten tryb przekazywania dobrze nadaje się do parametrów wejściowych funkcji lub procedury.
![]() |
Tryb przekazywania przez odwołanie (byRef)
Ten tryb przekazywania jest trybem domyślnym, jeśli nie określono żadnego trybu przekazywania parametru. Gdy parametr formalny określa ten tryb przekazywania, parametr formalny i odpowiadający mu parametr rzeczywisty stanowią jedną i tę samą zmienną. Zatem jeśli funkcja modyfikuje parametr formalny, modyfikowany jest również parametr rzeczywisty. Ten tryb przekazywania dobrze nadaje się do:
- dla parametrów wyjściowych, ponieważ ich wartości muszą zostać przekazane do programu wywołującego
- dla parametrów wejściowych, których przepisywanie jest uciążliwe, takich jak tabele
![]() |
Poniższy program przedstawia przykłady przekazywania parametrów:
Program |
|
Wyniki |
Komentarze
- W skrypcie VBScript nie ma wyznaczonego miejsca na funkcje i procedury. Mogą one znajdować się w dowolnym miejscu tekstu źródłowego. Zazwyczaj grupuje się je na początku lub na końcu, tak aby główny program stanowił ciągły blok.
5.3.3. Składnia wywoływania funkcji i procedur
Niech procedura p przyjmuje parametry formalne pf1, pf2, ...
- wywołanie procedury p odbywa się w postaci
bez nawiasów wokół parametrów
- jeśli procedura p nie przyjmuje żadnych parametrów, można bez różnicy użyć wywołania p lub p() oraz deklaracji sub p lub sub p()
Niech f będzie funkcją przyjmującą parametry formalne pf1, pf2, ...
- wywołanie funkcji f ma postać
Nawiasy wokół parametrów są obowiązkowe. Jeśli funkcja f nie przyjmuje żadnych parametrów, można bez różnicy użyć wywołania f lub f() oraz deklaracji function f lub function f().
- Wynik funkcji f może zostać zignorowany przez program wywołujący. Funkcja f jest wówczas traktowana jako procedura i podlega zasadom wywoływania procedur. Aby wywołać funkcję f, pisze się wówczas f pe1, pe2, ... (bez nawiasów).
Jeśli funkcja lub procedura jest metodą obiektu, wydaje się, że zasady są nieco inne i niejednolite.
- Można więc zapisać MyFile.WriteLine „To jest test.” lub MyFile.WriteLine („To jest test.”)
- ale choć można zapisać wscript.echo 4, nie można zapisać wscript.echo(4).
Będziemy przestrzegać następujących zasad:
- nie stosujemy nawiasów wokół parametrów procedury lub funkcji używanej jako procedura
- nawiasy wokół parametrów funkcji
5.3.4. Kilka przykładów funkcji
Poniżej znajduje się kilka przykładów definicji i zastosowań funkcji:
Program |
|
Wyniki |
Komentarze
- Funkcja rendUnTableau pokazuje, że funkcja może zwracać wiele wyników, a nie tylko jeden. Wystarczy, że umieści je w wariancie typu tablicowego i zwróci ten wariant jako wynik.
- Z kolei funkcja argumentsVariables pokazuje, że można napisać funkcję, która przyjmuje zmienną liczbę argumentów. Wystarczy również umieścić je w wariancie tablicowym i uczynić ten wariant parametrem funkcji.
5.3.5. Parametr wyjściowy lub wynik funkcji
Załóżmy, że analiza aplikacji wykazała konieczność zastosowania modułu M z parametrami wejściowymi Ei i parametrami wyjściowymi Sj. Przypomnijmy, że parametry wejściowe to informacje, które program wywołujący przekazuje programowi wywoływanym, a odwrotnie – parametry wyjściowe to informacje, które program wywoływany przekazuje programowi wywołującemu. W języku VBScript istnieje kilka rozwiązań dotyczących parametrów wyjściowych:
- jeśli istnieje tylko jeden parametr wyjściowy, można uczynić go wynikiem funkcji. Wówczas nie ma już parametru wyjściowego, a jedynie wynik funkcji.
- jeśli istnieje n parametrów wyjściowych, jeden z nich może pełnić rolę wyniku funkcji, a pozostałe n-1 pozostają parametrami wyjściowymi. Można również zrezygnować z funkcji na rzecz procedury z n parametrami wyjściowymi. Można również użyć funkcji, która zwróci tablicę, w której umieszczono n wartości do przekazania programowi wywołującemu. Należy pamiętać, że wywoływany program zwraca wyniki do programu wywołującego poprzez kopiowanie wartości. W przypadku parametrów wyjściowych przekazywanych przez odwołanie unika się tego kopiowania. W związku z tym to ostatnie rozwiązanie pozwala zaoszczędzić czas.
5.4. Program VBScript do sortowania wartości
Rozpoczęliśmy omówienie programowania modułowego od analizy algorytmicznej sortowania wartości liczbowych wprowadzanych z klawiatury. Oto przykładowy kod VBScript, który można by w tym celu stworzyć:
Uwagi:
- moduł échanger, który został zidentyfikowany w początkowym algorytmie, nie został tutaj zaimplementowany jako moduł w języku VBScript, ponieważ uznano go za zbyt prosty, by poświęcać mu osobny moduł.
5.5. Program IMPOTS w formie modułowej
Powracamy do programu do obliczania podatku, tym razem napisanego w formie modułowej
Komentarze
- Funkcja getArguments umożliwia pobranie informacji (małżonek, dzieci, wynagrodzenie) o podatniku. W tym przypadku informacje te są przekazywane jako argumenty do programu VBScript. Gdyby sytuacja uległa zmianie, na przykład gdyby argumenty te pochodziły z interfejsu graficznego, konieczna byłaby zmiana wyłącznie procedury getArguments, a nie pozostałych.
- Funkcja getArguments może wykrywać błędy w argumentach. Gdy tak się stanie, można by zdecydować o zatrzymaniu wykonywania programu w funkcji getArguments za pomocą instrukcji wscript.quit. Nigdy nie należy tego robić w funkcji ani procedurze. Jeśli funkcja lub procedura wykryje błąd, musi w jakiś sposób zgłosić go programowi wywołującemu. To program wywołujący podejmuje decyzję o zatrzymaniu lub kontynuowaniu wykonywania, a nie procedura. W naszym przykładzie program wywołujący mógłby zdecydować się na ponowne poproszenie użytkownika o wprowadzenie błędnych danych z klawiatury zamiast zatrzymywać wykonywanie.
- W tym przypadku funkcja getArguments zwraca tablicę, której pierwszy element to kod błędu (0, jeśli nie wystąpił błąd), a drugi – komunikat o błędzie, jeśli błąd wystąpił. Sprawdzając uzyskany wynik, program wywołujący może ustalić, czy wystąpił błąd, czy nie.
- Procedura getData pozwala uzyskać dane niezbędne do obliczenia podatku. W tym przypadku dane te są zdefiniowane bezpośrednio w procedurze getData. Gdyby dane te miały pochodzić z innego źródła, na przykład z pliku lub bazy danych, należałoby przepisać jedynie procedurę getData, a nie pozostałe.
- Funkcja calculerImpot umożliwia obliczenie podatku po uzyskaniu wszystkich danych, niezależnie od sposobu ich pozyskania.
- Należy zatem zauważyć, że programowanie modułowe umożliwia (ponowne) wykorzystanie niektórych modułów w różnych kontekstach. Koncepcja ta została w ciągu ostatnich dwudziestu lat znacznie rozwinięta w ramach paradygmatu obiektowego.







