Wprowadzenie do języka Visual Basic for Applications (1)
Sławomir Żaboklicki
Język programowania Visual Basic for Applications (VBA) jest dołączany do wszystkich aplikacji pakietu Office 97. Ma go Word, Excel, Access, PowerPoint, Binder. Jest też wbudowany w Microsoft Project. Outlook używa uproszczonej wersji VBA - języka VB Script. Dzięki VBA każdą z tych aplikacji można dopasować do indywidualnych potrzeb użytkowników (uzupełnienia lub zmiany zestawu poleceń oraz automatyzacji wymiany informacji pomiędzy aplikacjami.
Mimo, że MS Office 97 powstał w oparciu o doświadczenia milionów użytkowników poprzednich wersji programów, to jednak istnieje pewien margines wymagań nietypowych. Nawet jeżeli można spełnić te wymagania za pomocą już istniejących narzędzi (np. kopiowanie informacji przez Schowek), to przy częstym ich wykorzystywaniu praca staje się nużąca, łatwiej o pomyłkę. Wtedy właśnie opłacalną się staje automatyzacja powtarzanych wielokrotnie czynności. W przypadku pracy z jedną tylko aplikacją często można to zrobić za pomocą rejestratora makropoleceń. Jeżeli jednak w grę wchodzi współbieżne wykorzystywanie kilku aplikacji, wykonywanie bardziej złożonych sekwencji poleceń, to VBA jest niezastąpiony.
Chcąc rozpocząć programowanie w VBA dobrze jest poznać i zrozumieć takie pojęcia jak:
procedury i funkcje;
instrukcje przypisania, uruchomienia procedury, sterujące;
obiekty ich właściwości i metody;
typy danych.
W tym i w następnych artykułach publikowanych na krążkach ENTERA będziemy omawiali te pojęcia. Nasz kurs VBA został celowo zapisany w formie dokumentu MS Worda. Pozwoli to umieszczać w nim makropolecenia i procedury, które demonstrować będą działanie poszczególnych składowych VBA.
Procedury i funkcje
Program w VBA składa się z zestawu procedur. Procedura to zestaw instrukcji wykonujących określone zadanie. Może być ona utworzona automatycznie przez zarejestrowanie makrodefinicji lub ręcznie poprzez pisanie ich do edytora VBA. Podział programu na proce
dury upraszcza jego tworzenie, testowanie (sprawdzanie poprawności) i rozbudowę. Nadrzędnym elementem nad procedurami jest najczęściej moduł skupiający procedury obsługujące jedną aplikację, okno dialogowe itp. Z danym dokumentem lub szablonem może być związanych wiele modułów (na przykład z tym dokumentem związanych jest 5 niezależnych modułów (okien dialogowych: ForNext, IfThenElse, IfThenEndIf, Kantorek, Numerki). Przedstawiono to na sąsiednim rysunku.
Procedura ma następującą budowę:
Sub nazwa procedury(parametry)
Instrukcje
End Sub
Parametry umieszczane w nawiasie i oddzielone przecinkami określają informację wprowadzaną do procedury. Procedura może też pobierać informacje w inny sposób o czym za chwilę. Istnieje specjalny rodzaj procedur, które są uruchamiane automatycznie, gdy wystąpi określone zdarzenie (np. kliknięcie myszą na przycisku polecenia, pozycji menu, wpisanie tekstu, wydanie polecenia wybranego z menu lub paska narzędzi itp.). Takie procedury (nazywane zdarzeniowymi) wykorzystuje się w programowaniu nowych poleceń pakietu.
Procedury mogą być publiczne lub prywatne. Procedury publiczne są dostępne dla innych procedur w całej aplikacji, we wszystkich jej modułach. Deklaruje się je za pomocą słowa Public wpisanego jako pierwsze słowo nagłówka procedury, np.:
Public Sub Wspolna()
.....
End Sub
Procedury prywatne są dostępne tylko w module, w którym zostały zapisane. Deklaruje się je używając słowa Private np.:
Private Sub MojaWlasna()
.....
End Sub
W VBA można też wykorzystywać i tworzyć funkcje. Mają one budowę:
Function NazwaFunkcji(parametry)
Instrukcje
Instrukcja podstawiająca pod NazwęFunkcji określoną wartość
End Function
VBA jest wyposażony w bogaty zestaw gotowych funkcji. Swoje własne funkcje opłaca się pisać najczęściej wtedy, gdy jakiś wzór jest wykorzystywany wielokrotnie w różnych miejscach programu.
Tak więc dokument lub szablon Worda może zawierać szereg modułów, a te z kolei zawierają procedury i funkcje wykonujące określone zadania i wymieniające się informacją. Więcej na temat budowy i działania procedur i funkcji można znaleźć w Pomocy VBA.
Instrukcje
Instrukcje to konkretne polecenia do wykonania. Są one wykonywane przez VBA kolejno jedna po drugiej. Rozróżnia się instrukcje proste i strukturalne. Do instrukcji prostych zalicza się instrukcje przypisania i wykonania procedury. Instrukcje proste są zapisywane w jednym wierszu. Jeżeli są bardzo długie, to można je przenosić do następnego wiersza kończąc wiersz poprzedni spacją i znakiem podkreślenia.
Instrukcja przypisania
Instrukcja przypisania ma budowę:
Obiekt = wyrażenie
Instrukcja oblicza wartość wyrażenia i przypisuje ją wartości obiektu. Sposób zapisu wyrażeń jest podobny do tego, który jest wykorzystywany w Excelu do zapisywania formuł. Przykładowe instrukcje przypisania:
zmiana czcionki zaznaczonego obszaru tekstu
Selection.Font.Name = „Arial”
przemnożenie liczby 132 przez 2 i podstawienie jako wartości obiektu o nazwie Alfa
Alfa = 123*2
dodanie jedności do poprzedniej wartości obiektu Alfa i zapisanie wyniku w obiekcie Alfa. Jeżeli np. przed wykonaniem instrukcji Alfa miało wartość 15, to po jej wykonaniu będzie miało wartość 16:
Alfa = Alfa +1
Wczytanie liczby zapisanej w oknie tekstowym TextBox1 i przypisanie jej zmiennej Beta
Beta = TextBox1.Value
Na sąsiednim rysunku przedstawiono okno dialogowe ilustrujące wykorzystanie instrukcji przypisania. Kliknij na przycisku
, żeby zobaczyć je w działaniu. Więcej na temat instrukcji przypisania można znaleźć w temacie pomocy „Tworzenie instrukcji języka Visual Basic”.
Instrukcja wykonania procedury ma postać:
NazwaProcedury(parametry)
Instrukcja For Next
Czasami pewną grupę instrukcji należy wykonać wielokrotnie. Najczęściej występuje to przy operowaniu tablicami np., gdy chcemy obliczyć sumę wszystkich elementów tablicy A. Można co prawda napisać:
Suma = Suma + A(1)
Suma = Suma + A(2)
.............
Ale przy sumowaniu w ten sposób tablicy składającej się z np. 1000 elementów taka metoda traci sens. Wykorzystując instrukcję For Next opisaną operację można zapisać w postaci:
For i = 1 To 1000
Suma = Suma + A(i)
Next i
Ogólna budowa instrukcji jest następująca:
For licznik = wartość początkowa To wartość końcowa
Instrukcje
Next licznik
Pod zmienną licznik podstawia jest wartość początkowa, a następnie sprawdzane jest, czy nowa wartość zmiennej licznik nie jest większa od wartości końcowej. Jeżeli nie jest większa, to są wykonywane Instrukcje. Po wykonaniu wszystkich instrukcji następuje zwiększenie wartości zmiennej licznik o 1 i program wraca do wiersza zaczynającego się od For. Tu ponownie sprawdza, czy licznik jest większy od wartości końcowej itd. Pętla jest wykonywana do momentu, aż wartość zmiennej licznik stanie się większa od wartości końcowej. Wtedy program przechodzi do wykonania instrukcji zapisanej po wierszu zawierającym Next licznik. Uruchom
, żeby prześledzić działanie instrukcji For Next. Więcej informacji na temat tej instrukcji można znaleźć w Pomocy VBA.
Instrukcja If Then Else End If
Instrukcja pozwala na wybór jednej z dwu alternatywnych dróg postępowania. Ma ona kilka form, z których najprostsza przyjmuje postać:
If wyrażenie logiczne Then
Instrukcje wykonywane, gdy wyrażenie logiczne jest prawdziwe
End If
Wyrażenie logiczne może być prawdziwe (przyjmuje wtedy wartość True) lub fałszywe (przyjmuje wtedy wartość False). Na przykład:
2 > 3 ma wartość False;
Alfa > Beta ma wartość True, jeśli wartość zmiennej Alfa jest większa od wartości zmiennej Beta;
Dochod > 17000 - ma wartość True jeżeli wartość zmiennej Dochod jest większa od 17000.
Jeżeli wyrażenie logiczne jest prawdziwe, to wykonywane są instrukcje zapisane po słowie Then. W przeciwnym przypadku instrukcje te nie są wykonywane i program przechodzi do wykonania kolejnej instrukcji zapisanej poniżej End If. Kliknij tu
, żeby zobaczyć, jak działa instrukcja It Then End If. Po wpisaniu dwóch liczb w pola A i B i kliknięciu na przycisku “Pokaż działanie instrukcji” będzie można, klikając na przycisku “Następny krok”, śledzić krok po kroku sposób wykonywania instrukcji.
Jeżeli po słowie Then występuje tylko jedna instrukcja, to można stosować zapis uproszczony:
If wyrażenie logiczne Then Instrukcja
Instrukcja jest wykonywana jedynie wtedy, gdy wyrażenie logiczne jest prawdziwe. Bardziej złożona forma instrukcji warunkowej zakłada wykonywanie jednej grupy instrukcji, gdy wyrażenie logiczne przyjmuje wartość True, a innej grupy instrukcji, gdy przyjmuje wartość False. Jej budowa jest następująca:
If wyrażenie logiczne Then
Instrukcje wykonywane, gdy wyrażenie logiczne jest prawdziwe
Else
Instrukcje wykonywane, gdy wyrażenie logiczne jest fałszywe
End If
Jeżeli wyrażenie logiczne przyjmuje wartość True, to są wykonywane instrukcje zapisane po słowie Then, a instrukcje po słowie Else nie są wykonywane. Jeżeli warunek przyjmuje wartość False, to wykonywane są instrukcje po słowie Else, a instrukcje po słowie Then nie są wykonywane. Uruchom
, żeby zobaczyć, jak działa instrukcja If Then Else. Po wpisaniu dwóch liczb w pola A i B należy kliknąć na przycisku "Pokaż działanie instrukcji" i dalej postępować jak w poprzednim Demo.. Jeżeli pierwsza z wpisanych liczb jest większa od drugiej, to program wykonując instrukcję Wynik.Text = "A > B" wyświetli odpowiedni tekst w oknie "Wynik". W przeciwnym przypadku w oknie "Wynik" pojawi się napis "A <= B".
Pytanie sprawdzające. Co się stanie jeśli w oba okna wpiszemy tę samą liczbę?
Pozostałe instrukcje zostaną omówione w następnym odcinku.
Obsługa błędów
Jeżeli VBA nie może wykonać jakiejś instrukcji, to przekazuje odpowiedni sygnał o błędzie do edytora VBA i kończy działanie programu. Przyczyny błędu mogą być różne, najczęściej jest to wina programisty, który źle przewidział działanie procedury. Mogą to też być błędy użytkownika, który np. wpisze literę zamiast cyfry w pole tekstowe. W każdym przypadku program nie powinien przerywać działania, a jedynie zasygnalizować pojawienie się błędu i dać użytkownikowi możliwość jego poprawienia lub choćby zapisania wyników. Właśnie do tego celu służy instrukcja On Error GoTo. Jej zadaniem jest przechwycić sygnał o błędzie i nakazać przeskok do miejsca w programie, które zawiera instrukcje obsługi błędów. Instrukcja On Error GoTo jest ściśle związana z sama procedurą i ma budowę:
Sub nazwa(parametry)
On Error GoTo Etykieta
Instrukcje wykonywane, gdy nie ma błędu
Exit Sub
Etykieta:
Instrukcje wykonywane, gdy wystąpił błąd
End Sub
Jeżeli w trakcie działania procedury nie jest sygnalizowany błąd, to wykonywane są instrukcje po wierszu On Error ..., a instrukcja Exit Sub nakazuje normalnie zakończyć działanie procedury. Jeżeli przy wykonywaniu którejkolwiek instrukcji wystąpi błąd, to VBA przerwie dalsze wykonywanie instrukcji i zacznie wykonywać instrukcje zapisane po wierszu Etykieta:.
ilustruje działanie obsługi błędów w aplikacji Kantorek. Dopóki użytkownik wpisuje poprawnie kwotę w dolarach (używając cyfr i przecinka), to każde wpisanie znaku uruchamia procedurę i instrukcję zawierającą przeliczenie dolarów na złotówki. Jeżeli użytkownik wpisze błędny znak, to uruchamiane są instrukcje po etykiecie ZlyZnak. Pojawia się odpowiedni komunikat (wykorzystano tu funkcję MsgBox opisaną w systemie Pomocy VBA), a następnie błędny znak jest usuwany instrukcją:
USD.Text = Left(USD.Text, Len(USD.Text)-1)
Wykorzystano tu dwie funkcje wbudowane w VBA. Funkcja Len oblicza liczbę znaków w obiekcie podanym w nawiasach (w tym przypadku w oknie USD). Funkcja Len zwraca wartość zawierającą podaną liczbę znaków począwszy od lewej strony ciągu znaków. Pierwszy jej argument określa skąd wziąć znaki (u nas z USD.Text), a drugi ile zostawić (u nas o jeden mniej niż było). Problem polega na tym, że takie wycięcie jednego znaku oznacza zmianę zawartości okna USD.Text, a każda zmiana w tym oknie automatycznie uruchamia procedurę Sub USD_Change().
Taka sytuacja, w której procedura wywołuje samą siebie nosi nazwę rekurencji. Jest to twór niechętnie stosowany przez programistów praktyków (choćby z powodów takich, jak opisany powyżej) i służący głównie do straszenia studentów informatyki, a także pełniący dość skutecznie zadanie zrażania do informatyki uczniów szkół średnich (został wpisany w kanon wiedzy informatycznej jakim są „Podstawy programowe” dla nowego, zreformowanego gimnazjum).
W przypadku Kantorka wpadnięcie w pułapkę rekurencji zostało spowodowane błędem w samych założeniach. Chcąc przyspieszyć działanie aplikacji zrezygnowano z zasady wykonania obliczeń dopiero po zatwierdzeniu wprowadzonych danych np. klinięciem na odpowiednim przycisku. VBA, jak każde narzędzie przystosowany jest do działania w sytuacjach typowych uwzględniających reguły tworzenia i wykorzystywania interfesju użytkownika. Dalsze eksperymenty i próby uniknięcia skutków rekurencji pozostawiamy Czytelnikom. Będziemy wdzięczni za uwagi i nadesłane propozycje rozwiązań. Na razie przechodzimy do następnego tematu - dostępu do baz danych.
Obiekty
Aplikacje pakietu Office są zbudowane z obiektów - wydzielonych struktur służących do:
przechowywania informacji - są to stale, zmienne i tablice;
przetwarzania informacji - są to tzw. zmienne obiektowe. Można je wykorzystywać dwojako:
do ustawiania lub odczytywania ich właściwości;
do wykonania pewnych czynności (metod).
Na przykład cały dokument Worda jest zmienną obiektową mającą swoje właściwości (np. nazwę) oraz mogącą zawierać w sobie inne obiekty.
Stałe
Szczególnym rodzajem obiektów są stałe. Tak jak i w przypadku obiektów dużo stałych jest wbudowanych w język programowania. VBA zawiera ich ponad 250, a ich nazwy zaczynają się od vb, nazwy stałych Worda zaczynają się na wd, Excela na x. Wykorzystując przeglądarkę obiektów można znaleźć nazwy stałych i ich wartości. Własne stałe deklaruje się używając instrukcji:
Const nazwa = wartość
Zmienne
Innym, często wykorzystywanym rodzajem obiektów są zmienne. Charakteryzują się one nazwą (nadawana przez programistę), typem określającym rodzaj przechowywanej informacji (Integer - liczba całkowita, Single - rzeczywista, String - ciąg znaków itd.) oraz wartością. Szczególnym typem zmiennej jest Variant mogący przechowywać zmienne o dowolnej budowie. Jest to typ domyślny przy deklarowaniu zmiennych. Deklaracja zmiennej może być rozumiana jako polecenie zarezerwowania określonego obszaru pamięci. Sposób deklaracji zmiennej określa zasięg jej oddziaływania:
Private nazwa As typ
określa zmienną dostępną jedynie w procedurze, w której została ona zadeklarowana;
Public nazwa As typ
określa zmienną dostępną we wszystkich procedurach wszystkich modułów.
Zmienne istnieją tylko w czasie działania procedury lub modułu. Jeżeli chce się, żeby zmienna istniała także po zakończeniu działania procedury, to należy zadeklarować ją jako:
Static nazwa As typ
Bardzo popularna jest deklaracja Dim. Jej zasięg oddziaływania zależy od miejsca, w którym została użyta. Wpisanie jej przed procedurami oznacza, że zadeklarowane w ten sposób zmienne są dostępne we wszystkich umieszczonych niżej procedurach. Zadeklarowanie zmiennej wewnątrz procedury oznacza, że jest ona lokalna dla tej procedury.
Na rysunku przedstawiono fragment kodu modułu ForNext. Zmienne całkowite Licznik i N zostały zadeklarowane powyżej treści procedur, są więc dostępne dla wszystkich procedur tego modułu. Podobnie jest ze zmienną Suma (tu nie zadeklarowano typu - domyślnie jest przyjęty typ Variant). Obiekt Sterowniki jest zadeklarowany jako Collection. Jest to specjalny typ kolekcji składającej się z innych obiektów.
Wewnątrz procedury PokazDzialanie-Click() jest zadeklarowana zmienna całkowita I. Jest więc ona dostępna tylko w tej procedurze.
Dzięki zadeklarowaniu zmiennych Licznik i N poza procedurami można ustawiać ich wartości w jednej procedurze, a odczytywać i wykorzystywać w innych. Jest to więc metoda przekazywania informacji między procedurami.
Tablice
Tablice służą do przechowywania zmiennych jednakowego typu. Deklaracja tablicy ma postać:
Dim nazwa(indeks dolny To indeks górny, ...) As Typ
Zamiast słowa Dim można użyć Static, Private, Public. Można deklarować tablice wielowymiarowe (do 60 wymiarów). Na przykład deklaracja:
Public Tablica3D(1 To 100, 1 To 200, 1 To 10) As Integer
określa tablicę trójwymiarową o nazwie Tablica3D o 100 wierszach, 20 kolumnach i o głębokości 10. Razem tablica zawiera 20 000 elementów.
Więcej o tablicach można przeczytać w Pomocy VBA.
Zmienne obiektowe
Ogólna zasada operowania obiektami jest podobna do adresowania plików w folderach czy katalogach dyskowych - należy określić położenie obiektu w hierarchii i właściwość lub metodę, którą się chce wykorzystać. Poszczególne poziomy hierarchii oddziela się kropkami. Na przykład instrukcja przypisania:
ThisDocument.Selection.Font.Name = „Arial”
określa nazwę czcionki w zaznaczonym obszarze aktywnego dokumentu.
W przypadku metody instrukcja jest najczęściej uzupełniana o dodatkowe parametry jak np.:
Document.Open(FileName:=”C:\Dokumenty\Sprawozdanie.doc”)
Pakiet Office składa się z kilkuset obiektów, można też tworzyć swoje własne.
Zmienne obiektowe deklaruje się wykorzystując ogólny typ Object:
Dim Arkusz As Object
lub lepiej podając jako nazwę klasy obiektów zawartych w bibliotece obiektów (wtedy program działa szybciej). Na przykład deklaracja:
Dim MojaPrezentacja As Presentation
określa obiekt jako prezentację programu PowerPoint.
Deklaracja Dim jedynie rezerwuje miejsce dla obiektu. Konieczne jest jeszcze utworzenie zmiennej obiektowej i przypisanie jej wartości konkretnego obiektu. Służy do tego instrukcja Set. Ma ona budowę:
Set zmienna obiektowa = wartość obiektu
Wartością obiektu może być konkretny obiekt lub metoda jego utworzenia. Na przykład deklaracje:
Dim MojaPrezentacja As Presentation
Set MojaPrezentacja = Presentations.Add
tworzą nową prezentację PowerPoint. Od tej chwili można wykorzystywać zmienną obiektową MojaPrezentacja np. w instrukcji tworzącej nową prezentację:
MojaPrezentacja.Slides.Add
Podobnie dla MS Excela deklaracje:
Dim Obszar As Excel.Application
Set Obszar = Worksheets(1).Range(„A1”)
określają komórkę A1 jako zmienną obiektową Obszar. Od tej chwili można ją wykorzystywać w procedurze np. pisząc instrukcję:
Obszar.Value = 155
Listę dostępnych klas obiektów można przeglądać za pomocą Przeglądarki obiektów w edytorze VBA.
Pracując w jednej aplikacji można wykorzystywać klasy obiektów innej aplikacji. Należy jednak wtedy do aplikacji macierzystej dołączyć bibliotekę klas tej innej aplikacji. Na przykład chcąc z poziomu MS Worda uruchomić i zarządzać prezentacją PowerPointa należy w do listy obiektów Worda dołączyć (poleceniem Odwołania w menu Narzędzia edytora VBA) bibliotekę Microsoft PowerPoint 8.0 Object Library. Chcąc przy tym wykorzystywać Pomoc VBA PowerPointa należy ją zainstalować za pomocą Instalatora pakietu Office.
12
Okno projektu edytora VBA prezentuje wykorzystywane moduły. Z dokumentem (Opis VBA) związanych jest 5 modułów (w tym przypadku formularzy okien dialogowych. Każdy taki formularz zawiera szereg procedur.
Następujące po sobie instrukcje tworzą sekwencję. Gra w numerki ilustruje, jak działają instrukcje przypisania.
Instrukcja pętli wykonuje zadaną liczbę razy instrukcje w niej zawarte
Instrukcja If Then umożliwia ominięcie wykonania zawartych w niej instrukcji
Instrukcja If Then Else stwarza możliwość wykonania jednej z dwóch grup instrukcji
Aplikacja powinna być zabezpieczona przed błędami użytkownika. Instrukcja On Error GoTo pozwala na przechwycenie i obsługę błędów