Szydełkowanie skryptu
Skrypt ułatwia automatyzację operacji wykonywanych w systemie. Automatyzacja to nie tylko łączenie kilku czynności w jeden proces, ale także możliwość wielokrotnego wykonywania danej operacji. Chcesz na przykład, by skrypt wykonywał się sam w regularnych odstępach czasu? Wystarczy użyć pętli.
Odczyt wybranych wartości rejestru Windows za pomocą skryptu VBScript, który był omówiony w poprzednich odcinkach kursu, to z pewnością przydatna umiejętność. Wszak w rejestrze przechowywane są niemal wszystkie informacje o każdym aspekcie działania systemu operacyjnego. Niekiedy jednak okazuje się, że jednorazowe wykonanie jakiejś operacji nie wystarcza, trzeba ją wykonać wielokrotnie. I na to jest sposób – wystarczy dodać pętle.
Pętle to konstrukcje umożliwiające wielokrotne wykonanie wybranego fragmentu kodu. W przypadku skryptów w języku VBScript do twojej dyspozycji pozostają następujące konstrukcje:
For Each … Next
For … Next
Do While
Do Until
Kiedy używać danej konstrukcji i dlaczego? Odpowiedzią niech będą konkretne przykłady kodu.
Pętla For Each … Next w praktyce
Przyjrzyj się zamieszczonemu poniżej fragmentowi listingu 1.
Krok 1
Z pewnością zauważyłeś trzy wyodrębnione części skryptu. Sekcja nagłówka (linie od 1 do 5) zawiera znane już z poprzednich odcinków kursu wyrażenia, takie jak m.in. Option Explicit czy deklaracje zmiennych za pomocą Dim.
Krok 2
Kolejny fragment – linia 7 – to sekcja referencyjna, w której, przypomnijmy, przypisujesz zadeklarowanym wcześniej zmiennym odpowiednie wartości. W tym przypadku zmiennej DrivesCollection przyporządkowane zostało zapytanie do systemu o liczbę dysków logicznych za pomocą funkcji GetObject, metody ExecQuery i mechanizmu Windows Management Instrumentation (WMI). Ponieważ jednak na razie zajmujemy się pętlami, a nie funkcjami czy zagadnieniami związanymi z WMI, pozostawiamy tę linię bez dodatkowych wyjaśnień – po prostu ją wpisz.
Krok 3
Ostatnie trzy linie 9–11 to sekcja robocza zawierająca właśnie pętlę For Each … Next. W opisywanym przykładzie wynikiem działania skryptu będzie wyświetlenie liter dysków twardych lub partycji, jakie są zdefiniowane w danym systemie.
Krok 4
Zapewne pamiętasz, że do wyświetlania jakichkolwiek komunikatów służy obiekt WScript i jego metoda Echo. Zauważ, że powyższy skrypt w momencie wykonania wyświetli tyle liter dysków, ile masz w swoim komputerze, mimo że użyłeś przecież tylko jednego obiektu WScript.Echo.
Krok 5
Skąd komputer „wie”, ile liter ma wyświetlić? Oto jak można na „ludzki” język przetłumaczyć trzy ostatnie wiersze skryptu: „Dla każdego obiektu (dysku) odnalezionego w wyniku zapytania systemu poprzez zmienną DrivesCollection wyświetl każdy znaleziony obiekt (literę dysku)”. Zatem dzięki pętli komunikat będzie zawierał tyle liter dysku, ile liter dysków zostało w systemie faktycznie przyporządkowanych dyskom logicznym. Dodatkową zaletą pętli For Each … Next jest to, że możesz przypisać dowolne polecenie każdemu obiektowi znajdującemu się w jakimś zbiorze, nie wiedząc zarazem, ile jest tych obiektów w zbiorze.
Krok 6
W przykładowym skrypcie nie tylko pętla For Each … Next jest nowym elementem. Pomijając wiersz 7, zwróć uwagę na sekcję nagłówka i zawartą w niej, w linii 3, deklarację stałej DriveType. Jak łatwo zauważyć, stała definiowana jest wyrażeniem Const. Ponadto najczęściej od razu definiowanej stałej przypisywana jest określona wartość, która nie ulega zmianie przez cały skrypt. W naszym przykładzie wartość 3 wzięła się stąd, że zawęża pole zapytania skierowanego do mechanizmu WMI tylko do dysków twardych. Więcej informacji o tym, jak odpytywać mechanizm WMI na temat innego typu dysków, w ramce „Jak pytać system...”.
Pętla For … Next w praktyce
Podstawową różnicą między wcześniej przedstawioną pętlą For Each … Next a For … Next jest to, że w pierwszej liczba powtórzeń operacji nie jest podawana przez użytkownika, lecz wynika z liczby elementów jakiegoś zbioru (w naszym przykładzie – liczby dysków w komputerze). Natomiast druga konstrukcja, choć używa się jej bardzo podobnie, wymaga dokładnego określenia przez autora skryptu liczby powtórzeń. Do czego można ją wykorzystać? Poprzedni skrypt wyświetlał litery dysków w systemie. Oto, jak należałoby go zmodyfikować, by wyświetlał litery dysków sieciowych (których liczba może się zmieniać) i by wykonał tę operację np. ośmiokrotnie w odstępach godzinnych – listing 2.
Krok 1
Skupmy się tylko na różnicach między tym a poprzednim skryptem. Zwróć uwagę na zamieszczone w sekcji nagłówkowej: deklarację (z przypisaniem wartości) stałej Godzina w linii 4 (wartość to po prostu liczba milisekund, tak bowiem odlicza czas interpreter VBScriptu) oraz deklarację zmiennej i w linii 7, będącej po prostu licznikiem iteracji (liczby powtórzeń pętli For … Next). Ponadto uległa zmianie wartość stałej DriveType (skrypt ma tym razem wypisywać litery dysków sieciowych).
Krok 2
Pętla For … Next „otacza” wcześniej utworzoną pętl ę wypisującą litery dysków. W linii 11 jest określana liczba powtórzeń (osiem).
Krok 3
W linii 15 za pomocą obiektu WScript.Echo jest wyświetlany komunikat informujący o zakończeniu i-tego przebiegu skryptu.
Krok 4
Natomiast w linii 16 skrypt zostaje zatrzymany na czas (w milisekundach) określony przez stałą Godzina.
Krok 5
Po wykonaniu ośmiu powtórzeń skrypt kończy działanie.
Dodatkowe pętle VBScript
VBScript udostępnia programiście skryptów jeszcze dwie inne konstrukcje pętli. Przedstawimy je nie na przykładzie konkretnego kodu, lecz w sposób syntetyczny.
Pętla Do While … Loop
Kolejna konstrukcja pętli działa na nieco odmiennej zasadzie niż pętla For… Nie ma tutaj analizy liczby elementów zbioru, czy też skrupulatnego odliczania powtórzeń operacji. Pętla Do While … Loop jest powtarzana tak długo, jak długo jest spełniony pewien warunek. Przykład:
Do While woda_nie_zagotowana
Podgrzewaj
Loop
Pętlę tego typu stosujesz, gdy podtrzymującym ją warunkiem jest stan znany w trakcie wykonywania.
Pętla Do Until … Loop
Ostatnia z konstrukcji pętli stosowanych w VBScripcie jest bardzo podobna do poprzedniej. Tak naprawdę różnica sprowadza się do tego, że pętla Do While … Loop jest wykonywana tak długo, dopóki warunek ją podtrzymujący jest prawdą. Z kolei Do Until … Loop działa odwrotnie. Skrypt będzie tak długo zapętlony, dopóki określony warunek jest fałszem. Odwołując się do podanego przykładu z gotowaniem wody, można rzecz ująć następująco:
Do Until woda_zagotowana
Podgrzewaj
Loop
Zauważ, że wynik działania obu konstrukcji jest identyczny – zagotowana woda. Niemniej możliwość określenia przeciwstawnych warunków okazuje się bardzo przydatna.
Dokumentacja wbudowana w skrypt
Gdy spojrzysz na dowolny skrypt pozbawiony jakiejkolwiek dokumentacji czy wbudowanych w kod skryptu komentarzy, połapanie się, o co chodzi w danym skrypcie, może nastręczać nie lada problemów. Warto dodać, że nie ma w tym przypadku na ogół znaczenia, czy to ty, czy też ktoś inny jest autorem danego skryptu. Tymczasem wystarczy dodawać do kodu skryptu odpowiednie komentarze, a treść skryptu i zamiary programisty będą jasne na pierwszy rzut oka. Przyjrzyj się fragmentowi skryptu w listingu 3. Chyba od razu dostrzegasz przejrzystość takiego przekazu. Oczywiście treści poprzedzone znakiem apostrofu (‘) to komentarze twórcy skryptu. Dzięki takim wstawkom kod i przeznaczenie skryptu są od razu jasne. Nie da się również przecenić walorów edukacyjnych tak dobrze udokumentowanych skryptów. Dlatego pamiętaj znak apostrofu i komentuj co bardziej newralgiczne partie kodu. Gdy wrócisz do skryptu po dłuższym czasie, od razu będziesz wiedział, o co chodzi.