\n Przejdź do treści

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.

Przyjrzyj się zamieszczonemu poniżej fragmentowi listingu 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.

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.

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.

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.

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.

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…”.

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.

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).

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).

W linii 15 za pomocą obiektu WScript.Echo jest wyświetlany komunikat informujący o zakończeniu i-tego przebiegu skryptu.

Natomiast w linii 16 skrypt zostaje zatrzymany na czas (w milisekundach) określony przez stałą Godzina.

Po wykonaniu ośmiu powtórzeń skrypt kończy działanie.

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.

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.

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.

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.

0 komentarzy

Zostaw komentarz