praca word(1)


Zespół Szkół Technicznych

im. Ignacego Mościckiego

Tarnów - Mościce



Specjalność: Systemy komputerowe.

PRACA

DYPLOMOWA

Temat: Makropolecenia używane w Microsoft Word.

Konsultant: Wykonał:

mgr Janusz Sadowski Marcin Waśniowski

Klasa V TSK

Tarnów 2003

Spis treści:

Wiadomości wstępne ............................................................................... 3

Co to jest język programowania? ......................................................... 3

Styl programowania .............................................................................. 5

Język programowania VBA ..................................................... 10

Zmienne, typy danych i stałe .................................................................. 10

Komentarze ........................................................................................... 10

Znak kontynuacji wiersza kodu ............................................................ 10

Stałe ....................................................................................................... 11

Zmienne i typy danych .......................................................................... 14

Operatory języka VBA .......................................................................... 31

Funkcje i podprogramy ............................................................................. 32

Wywoływanie funkcji ............................................................................ 32

Wywoływanie podprogramów ............................................................... 35

Parametry i argumenty ........................................................................... 36

Wychodzenie z procedury ...................................................................... 41

Procedury publiczne i prywatne ............................................................. 41

Dodawanie odwołań do projektu ............................................................ 41

Pełne nazwy procedur ............................................................................. 42

Funkcje i instrukcje wbudowane ............................................................... 43

Funkcja MsgBox ..................................................................................... 44

Funkcja InputBox .................................................................................... 47

Funkcje umożliwiające operacje na łańcuchach znaków ........................ 48

Różne funkcje i instrukcje ....................................................................... 52

Instrukcje kontrolujące przepływ programu ............................................ 54

Instrukcja If... Then .................................................................................. 54

Pętla For ................................................................................................... 55

Pętla For Each .......................................................................................... 56

Pętla Do .................................................................................................... 57

Instrukcja Select Case .............................................................................. 61

Ostatnie uwagi o VBA ............................................................................. 62

BHP ................................................................................................................ 63

Wstęp......................................................................................................... 63

Działanie prądu na organizm ludzki ......................................................... 67

Środki ochrony przeciw pożarowej .......................................................... 68

Wiadomości wstępne

Należy od kilku ogólnych faktów związanych z programowaniem i językami programowania, co pozwoli spojrzeć na materię poruszaną w tej pracy z pewnej perspektywy. VBA jest jednym z wielu języków programowania i wszyscy potencjalni programiści powinni wiedzieć, jaką pozycję zajmuje on wśród innych języków. Rozdział ten zawiera informacje ogólne na temat programowania i uży­wanych w nim języków, które zainteresują zarówno użytkowników początkujących, jak i doświad­czonych w programowaniu.

Co to jest język programowania?

Mówiąc prosto, język programowania to bardzo wyspecjalizowany i ograniczony język rozumiany przez komputer na pewnym poziomie. Języki programowania można podzielić na trzy grupy w za­leżności od ich przeznaczenia.

- Języki zaprojektowane do sterowania komputerem na niskim poziomie - czyli do manipulowania systemem operacyjnym (Windows lub DOS) albo nawet sprzętem ­są nazywane językami niskiego poziomu. Przykładem jest asembler.

- Języki zaprojektowane do tworzenia samodzielnych programów, takich jak Microsoft Word, są językami wysokiego poziomu. Należą do nich BASIC, COBOL, FORTRAN, C, C++ i Visual Basic.

- Języki zaprojektowane do manipulowania aplikacjami, takimi jak Microsoft Word, to języki poziomu aplikacji. Należy do nich VBA dla Worda, Excela i PowerPointa. Każdy z nich jest odmianą języka VBA i służy do sterowania konkretną aplikacją.

Powyższe określenia nie są obowiązujące i mogą być również używane w innym znaczeniu. Nie sposób jednak zaprzeczyć, że niektóre języki są używane na poziomie niższym niż inne.

Świat komputerowy jest pełen setek języków programowania. Niektóre z nich zostały stworzone dla konkretnych komputerów; inne - dla konkretnych typów aplikacji. Tabela 2.1 przedstawia przykłady języków programowania i ich ogólne zastosowanie.

Tabela 1.1. Niektóre języki programowania

Język

Ogólne zastosowanie

BASIC

Prosty, łatwy w nauce język dla początkujących

Visual Basic

Wersja BASIC-a służąca do tworzenia aplikacji dla Windows

C, C++

Języki o ogromnych możliwościach, bardzo szybkie i dające dużą kontrolę nad komputerem

Visual C++

Wersja języka C++ zaprojektowana do tworzenia aplikacji dla Windows

Pascal

Język edukacyjny, przeznaczony do nauki poprawnego programowania

COBOL

Język programowania do zastosowań w biznesie

FORTRAN

Język programowania naukowego, niezrównany w skomplikowanych

obliczeniach

Lisp

Język do przetwarzania list (używany w omawianiu zagadnień sztucznej

inteligencji)

ALGOL

Próba stworzenia języka uniwersalnego

SIMULA

Język symulacyjny, służący do modelowania zjawisk fizycznych

SmallTalk

Język programowania zorientowanego obiektowo

Języki programowania różnią się składnią. Niektóre języki są znacznie łatwiejsze w czytaniu niż inne (podobnie jest z językami naturalnymi). Tabela 2.2 przedstawia sposób, w jaki w różnych ję­zykach programowania można przypisać wartość (w tym przypadku 5) zmiennej o nazwie X. War­to zwrócić uwagę na różnorodność metod wykonania nawet tak prostego zadania.

Tabela 1.2. Operacja przypisania w różnych językach.

Język

Instrukcja przypisania

APL

X <- 5

BASIC

LET X = 5 lub X = 5

BETA

5 -> X

C, C++

X = 5;

COBOL

MOVE 5 TO X

FORTRAN

X = 5

J

X =. 5

Lisp

(SETQ X 5)

Pascal

X : =5

Visual Basic

X=5

Styl programowania

Dobry styl programowania, podobnie jak dobry styl pisania, jest sprawą w znacznej mierze su­biektywną. Prawdopodobnie najlepiej nauczyć się go poprzez studiowanie przykładów.

Nie ma tu miejsca na szczegółowe rozważania na temat stylu programowania. Trzeba jednak wspomnieć o dwóch najważniejszych być może zasadach dobrego programowania. Są to:

Komentarze

Nie sposób przecenić znaczenia sensownych komentarzy w programach - przynajmniej tych nieco dłuższych.

Dobre programy są intensywnie używane na przestrzeni stosunkowo długiego czasu, mierzonego w miesiącach, a nawet latach. Siłą rzeczy programista będzie chciał wrócić do swojego kodu, aby dokonać zmian (na przykład dodać nowe funkcje) lub usunąć błędy. Mimo wszystkich starań ję­zyki programowania nie są tak czytelne, jak języki naturalne. Może się więc okazać, że programi­sta nie będzie w stanie zrozumieć (a nawet rozpoznać!) kodu napisanego kilka miesięcy lub kilka lat wcześniej i w celu ponownego zaznajomienia się w własnym kodem będzie musiał polegać na precyzyjnie napisanym komentarzu .

Należy tu podkreślić, że pisanie komentarzy jest prawie taką samą sztuką, jak pisanie samego kodu. Często można spotkać komentarze podobne do poniższego:

'Przypisz zmiennej x wartość5

x=5

Komentarz ten jest bezużyteczny, ponieważ kod objaśnia się sam. Jest to zwykłe marnowanie czasu i miejsca. Warto tu zauważyć, że w pracach dydaktycznych, takich jak ta praca, można znaleźć komentarze, których nie powinno być w profesjonalnie napisanych programach.

Przeczytanie komentarza (bez kodu) powinno wystarczyć do zrozumienia nie tylko zadania, które program ma wykonać, ale również etapów prowadzących do osiągnięcia celu. Oto komentarze z programu napisanego w języku BASIC :

'Program napisany w języku BASIC

'obliczający średnią nie więcej niż 100 liczb

'Poproś o liczby

'Jeżeli Liczba należy do przedziału od 1 do 100, kontynuuj

'Wykonaj pętlę pobierającą liczby

'Poproś o następną liczbę

'Dodaj liczbę do sumy liczb

'Oblicz średnią

'Wyświetl średnią

Czytelność

Czytelność jest sprawą subiektywną. To, co jest czytelne dla jednej osoby, może nie być czytelne dla innej. To, co jest czytelne dla autora programu, prawdopodobnie jest mniej czytelne dla wszystkich innych osób, przynajmniej do pewnego stopnia. Dobrze jest o tym pamiętać przed przystąpieniem do programowania (zakładając, że chcemy, aby inni potrafili czytać nasze programy).

Instrukcja GOTO, której różne wcielenia wchodzą w skład wielu języków (w tym VBA), należy do tych instrukcji, które najbardziej psują czytelność kodu. Nie będzie się tu rozwodzić się nad instruk­cją GOTO, ale pomoże ona zilustrować sprawę dobrego stylu programowania.

Instrukcja GOTO jest bardzo prosta - przenosi ona wykonywanie programu w inne miejsce. Na przykład następujący kod napisany w języku BASIC prosi użytkownika o podanie liczby dodatniej. Jeżeli użytkownik poda liczbę ujemną, instrukcja GOTO przenosi wykonywanie kodu do pierw­szego wiersza programu (oznaczonego etykietą PonowProbe). Spowoduje to ponowne wykonanie całego programu. Krótko mówiąc, program będzie wykonywany do momentu podania liczby do­datniej przez użytkownika:

PonowProbe:

INPUT "Wpisz liczbę dodatnią: ", x

IF x <=0 TREN GOTO PonowProbe

Chociaż powyższy program nie reprezentuje dobrego stylu programowania, jest przynajmniej czy­telny. Jednak kod poniższy jest znacznie trudniejszy do czytania:

PonowProbe

INPUT "Wpisz liczbę z przedziału od 1 do 100: ", x

IF x > 100 THEN GOTO ZbytDuza

IF x <=0 THEN GOTO ZbytMala

PRINT "Podana liczba to: ", x

GOTO Zrobione

ZbytDuza:

PRINT "Podana liczba jest zbyt duża"

GOTO PonowProbe

ZbytMala:

PRINT "Podana liczba jest zbyt mała"

GOTO PonowProbe

Zrobione:

END

Taki rodzaj kodowania jest nazywany kodem spaghetti, ponieważ zmusza do przeskakiwania z miejsca na miejsce, kiedy chce się prześledzić przepływ programu. Trudno sobie wyobrazić taki styl programowania w programie zawierającym tysiące wierszy. Wersja podana poniżej jest znacz­nie czytelniejsza, choć nie jest to jeszcze styl najlepszy:

PonowProbe:

INPUT "Wpisz liczbę z przedziału od 1 do 100: ", x

IF X > 100 TREN

PRINT "Podana liczba jest zbyt duża"

GOTO PonowProbe

ELSEIF x <=0 THEN

PRINT "Podana liczba jest zbyt mała"

GOTO PonowProbe

END IF

PRINT "Podana liczba to: ",

END

Poniższy kod wykonuje tę samą pracę, ale unika użycia instrukcji GOTO i większość programistów uznałoby go za napisany lepszym stylem:

DO

INPUT "Wpisz liczbę z przedziału od 1 do 100: ", x

IF x > 100 THEN

PRINT "Podana liczba jest zbyt duża "

ELSEIF x <= 0 THEN

PRINT "Podana liczba jest zbyt mała "

END IF

LOOP UNTIL x >=1 AND x<=100

PRINT "Podana liczba to: ", x

END

Niektórzy programiści chcą, aby ich kod był „oryginalny" lub „efektowny", ale w rzeczywistości okazuje się on trudny do czytania i podatny na powstawanie błędów. Szczególnie łatwo o to w ję­zyku C. Rozważając na przykład następujące trzy wiersze napisane w języku C:

x = x + 1;

x = x + i;

i = i - 1;

Pierwszy wiersz dodaje 1 do x, drugi dodaje i do x, a trzeci odejmuje 1 od i. Taki kod jest z pew­nością czytelny (chociaż niezbyt sensowny). Jednak można go również napisać tak:

x = ++ x + i--,

Niektórzy programiści mogą uznać to za oryginalne programowanie, ale taki kod jest nie do przyjęcia. Właśnie dlatego rozważny programista przedkłada czytelność kodu nad „oryginal­ność" i „efektowność".

Programowanie modułowe

Innym ważnym zagadnieniem związanym z czytelnością jest programowanie modułowe. We wcze­snym etapie rozwoju programowania komputerów osobistych (jak również rozwoju języka BASIC) większość programów składało się tylko z jednego modułu zawierającego czasem setki, a nawet tysiące wierszy kodu. Czytanie takiego programu nie jest łatwe, zwłaszcza w sześć miesięcy po je­go napisaniu. Programy te używały tych samych segmentów kodu wielokrotnie, co było marnowa­niem czasu i miejsca.

Ilustruje to poniższy przykład napisany w języku BASIC. Dla ułatwienia dodano numery wierszy. (Zrozumienie znaczenia każdego wiersza kodu nie jest konieczne dla zrozumienia samego zagad­nienia, które on ilustruje).

10 'Program odwracający kolejność liter w nazwisku

20 'Czytaj wspak imię

30 INPUT "Wpisz imię: ", nazwisko$

40 CzytajWspak$ _ ""

50 FOR i = LEN(nazwisko$) TO 1 STEP -1

60 CzytajWspak$= CzytajWspak$ + MID$(nazwisko$, i, 1)

70 NEXT i

80 PRINT "Imię czytane wspak: " + Czytajwspak$

90 'Czytaj wspak drugie imię

100 INPUT "Wpisz drugie imię: ", nazwisko$

110 CzytajWspak$ _ ""

120 FOR i = LEN(nazwisko$) TO 1 STEP -1

130 Czy tajWspak$= Czytaj Wspak $ + MID$(nazwisko$, i, 1)

140 NEXT i

150 PRINT "Drugie imię czytane wspak: " + CzytajWSpak$

160 'Czytaj wspak nazwisko

170 INPUT "Wpisz nazwisko: ", nazwisko$

180 Czytaj Wspak$ _ ""

190 FOR i = LEN(nazwisko$) TD 1 STEP -1

200 CzytajWspak$= Czy tajWspak$ + MID$(nazwisko$, i, 1)

210 NEXT i

220 PRINT "Nazwisko czytane wspak: " + CzytajWspak $

Należy zwrócić uwagę, że wiersze 40-70, 110-140 i 180-210 są identyczne. Jest to marnowanie miejsca. Lepszym rozwiązaniem byłoby wpisanie kodu, który odwraca łańcuch znaków (nazwisko), do oddzielnego modułu kodu i wywoływanie tego modułu trzy razy, jak pokazuje poniższy przykład:

'Program czytający wspak nazwisko

DECLARE FUNCTION CzytajWspak$(nazwisko$)

'Czytaj wspak imię

INPUT "Wpisz imię: ", nazwisko$

PRINT "Imię czytane wspak: " + CzytajWspak$(nazwisko$)

'Czytaj wspak drugie imię

INPUT "Wpisz drugie imię: ", nazwisko$

PRINT "Drugie imię czytane wspak: " + CzytajWspak$(nazwisko$)

'Czytaj wspak nazwisko

INPUT "Wpisz nazwisko: ", nazwisko$

PRINT "Nazwisko czytane wspak: " + CzytajWspak$(nazwisko$)

Oto oddzielny moduł kodu odwracający łańcuch znaków:

'Kod czytający łańcuch znaków wspak

FUNCTION CzytajWspak$(nazwisko$)

LancuchZnakow$= ""

FOR i = LEN(nazwisko$) TO 1 STEP -1

LancuchZnakow$ = LancuchZnakow$ + MID$(nazwisko$, i, 1)

NEXT i

CzytajWspak$ = LancuchZnakow$

END FUNCTION

Oczywiście w tym przykładzie nie zaoszczędzono zbyt dużo miejsca, ale można sobie wyobrazić, co się stanie, jeżeli zamieni się procedurę odwracającą łańcuch znaków na taką, która zawiera kilkaset wierszy kodu, i wykona się ją kilkaset razy w głównym programie. Dzięki modularyzacji można zaoszczędzić dosłownie tysiące wierszy kodu.

Istnieje inna ważna zaleta programowania modułowego. Jeżeli zdecyduje się na napisanie in­nego programu wymagającego odwracania łańcuchów znaków, można po prostu dodać moduł kodu odwracający łańcuch znaków do nowego programu, bez konieczności pisania nowego kodu. Profesjonalni programiści często tworzą biblioteki kodu zawierające użyteczne moduły kodu, które w razie potrzeby można dodać do nowych aplikacji.

Trudno przecenić ważność programowania modułowego. Na szczęście VBA ułatwia tworzenie programów modułowych.

Ogólnie mówiąc, istnieją dwie grupy modułów kodu: funkcje i procedury typu sub. Różnią się one tym, że funkcja zwraca wartość, a procedura typu sub - nie zwraca (oczywiście można nie użyć wartości zwracanej przez funkcję.) Na przykład, funkcja Czytaj Wspak opisana wyżej zwraca od­wrócony łańcuch znaków. Natomiast poniższy moduł kodu coś robi, ale nie zwraca wartości - po prostu zawiesza działanie na pewną liczbę sekund (podanych w argumencie sekunda):

SUB ChwilaPrzerwy(sekunda)

`Odczytaj bieżący czas

Start = TIMER

`Stwórz pętlę, która nic nie robi

`przez liczbę sekund podaną w argumencie sekunda

DO

LOOP UNTIL TIMER - Start > sekunda

END SUB

Funkcje i procedury typu sub są niezwykle często używane w nowoczesnym programowaniu. Jedne i drugie są nazywane procedurami.

Język programowania VBA

Zmienne, typy danych i stale

W tym rozdziale zostaną omówione podstawy języka VBA używanego we wszystkich apli­kacjach pakietu Microsoft Office. Będzie zaprezentowane wiele krótkich fragmentów kodu.

Komentarze

Wspomniane już zostało ważnej roli, jaką odgrywają komentarze. Komentarzem jest każdy tekst poprzedzony znakiem apostrofu. W trybie działania programu, Word ignoruje komentarze. W po­niższym przykładzie komentarzem jest pierwszy wiersz, jak również tekst w trzecim wierszu, znaj­dujący się na prawo od apostrofu:

'Zadeklaruj zmienną typu String

Dim NazwaDokumentu As String

NazwaDokumentu = ActiveDocument.Name 'Odczytaj nazwę dokumentu

W czasie usuwania błędów fragment kodu, który chwilowo ma być niewidoczny dla Worda w try­bie działania programu, można zaznaczyć jako komentarz. Jeżeli chce się, aby kod był ponownie wykonywany, należy usunąć znaki komentarza. Przyciski CommentBlock, i UncommentBlock znajdu­jące się na pasku narzędzi Edit, służą do wstawiania i usuwania znaku komentarza (apostrofu) we wszystkich zaznaczonych wierszach, co ułatwia wstawianie znaku komentarza w wielu wierszach jednocześnie. Chociaż przyciski te nie mają klawiszy skrótów, można dodać je do menu i przy­pisać im klawisze dostępu.

Znak kontynuacji wiersza kodu

Długie wiersze kodu napisane w języku VBA mogą być trudne do czytania, szczególnie kiedy mu­si się korzystać z poziomego paska przewijania edytora kodu, aby zobaczyć cały wiersz. Z tego po­wodu Microsoft wprowadził znak kontynuacji wiersza kodu, którym jest znak podkreślenia (_). Przed znakiem kontynuacji wiersza kodu należy postawić znak spacji. Należy zwrócić uwagę, że na pra­wo od znaku kontynuacji wiersza nie można postawić żadnego znaku (w tym również komentarza). Oto przykład:

ActiveDocument.Paragraphs(1).Alignment = _

WdAlignParagraphCenter

Word traktuje powyższy kod jak jeden wiersz.

WSKAZÓWKA! Znaku kontynuacji wiersza kodu nie można umieścić w łańcuchu znaków wziętym w cudzysłów.

Stałe

Język VBA posiada dwa typy stałych. Literał to konkretna wartość - taka jak liczba, data lub łań­cuch znaków - która się nie zmienia i jest używana tak, jak została zadeklarowana. Należy zwrócić uwagę, że stałe łańcuchów znaków są wzięte w cudzysłów, na przykład:

"Stefania Szybki"

natomiast stałe dat są umieszczone między dwoma znakami numeru, na przykład:

#21/4/2000#

Następujący kod przypisuje datę zmiennej MojaData:

Dim MojaData As Date

MojaData = #4/21/2000#

Drugi typ stałej to stała symboliczna.

Aby zdefiniować lub zadeklarować stałą symboliczną w programie, należy użyć słowa kluczowego Const, na przykład:

Const NazwaPliku = "c:\Test.doc"

W trybie działania programu Word zastępuje wyrażenie NazwaPliku łańcuchem "c:\Test.doc". Oznacza to, że "c:\Test.doc" jest stałą, ponieważ się nie zmienia, ale nie literałem, ponieważ za­miast łańcucha znaków "c:\ Test.doc" wpisuje się w kodzie NazwaPliku.

Zaletą stałych symbolicznych jest to, że jeżeli zdecyduje się zmienić łańcuch znaków "c:\ Test.doc" na "c:\Moje dokumenty\Test.doc", nie musi się wyszukiwać w kodzie każdego wystąpie­nia łańcucha znaków "c:\Test.doc" i zastępować go nowym. Wystarczy jedynie zmienić deklarację stałej NazwaPliku:

Const NazwaPliku = "c:\ Moje dokumenty\Test.doc"

Stałe symboliczne należy deklarować na początku każdej procedury, w której mają one być użyte (lub w sekcji deklaracji modułu kodu). Poprawia to czytelność kodu.

Oprócz stałych symbolicznych, które definiuje się za pomocą instrukcji Const, VBA posiada wiele wbudowanych stałych symbolicznych (około 700) o nazwach zaczynających się od liter vb. VBA dla Worda posiada dodatkowe stałe symboliczne (około 2000) o nazwach rozpoczynających się od liter wd.

Do najczęściej używanych stałych VBA należą vbCrLf - równoznaczna z naciśnięciem klawisza Enter, vbTab - równoznaczna z naciśnięciem klawisza Tab. Word używa również stałej vbCr jako znaku akapitu.

Enumeracje

Enumeracja (w skrócie Enum) to struktura służąca do definiowania grupy stałych symbolicznych. Na przykład, wśród 192 enumeracji Worda znajduje się enumeracja definiująca ustawienia akapitu:

Enum WdParagraphAlignment

wdAlignParagraphLeft = 0

wdAlignParagraphCenter = 1

wdAlignParagraphRight = 2

wdAlignParagraphJustify = 3

End Enum

Zatem poniższy wiersz kodu wyśrodkuje pierwszy akapit w aktywnym dokumencie:

ActiveDocument.Paragraphs(1).Alignment = wdAlignParagraphCenter

Enumeracje są wbudowane, więc nie musi się ich deklarować przed użyciem stałych symbolicznych. Można stworzyć własne enumeracje, ale najczęściej nie jest to konieczne z powodu ogromnej liczby enumeracji wbudowanych.

Innym przykładem jest wbudowana enumeracja definiująca wartości zwracane, kiedy użytkownik klika przycisk okna komunikatów:

Enum VbMsgBoxResult

vbOK = 1

vbCancel = 2

vbAbort = 3

vbRetry = 4

vbIgnore = 5

vbYes = 6

vbNo = 7

End Enum

Na przykład, kiedy użytkownik klika przycisk OK w oknie komunikatu, VBA zwraca wartość vbOK. Łatwiej zapamiętać, że VBA zwraca stałą symboliczną vbOK, niż zapamiętać, że zwraca stałą 1. W dalszej części zostanie omówione , jak odczytać i wykorzystać zwracane wartości.

VBA definiuje również stałe symboliczne, które decydują o typie przycisków pojawiających się w oknie komunikatów. Oto fragment enumeracji zawierającej te stałe symboliczne:

Enum VbMsgBoxStyle

vbOKOnly = 0

vbOKCancel = 1

vbAbortRetryIgnore = 2

vbYesNoCancel = 3

vbYesNo = 4

vbRetryCancel = 5

End Enum

Poniższy przykład ilustruje użycie omawianych stałych :

If MsgBox("Kontynuować?", vbOKCancel) = vbOK Then

'Tu wpisz kod wykonywany, kiedy użytkownik

'klika przycisk OK

Else

'Tu wpisz kod wykonywany,kiedy użytkownik

'klika przycisk Anuluj

End If

Pierwszy wiersz kodu:

MsgBox("Kontynuować?", vbOKCancel)

sprawia, że Word wyświetla okno komunikatu z dwoma przyciskami - OK i Anuluj - oraz wiado­mość „Kontynuować?" (Rysunek 5.1).

0x01 graphic

Rysunek 5.1. Proste okno komunikatu.

Jeżeli użytkownik klika przycisk OK, Word zwraca wartość vbOK. W innym przypadku zwróci wartość vbCancel. Zatem instrukcja If w pierwszym wierszu rozróżnia te dwie odpowiedzi. In­strukcja If jest omawiana trochę później ,w Instrukcje kontrolujące przeplyw programu.

Wyraźnie widać, że pierwszy wiersz omawianego fragmentu kodu jest czytelniejszy niż wiersz:

If MsgBox("Kontynuować?", 1) = 1 Then

Aby jeszcze bardziej docenić wartość stałych symbolicznych, należy spojrzeć na enumerację definiującą stałe kolorów:

Enum ColorConstants

vbBlack = 0

vbBlue = 16711680

vbMagenta = 16711935

vbCyan = 16776960

vbWhite = 16777215

vbRed = 255

vbGreen = 65280

vbYellow = 65535

End Enum

Który z poniższych wierszy jest czytelniejszy:

PoleTekstowe.ForeColor = vbBlue

czy

PoleTekstowe.ForeColor = 16711680

Zmienne i typy danych

Zmienna jest zarezerwowanym miejscem w pamięci, które przechowuje wartości określonego typu. Wartość zmiennej może zmieniać się w czasie wykonywania programu - stąd nazwa „zmienna".

W VBA zmienna posiada określony typ danych, który wskazuje, jaki rodzaj danych może ona przechowywać. Na przykład zmienna typu String przechowuje łańcuchy znaków (tekst). Zmienna typu Integer przechowuje liczby całkowite. Tabela 5.1 przedstawia typy danych, ich zakres warto­ści oraz ilość pamięci, którą one zajmują. Za chwilę zostaną omówione zmienne stosowane najczęściej.

Tabela 5.1. Typy danych VBA.

Typ

Rozmiar

Zakres wartości

Byte

1 bajt

0 do 255

Boolean

2 bajty

True i False

Integer

2 bajty

-32 768 do 32 767

Long

4 bajty

od -2147483648 do 2147483747

Single

4 bajty

w przybliżeniu od -3,4E38 do 3,4E38

3,4E38

Double

8 bajtów

W przybliżeniu od -1,8E308 do 4,9E324

Currency

8 bajtów

W przybliżeniu od

-922337203685477,5808 do

922337203685477,5807

Date

8 bajtów

od 1/1/100 do 12/31/9999

Object

4 bajty

Odwołanie do obiektu

String

Zmiennej długości: 10 bajtów + długość łańcucha znaków

Łańcuchy zmiennej długości: <= około 2 miliardy (65 400 dla win 3.1); Łańcuchy stałej długości: do 65 400

Variant

16 bajtów dla liczb

22 bajty+ długość łańcucha znaków

Liczba: tyle co Double

Łańcuch znaków: tyle co String

Zdefiniowany przez programistę

Różne

Deklarowanie zmiennych

Deklarowanie zmiennej oznacza zdefiniowanie jej typu danych. Zmienne deklaruje się za pomocą słowa kluczowego Dim (lub słów kluczowych Private i Public). Oto kilka przykładów:

Dim Nazwisko As String

Dim Wakacje As Date

Dim Wiek As Integer

Dim Wzrost As Single

Dim Pieniądze As Currency

Dim dok As Document

Dim Akapit as Paragraph

Zmienne deklaruje się zgodnie z następującym wzorem:

Dim NazwaZmiennej As TypDanych

Jeżeli użyje się zmiennej, która nie była zadeklarowana lub która została zadeklarowana bez podania jej typu, na przykład:

Dim Wiek

VBA przypisze jej typ Variant. Będzie to oznaczać zmarnowanie pamięci, ponieważ, jak wynika z tabeli 5.2, zmienna typu Variant wymaga więcej pamięci niż większość innych typów zmiennych.

Na przykład zmienna typu Integer (przechowująca liczby całkowite) wymaga 2 bajtów, podczas gdy zmienna typu Variant przechowująca tę samą liczbę całkowitą wymaga 16 bajtów, co oznacza, że 14 bajtów zostało zmarnowanych. W złożonych programach zawierających setki lub nawet ty­siące zmiennych spowodowałoby to znaczące straty pamięci. Z tego powodu zaleca się deklarowa­nie wszystkich zmiennych.

Można umieścić więcej deklaracji w jednym wierszu. Na przykład wiersz kodu:

Dim Wiek As Integer, Nazwisko As String, Pieniądze As Currency

deklaruje trzy zmienne. Należy zwrócić uwagę, że wiersz:

Dim Wiek, Wzrost, Waga As Integer

deklaruje zmienne Wiek i Wzrost jako typ Variant, nie Integer. Innymi słowy, należy określić typ dla każdej zmiennej.

Można również dodać do nazwy zmiennej specjalny znak określający jej typ. Tabela 5.2 zawiera zestawienie tych znaków.

Tabela 5.2. Znaki określające typ zmiennej.

Znak

Typ

%

Integer

&

Long

!

Single

#

Double

@

Currency

$

String

Na przykład wiersz:

Dim Nazwisko$

deklaruje zmienną o nazwie Name$ typu String. Można użyć jej w kodzie w następujący sposób:

Name$ _ "Alicja"

Chociaż można deklarować zmienne i stałe w dowolnym miejscu procedury, do zasad dobrego pro­gramowania należy deklarowanie zmiennych na początku procedury. Ułatwia to czytanie kodu.

Jawne deklarowanie zmiennych

Powiedziane zostało, że używanie typu Variant oznacza zwykle marnowanie pamięci. Istnieje jeszcze jeden, ważniejszy powód, dla którego warto deklarować zmienne jawnie (tj. przed ich użyciem). Jeżeli popełni się błąd wpisując nazwę zadeklarowanej zmiennej, VBA „pomyśli", że chce się stworzyć nową zmienną.

Procedura NowyList (wydruk 5.1) ilustruje, jak może to być niebezpieczne. Procedura NowyList ma w pierwszy otwartym dokumencie zmieniać zawartość, poprosić użytkownika o nazwę, pod którą ma być zapisany zmieniony dokument, i zapisać dokument pod nową nazwą.

Wydruk 5.1. Procedura z błędem typograficznym.

Public Sub NowyList()

Dim List As Document Dim NazwaListu As String

'Weź pierwszy otwarty dokument

Set List = Documents(1)

'Odczytaj nazwę dokumentu

NazwaListu = List.Name

'Zmień zawartość dokumentu

List.Content = "Kocham Cię!"

'Poproś użytkownika o nową nazwę dla dokumentu

NazwaList =InputBox("Wpisz nową nazwę dla dokumentu"& NazwaListu)

'Zapisz dokument

List.SaveAs NazwaListu

End Sub

Należy zwrócić uwagę, że wiersz

NazwaList =InputBox("Wpisz nową nazwę dla dokumentu"& NazwaListu)

zawiera błąd typograficzny. Ponieważ zmienna NazwaList nie została zadeklarowana, Word po­traktuje ją jak nową zmienną i nada jej typ Variant. Co więcej, VBA uzna, że chce się, aby nowa nazwa pliku została przypisana zmiennej NazwaList i zapisze zmieniony dokument pod jego orygi­nalną nazwą, przechowywaną w zmiennej NazwaListu. Spowoduje to utratę oryginalnego doku­mentu, który zostanie nadpisany bez ostrzeżenia!

Option Expllcit

Aby uniknąć problemu opisanego w powyższym przykładzie, w sekcji deklaracji każdego modułu kodu należy wpisać wiersz:

Option Explicit

Dzięki temu Word nie wykona żadnego programu, w którym zauważy niezadeklarowane zmienne. Aby VBA automatycznie wpisywał instrukcję Option Explicit do każdego nowego modułu kodu, trzeba zaznaczyć pole wyboru Reguire Variable Declaration w oknie Options. Namawia się do zaznaczenia tej opcji.

Teraz omówione zostaną niektóre typy danych przedstawione w tabeli 5.1.

Numeryczne typy danych

Do numerycznych typów danych należą: Integer, Long, Single, Double i Currency. Programiści VBA stosują najczęściej zmienne typu Integer i Long. Na przykład liczbę znaków w dokumencie Worda można zapisać w zmiennej typu Long.

Nawiasem mówiąc, dokumentacja VBA informuje czasem, że dana wartość jest typu Integer, kiedy tak naprawdę jest ona typu Long. Jest to prawdopodobnie spowodowane tym, że w czasach Win­dows 3.11 (16-bitowego systemu operacyjnego) wiele z tych wartości posiadało typ Integer. Jednak wraz z pojawieniem się systemu Windows 95 i wersji późniejszych, wartościom tym przypisano typ Long.

Dane typu Boolean

Zmienna typu Boolean może przyjąć jedną z dwóch wartości: True lub False. Ten bardzo pomoc­ny typ został wprowadzony do VBA stosunkowo niedawno. Przed wprowadzeniem typu Boolean, VBA rozpoznawał 0 jako False, a każdą wartość różną od zera jako True.

Dane typu String

String to łańcuch znaków. Pusty String nie zawiera żadnych znaków. Łańcuch znaków może za­wierać zwykły tekst (litery, cyfry, znaki interpunkcji), jak również znaki takie jak vbCrLf (powrót karetki/wysunięcie wiersza) lub vbTab (znak tabulacji). Stała typu String musi być wzięta w cudzy­słów. Pusty String (łańcuch znaków) zapisuje się jako pusty cudzysłów:

PustyString = ""

Są dwa rodzaje łańcuchów znaków: łańcuchy o stałej długości i łańcuchy o zmiennej długości. Zmienną przechowującą łańcuch znaków o stałej długości deklaruje się w następujący sposób:

Dim NazwaZmiennej As String * DługośćŁańcuchaZnaków

Na przykład poniższy wiersz kodu deklaruje zmienną przechowującą łańcuch 10 znaków:

Dim Nazwisko As String * 10

Należy zwrócić uwagę, że kod:

Dim s As String *10

s = "test"

Debug.Print s & "/"

wyświetli w oknie Immediate następujący wiersz:

test /

Oznacza to, że puste miejsca w łańcuchu znaków o stałej długości są wypełniane spacjami.

Drugi rodzaj zmiennych typu String to zmienne przechowujące łańcuchy znaków o zmiennej dłu­gości. Deklaruje się je w następujący sposób:

Dim NazwaZmiennej As String

Kod:

Dim s As String

s = "test"

Debug.Print s & "/"

s = "inny test"

Debug.Print s & "/"

wyświetli w oknie Immediate następujące wiersze:

test/

inny test/

Łańcuchy znaków o zmiennej długości są używane znacznie częściej niż łańcuchy znaków o stałej długości, chociaż te ostatnie mają swoje ważne zastosowania.

Typ Date

Zmienne typu Date wymagają 8 bajtów pamięci i są przechowywane jako liczby dziesiętne repre­zentujące daty między 1 stycznia 100 a 31 grudnia 9999 (nie występuje tu problem Y2K) i godziny między 00:00:00 a 23:59:59.

Aby zmiennej typu Date przypisać datę, można ją umieścić między znakami numeru lub wziąć ją w cudzysłów. Oto przykłady przypisania daty i czasu:

Dim dt As Date

dt = #22/4/2000#

dt = "22 kwietnia 2000"

dt = #1/1/99#

dt = #12:50:00 PM#

dt = #2/12/99 12:50:00 AM#

VBA posiada dużą ilość funkcji służących do operacji na datach i czasie. Dokumentacja VBA za­wiera dokładne informacje, jak użyć tych funkcji do manipulowania datami i czasem w tworzonych programach.

Typ Variant

Zmienna typu Variant może przechowywać wszystkie rodzaje danych z wyjątkiem łańcuchów zna­ków o stałej długości oraz danych o typach zdefiniowanych przez programistę. W poprzedniej części tego rozdziału omówiono już zalety i wady typu Variant i wyjaśniono, dlaczego generalnie należy unikać stosowania tego typu.

Typy obiektów Worda

VBA Worda posiada wiele dodatkowych typów danych, które można ogólnie określić jako typy obiektów Worda. Oto lista typów obiektów modelu obiektowego Worda:

Border

Document

Font

Options

PageSetup

Paragraph

ParagraphFormat

Selection

Styl e

Table, Cell, Row, Column

Template

Window

Można zatem zadeklarować następujące zmienne:

Dim dok As Document

Dim czcionka As Font

Dim opcja As Options

Dim akapit As Paragraph

Dim zaznaczenie As Selection

Dim tabela As Table

Dim szablon As Template

Deklarowanie zmiennej za pomocą słów kluczowych As Object

Można również zadeklarować dowolny obiekt Worda za pomocą instrukcji As Object, jak pokazuje następujący przykład:

Dim akapit As Object

Należy jednak unikać deklarowania zmiennych w ten sposób. Preferowany sposób to:

Dim akapit As Paragraph

ponieważ do momentu uruchomienia programu, Word nie wie, z jakim typem obiektu ma do czy­nienia i dopiero w trybie wykonywania programu musi to określić, co spowalnia wykonanie pro­gramu. Deklarowanie zmiennej za pomocą instrukcji As Object jest nazywane late binding.

Instrukcja Set

Zmienne obiektowe deklaruje się podobnie jak inne zmienne. Oto przykład deklaracji dwóch zmiennych:

Dim LiczbaCałkowita As Integer 'deklaracja zmiennej nieobiektowej Dim dok As Document 'deklaracja zmiennej obiektowej

Jednak przypisanie wartości do zmiennej wygląda inaczej dla obiektów, a inaczej dla innych zmiennych. Aby przypisać wartość do zmiennej obiektowej, należy użyć instrukcji Set. Poniższy kod przypisuje aktywny dokument Worda do zmiennej dok:

Set dok = ActiveDocument

Tablice

Tablica jest kolekcją zmiennych o identycznych nazwach, ale o różnych wartościach indeksu. Na przykład, aby zapisać pierwszych 100 akapitów dokumentu, można by zadeklarować tablicę w na­stępujący sposób:

Dim Akapit(1 To 100) As Paragraph

Tablica nosi nazwę Akapit i zawiera 100 elementów. Dolny indeks tablicy wynosi 1, a górny 100. Każda ze zmiennych:

Akapit(1), Akapit(2),...,Akapit(100)

ma typ Paragraph. Jeżeli pominie się pierwszy indeks tablicy w deklaracji:

Dim Akapit (100) As Paragraph

VBA automatycznie ustawi dolny indeks na 0, dzięki czemu tablica będzie zawierać 101 elementów.

Łatwo zauważyć zalety tablicy: deklarowanie 100 oddzielnych zmiennych (zamiast jednej 100-ele­mentowej tablicy) nie jest przyjemną perspektywą. Poza tym, jak wkrótce będzie pokazane, można wykonywać operacje na wszystkich elementach tablicy jednocześnie za pomocą kilku prostych programistycznych technik. Na przykład poniższy kod pogrubia wszystkie 100 akapitów tablicy:

For i = 1 To 100

Akapit(i).Range.Bold = True

Next i

Wymiar tablicy

Tablica Akapit zdefiniowana w poprzednim podrozdziale jest jednowymiarowa. Można również definiować tablice wielowymiarowe. Na przykład poniższy wiersz kodu:

Dim Komórki (1 To 10, 1 To 100) As String

deklaruje tablicę dwuwymiarową o indeksach od 1 do 10 i od 1 do 100. Zatem tablica ma rozmiar I 0 x 100 = 1000.

Tablice dynamiczne

Jeżeli zadeklarujemy tablicę w następujący sposób:

Dim Pliki (1 To 10) As String

zarówno dolny, jak i górny indeks są określone, dzięki czemu rozmiar tablicy jest stały. Istnieją jednak sytuacje, kiedy w czasie deklarowania tablicy nie wie się, jaki powinna mieć ona rozmiar. W takich przypadkach można zastosować tablicę dynamiczną oraz instrukcję ReDim.

Tablicę dynamiczną deklaruje się bez podania indeksu (nawiasy są puste), jak pokazuje poniższy wiersz kodu:

Dim Pliki() As String

Rozmiar tablicy dynamicznej ustala się za pomocą instrukcji ReDim:

ReDim Pliki (1 To 10)

Rozmiar tej samej tablicy można zmienić ponownie:

ReDim Pliki (1 To 100)

Warto zwrócić uwagę, że zmiana rozmiaru tablicy usuwa jej zawartość - chyba że użyje się słowa kluczowego Preserve:

ReDim Preserve Pliki (1 To 200)

Kiedy używamy Preserve, możemy zmienić tylko górny indeks tablicy (i tylko ostatni wymiar wie­lowymiarowej tablicy).

Funkcja Ubound

Funkcja UBound zwraca bieżący górny indeks tablicy. Przydaje się do określenia, kiedy rozmiar tablicy powinien zostać zmieniony. Można założyć, że w tablicy o nazwie Pliki chce się zapisać nazwy nieznanej liczby plików. Jeżeli numer następnego pliku wynosi iNastępnyPlik, poniższy kod sprawdza, czy górny indeks jest mniejszy od iNastępnyPlik. Jeżeli tak, górny indeks tablicy zostaje zwiększony o 10, aby zrobić miejsce na nazwę nowego pliku (bieżąca zawartość tablicy zostaje zachowana dzięki słowu kluczowemu Preserve):

If UBound(Pliki) < iNastępnyPlik Then

ReDim Preserve Pliki(UBound(Pliki) + 10)

End If

Zmiana rozmiaru tablicy wymaga czasu. Należy zatem unikać częstych zmian rozmiaru tablicy, ustalając wystarczająco wysoki indeks górny. W powyższym przykładzie do indeksu górnego dodano od razu 10, a nie 1. Należy wyważyć, co jest korzystniejsze: częste zmiany rozmiarów tablicy czy zadeklarowanie tablicy o takim rozmiarze, aby nie trzeba go było zmieniać. Pamiętać trzeba, że częsta zmiana rozmiaru tablicy może oznaczać marnowanie czasu, natomiast zadeklarowanie zbyt dużej tablicy może oznaczać marnowanie pamięci, jeżeli nie zostaną wykorzystane jej wszystkie elementy.

Konwencje stosowane w nazywaniu zmiennych

Ponieważ pisane programy mogą stać się z czasem coraz bardziej skomplikowane, powinno się uczynić wszystko, aby były one jak najbardziej czytelne. W jakiś czas po napisaniu programu mo­żna nie pamiętać wszystkich jego niuansów, dlatego dodawanie komentarzy jest tak ważne.

Można również ułatwić czytanie kodu dzięki stosowaniu jednolitych nazw stałych, zmiennych, pro­cedur i innych elementów kodu. Ogólnie mówiąc, nazwa powinna mieć dwie cechy. Po pierwsze powinna przypominać cel albo zadanie, jakie dany element realizuje. Można założyć, że zmiennym typu Document chce się przypisać kilka dokumentów zawierających faktury. Poniższy kod:

Dim dokl As Document

Dim dok2 As Document

Set dokl = Documents.Open("c:\FakturaZaKsiążki.doc")

Set dok2 = Documents.Open("c:\FakturaZaPłyty.doc")

jest zupełnie poprawny, ale 1000 wierszy kodu dalej i 6 miesięcy później, czy będzie się w stanie odróżnić dok1 od dok2? Ponieważ został zadany sobie trud nadania plikom opisowych nazw, to samo powinno się zrobić ze zmiennymi:

Dim dokKSiążki As Document

Dim dokPłyty As Document

Set dokKsiążki = Documents.Open("c:\FakturaZaKsiążki.doc")

Set dokPłyty = Documents.Open("c:\FakturaZaPłyty.doc")

Oczywiście istnieją wyjątki od każdej reguły, ale generalnie lepiej nadać zmiennym nazwy opisowe. To samo dotyczy innych elementów wymagających nazw - stałych, procedur, kontrolek, formula­rzy i modułów kodu.

Po drugie, nazwa zmiennej powinna zawierać informację o swoich cechach, na przykład o swoim typie. Wielu programistów stosuje konwencję, w myśl której kilka pierwszych znaków nazwy zmiennej wskazuje jej typ. Konwencja ta jest nazywana notacją węgierską na cześć węgierskiego programisty Charlesa Simonyi, któremu przypisuje się jej wymyślenie.

Tabele 5.3 i 5.4 zawierają przedrostki stosowane w nazwach zmiennych standardowych i obiekto­wych występujących w tej pracy. Oczywiście każdy programista może stworzyć własną konwen­cję. Trzeba tylko pamiętać, aby nazwy były konsekwentne. Przedrostki mają przypominać programiście typ danych, ale niełatwo je stworzyć używając jedynie kilku znaków - im przedrostki dłuższe, tym mniejsze prawdopodobieństwo, że będzie się je stosować. Należy zwrócić uwagę, że przedrostek c jest używany dla typu Integer i Long.

Tabela 5.3. Przedrostki używane w nazwach zmiennych standardowych.

Zmienna

Przedrostek

Boolean

b lub f

Byte

b lub bt

Currency

cur

Date

dt

Double

d lub dbl

lnteger

i, c lub int

Long

1, c lub lng

Single

s lub sng

String

s lub str

Typ zdefiniowany przez programistę

u lub ut

Variant

v lub var

Tabela 5.4. Przedrostki używane w nazwach zmiennych obiektowych.

Zmienna

Przedrostek

Bookmark

bmk

Dialog

dial

Document

doc

Field

fld

Font

fnt

Frame

fra

Paragraph

para

Range

rng

Selection

sel

Table

tbl

Word

wrd

Oprócz typu danych, zmienna posiada zakres i okres życia. Niektórzy programiści w nazwie zmiennej zawierają informację o jej zakresie. Na przykład, g oznacza zakres globalny, m - zakres modułu. A zatem, giRozmiar jest zmienną globalną o typie Integer. Zakres i okres życia zmiennej omawiany jest w następnych podrozdziałach (ale nie stosuje się nazw zmiennych, które zawierają informację o ich zakresie).

Zakres zmiennych

Zmienne i stałe posiadają zakres, który wskazuje, w jakim miejscu programu są one rozpoznawane widoczne). Zmienna lub stała może mieć zakres lokalny, modułowy lub publiczny.

Zmienne lokalne

Zmienną - lub stałą - lokalną deklaruje się w procedurze. Na rysunku 5.2 ZmiennaLokalna jest zmienną lokalną, StalaLokalna jest stałą lokalną. Zmienna - lub stała lokalna - nie jest widoczna poza procedurą, w której została zadeklarowana. Jeżeli spróbuje się uruchomić procedurę B przed­stawioną na rysunku 5.2, otrzyma się komunikat o błędzie, informujący, że nie zdefiniowano zmiennej, i nazwa ZmiennaLokalna zostanie wyróżniona.

0x01 graphic

Rysunek 5.2. Przykłady zakresu zmiennych.

Jedną z zalet zmiennych lokalnych jest to, że można używać tej samej nazwy w różnych procedu­rach, ponieważ każda zmienna lokalna jest widoczna tylko w swojej procedurze.

Zmienne modułowe

Zmienną - lub stałą - modułową deklaruje się w sekcji deklaracji modułu kodu (standardowego, klasy lub formularza). Zmienne - i stałe - modułowe mogą być prywatne (private) lub publiczne (public). Mówiąc najprościej, publiczne zmienne - i stałe - modułowe są widoczne we wszystkich procedurach wszystkich modułów projektu. Prywatne zmienne - i stałe - modułowe są widoczne w procedurach modułu, w którym zostały zadeklarowane.

Zmienne i stałe publiczne deklaruje się za pomocą słowa kluczowego Public:

Public Liczba As Integer

Public Const Pi = 3.14

Zmienne i stałe prywatne deklaruje się za pomocą słowa kluczowego Private:

Private Liczba As Integer

Private Const Pi = 3.14

Deklarując zmienną modułową, zamiast słowa Private można użyć słowa Dim. Może to jednak uczynić kod mniej czytelnym, dlatego zmienne o zakresie modułowym należy deklarować za po­mocą słowa Private.

Warto jeszcze wspomnieć o jednej rzeczy. Zmienna - lub stała - publiczna zadeklarowana w module standardowym lub module klasy (ale nie w module formularza) jest widoczna w każdym projekcie posiadającym odwołanie do projektu, w którym została ona zadeklarowana. Ponieważ projekt za­wierający dokument zawsze posiada odwołanie do projektu zawierającego dołączony szablon, wszystkie publiczne zmienne i stałe zadeklarowane w projekcie zawierającym szablon są widoczne w projekcie zawierającym dokument. Poza tym wszystkie publiczne zmienne i stałe zadeklarowane w projekcie zawierającym szablon Normal są widoczne we wszystkich projektach.

Zmienne publiczne są czasem nazywane zmiennymi globalnymi, ale określenie to wychodzi z użycia.

Okres życia zmiennej

Zmienne charakteryzują się okresem życia. Różnica między okresem życia a zakresem jest prosta: okres życia określa, jak długo (i kiedy) zmienna zwraca wartość, natomiast zakres określa miejsce, którym zmienna jest dostępna lub widoczna.

Kiedy rozważyć następujący przykład:

Sub ProceduraA ( )

Dim ZmiennaLOkalna As Integer

ZmiennaLokalna = 0

Call ProceduraB

ZmiennaLokalna = 1

End Sub

Należy zwrócić uwagę, że ZmiennaLokalna jest zmienną lokalną. Po wykonaniu wiersza kodu:

Call ProceduraB

następuje przejście do procedury B. W czasie wykonywania procedury B, zmienna ZmiennaLokalna jest poza zasięgiem, ponieważ jest ona lokalną zmienną procedury A - jednak nadal żyje (jest w stanie zwrócić wartość). Innymi słowy, zmienna ciągle istnieje i posiada wartość, ale nie jest dostępna dla kodu procedury B. W procedurze B mogłaby również znajdować się zmienna o nazwie Zmienna­Lokalna, która nie miałaby nic wspólnego ze zmienną o tej samej nazwie w procedurze A.

Po wykonaniu procedury B, następuje powrót do procedury A, a konkretnie do wiersza:

ZmiennaLokalna = 1

Jest to poprawna instrukcja, ponieważ zmienna ZmiennaLokalna znowu jest w zasięgu.

Zatem okres życia zmiennej lokalnej ZmiennaLokalna trwa od momentu, kiedy VBA wchodzi do procedury A, aż do momentu, kiedy VBA z niej wychodzi. Okres życia zmiennej ZmiennaLokalna obejmuje również czas wykonywania procedury B wywołanej z procedury A, mimo że w tym cza­sie zmienna ZmiennaLokalna jest poza zasięgiem.

Nawiasem mówiąc, dokumentacja VBA czasem miesza zakres z widocznością zmiennej. Wydaje się, że twórcy plików pomocy rozumieją różnicę, ale nie zawsze używają tych terminów poprawnie.

Zmienne statyczne

Należy przypomnieć, iż zmienna może znajdować się w zasięgu lub poza nim i nadal zachowywać swoją wartość. Kiedy jednak okres życia zmiennej dobiega końca, zmienna zostaje zniszczona, a jej war­tość utracona. Okres życia określa istnienie zmiennej; zakres zmiennej określa jej dostępność.

Rozważając następujące procedury:

Sub ProceduraA()

Call ProceduraB

Call ProceduraB

Call ProceduraB

Call ProceduraB

Call ProceduraB

End Sub

Sub ProceduraB()

Dim x As Integer

x = 5

...

End Sub

Procedura A pięć razy wywołuje procedurę B. W momencie wywołania procedury B, VBA tworzy zmienną lokalną x; kiedy wykonanie procedury B dobiega końca, VBA usuwa zmienną lokalną. Zatem zmienna x jest tworzona i usuwana pięć razy.

Zwykle o to właśnie chodzi. Zdarzają się jednak sytuacje, kiedy chce się, aby okres życia zmiennej lokalnej trwał dłużej niż okres życia procedury, w której została ona zadeklarowana. Można założyć, że chce się stworzyć procedurę, która wykona coś specjalnego, kiedy wywoła się ją po raz pierwszy. Na przykład, poniższe makro zmienia czcionkę zaznaczonego tekstu na Comic Sans:

Sub ZmienNaComic()

Selection.Font.Name = "Comic Sans"

End Sub

Przypuszczając, że chce się ostrzec użytkownika, że Comic Sans jest czcionką nieformalną, i zapytać, czy naprawdę chce dokonać zmian. Chce się to ostrzeżenie i pytanie wyświetlić tylko raz, aby nie naprzykrzać się użytkownikowi. W takiej sytuacji potrzebuje się zmiennej lokalnej, która pamięta, czy procedura ZmienNaComic jest wywoływana po raz pierwszy. Taką zmienną jest zmienna statyczna.

Zmienna statyczna jest zmienną lokalną żyjącą tak długo, jak długo żyje moduł - a nie tylko pro­cedura - w której została zadeklarowana. Zmienna statyczna zachowuje swoją wartość dopóty, dopóki jest aktywny dokument lub szablon zawierający moduł kodu (nawet gdy żaden kod nie jest wykonywany).

Zatem zmienna statyczna posiada zakres zmiennej lokalnej, ale okres życia zmiennej modułowej.

Modyfikując teraz makro ZmienNaComic, aby wyglądało tak, jak przedstawia wydruk 5.2. Naj­pierw należy zadeklarować zmienną statyczną typu Boolean o nazwie NiePierwszyRaz. Użycie zmiennej o nazwie PierwszyRaz może wydawać się prostsze, jednak problem polega na tym, że VBA automatycznie inicjalizuje zmienne typu Boolean na wartość False. Oznacza to, że w mo­mencie pierwszego wywołania procedury ZmienNaComic zmienna PierwszyRaz miałaby wartość False, a nie o to chodzi. Inicjalizowanie zmiennych zostanie omówione za chwilę.

Wydruk 5.2. Zmodyfikowana procedura ZmienNaComic używająca zmiennej statycznej.

Sub ZmienNaComic()

'Zadeklaruj zmienną statyczną typu Boolean

Static NiePierwszyRaz As Boolean

'Jeżeli użytkownik dokonuje zmiany

'po raz pierwszy, zapytaj o potwierdzenie

If NiePierwszyRaz = False Then

If MsgBox("Comic Sans jest czcionką nieformalną. Kontynuować?", _

­vbYesNo) = vbYes Then

'Dokonaj zmiany

Selection.Font.Name = "Comic Sans"

End If

'Uaktualnij wartość zmiennej

NiePierwszyRaz = True

Else

'Jeżeli użytkownik dokonuje zmiany

'po raz kolejny, po prostu dokonaj zmiany Selection.FOnt.Name = "Comic Sans"

End If

End Sub

Instrukcja If sprawdza, czy wartość zmiennej NiePierwszyRaz wynosi False - tak będzie w mo­mencie pierwszego wywołania procedury ZmienNaComic. W takim przypadku VBA wyświetla okno komunikatu przedstawione na rysunku 5.3. Jeżeli użytkownik kliknie przycisk Tak, czcionka zostanie zmieniona. Zmiennej statycznej NiePierwszyRaz typu Boolean zostaje przypisana wartość True. Zmienna NiePierwszyRaz - jako zmienna statyczna - zachowuje swoją wartość nawet po wykonaniu procedury ZmienNaComic.

0x01 graphic

Rysunek 5.3.Okno komunikatu, wyświetlane, kiedy wartość zmiennej NiePierwszyRaz wynosi False

W czasie następnego wykonywania makra wartość zmiennej NiePierwszyRaz będzie wynosić True, dzięki czemu warunek If:

If NiePierwszyRaz = False Then

będzie fałszywy i funkcja MsgBox nie zostanie wykonana. Wykonana zostanie natomiast klauzula Else: czcionka zostanie zmieniona bez wyświetlania jakiegokolwiek komunikatu. Zmienne statyczne nie są stosowane zbyt często, ale w niektórych sytuacjach mogą okazać się bardzo pomocne.

Chociaż lokalną zmienną statyczną można zastąpić zmienną modułową, lepiej używać zmiennej statycznej, ponieważ jej zakres jest bardziej ograniczony niż zakres zmiennej modułowej. Dzięki stosowaniu zmiennej lokalnej o zwiększonym okresie życia, można uniknąć przypadkowej zmiany wartości zmiennej spoza procedury, w której została zadeklarowana. Należy pamiętać, że proce­dura może być fragmentem znacznie większego modułu kodu, w którym dzieje się wiele różnych rzeczy. Lepiej więc ukryć zmienną NiePierwszyRaz przed innymi procedurami.

Inicjalizacja zmiennych

Kiedy VBA rozpoczyna wykonywanie procedury, wszystkie jej zmienne są automatycznie inicjali­zowane, czyli przypisywane są im wstępne wartości. Generalnie nie należy polegać na inicjalizacji, ponieważ program jest mnie czytelny i podatny na powstawanie błędów logicznych. Należy więc inicjalizować zmienne lokalne samodzielnie jak pokazuje poniższy wydruk:

Sub Inicjalizuj()

Dim x As Integer

Dim s As String

x = 0 'Zmiennej x przypisz 0

s = "" 'Zmiennej s przypisz pusty łańcuch znaków

'W tym miejscu dodaj kod...

End Sub

Należy zwrócić uwagę, że nie można zainicjalizować zmiennych statycznych. Należy więc zapoznać się z zasadami, według których VBA inicjalizuje zmienne:

zmiennym numerycznym (Integer, Long, Single, Double i Currency) VBA przypisuje wartość zero;

łańcuchowi znaków o zmiennej długości VBA przypisuje pusty łańcuch znaków;

łańcuch znaków o stałej długości VBA wypełnia znakiem reprezentowanym przez znak ASCII 0 lub Chr(0);

zmiennej typu Variam VBA przypisuje wartość Empty;

zmiennej obiektowej VBA przypisuje wartość Nothing.

Słowo kluczowe Nothing spełnia kilka funkcji w VBA. Nothing służy do usuwania odwołania do obiektu. Służy też jako wartość zwracana przez niektóre funkcje, z reguły do wskazania, że operacja się nie powiodła. Wreszcie, służy do inicjalizowania zmiennych obiektowych.

Operatory języka VBA

VBA używa garści operatorów i znaków porównań - niektóre z nich przedstawia tabela 5.5.

Tabela 5.5. Operatory i znaki porównań.

Typ

Nazwa

Symbol

Operatory arytmetyczne

Dodawanie

Odejmowanie

Mnożenie

Dzielenie

Dzielenie bez reszty

Potęgowanie

Modulo

+

-

*

/

\

^

Mod

Operator łańcucha znaków

Konkatenacja

&

Operatory logiczne

AND

OR

NOT

And

Or

Not

Operatory porównania

Równy

Mniejszy od

Większy od

Mniejszy lub równy

Większy lub równy

Różny

=

<

>

<= lub =<

>= lub =>

<> lub ><

Operator Mod zwraca resztę z dzielenia. Na przykład:

8 Mod 3

zwraca 2, ponieważ reszta z dzielenia 8 przez 3 wynosi 2.

Konkatenacja oznacza połączenie łańcuchów znaków. Na przykład wyrażenie:

"Być albo " & "nie być"

jest tożsame z wyrażeniem:

"Być albo nie być"

Funkcje i podprogramy

VBA pozwala na definiowanie trzech typów procedur. Są to: funkcja, podprogram (subroutine) i Property. Różnica między funkcją a podprogramem polega na tym, że funkcja zwraca wartość, a podprogram nie zwraca.

Wywoływanie funkcji

Funkcję deklaruje się według następującego wzoru:

[Public lub Private] Function NazwaFunkcji (Parametrl As TypDanychl, _

­ Parametr2 As TypDanych2, ...) As TypZwracanejWartości

Należy podać typ danych nie tylko każdego parametru, ale i zwracanej wartości. W przeciwnym razie VBA przypisze im typ Variant.

Opcjonalne słowa kluczowe Public i Private omówione zostaną za chwilę, ale nietrudno się domyślić, że ­podobnie jak w deklaracjach zmiennych - wskazują one zakres funkcji. Na przykład funkcja DodajJeden, przedstawiona w wydruku 6.1, dodaje 1 do oryginalnej wartości.

Wydruk 6. 1. Funkcja DodajJeden.

Public Function DodajJeden(Wartość As Integer) As Integer DodajJeden = Wartość + 1

End FunCtion

Aby użyć wartości zwracanej przez funkcję, należy wywołać funkcję w miejscu, w którym ta war­tość ma zostać odczytana. Na przykład wiersz kodu:

MsgBox "1 + 5 = " & DodajJeden(5)

wyświetla okno komunikatu pokazane na rysunku 6.1. Wyrażenie

DodajJeden(5)

zostaje zastąpione przez wartość zwracaną przez funkcję DodajJeden - w tym przypadku 6.

Należy zwrócić uwagę, że generalnie parametry przekazywane funkcji w czasie jej wywoływania muszą znajdować się w nawiasach.

Aby funkcja mogła zwrócić wartość, w treści funkcji należy przypisać tę wartość do nazwy funkcji. Wydruk 6.2 pokazuje bardziej złożony przykład funkcji.

0x01 graphic

Rysunek 6.1. Okno komunikatu wygenerowane za pomocą instrukcji MsgBox.

Wydruk 6.2. Przypisywanie zwracanej wartości do nazwy funkcji.

Function Policz (Co As String) As Long

'Zwróć liczbą znaków lub liczbę wyrazów

'w aktywnym dokumencie

'Zwróć -1, jeżeli funkcji nie przekazano

'ani wartości "Znaki", ani "Wyrazy"

If Co = "Znaki" Then

'Zwróć liczbę znaków

Policz = ActiveDocument.Characters.Count

ElseIf Co = "wyrazy" Then

'Zwróć liczbę słów

Policz = ActiveDocument.Words.Count

Else

'Zwróć -1

Policz = -1

End If

End Function

Funkcja Policz zwraca liczbę znaków lub liczbę wyrazów w aktywnym dokumencie w zależności od wartości parametru przekazywanego funkcji. Parametry zostaną omówione w dalszej części tego rozdziału. Warto zwrócić uwagę, że do nazwy funkcji przypisane są różne wartości w zależ­ności od wartości parametru. Przypisania wzajemnie się wykluczają; tylko jedno z nich zachodzi w czasie danego wywołania funkcji.

Ignorowanie zwracanej wartości

Może się zdarzyć, że chce się wywołać funkcję, ale nie potrzebuje się wartości, którą ona zwraca. Można założyć, że fragment jest zmienną reprezentującą fragment (Range) tekstu dokumentu Worda. Można przesunąć koniec fragmentu tekstu za pomocą metody MoveEnd. Jest to funkcja, która przesuwa koniec fragmentu tekstu o podaną liczbę jednostek i zwraca liczbę jednostek, o którą ko­niec tego fragmentu został rzeczywiście przesunięty. Liczba przesuniętych jednostek może być mniejsza od liczby podanych jednostek, jeżeli fragment tekstu „zderzy się" z początkiem lub koń­cem dokumentu przed zakończeniem zdania.

Na przykład kod:

Dim odległość As Long

odległość = fragment.MoveEnd(wdCharacter, 5)

próbuje przesunąć koniec fragmentu tekstu fragment o pięć znaków w prawo. Jeżeli próba zakoń­czy się sukcesem, funkcja zwraca liczbę 5. Jeżeli jednak na prawo od bieżącej pozycji końcowej znajduje się mniej niż 5 znaków, fragment tekstu zostanie przesunięty w prawo o tyle znaków, o ile to możliwe i funkcja zwróci liczbę znaków, o którą fragment został przesunięty.

Chociaż wartość zwracana przez metodę MoveEnd często jest użyteczna, są sytuacje, kiedy nie jest ona potrzebna. Na przykład poniższy kod zaznacza pierwszy akapit aktywnego dokumentu, w tym również znak akapitu:

Dim fragment As Range

Set fragment = ActiveDocument.Paragraphs(1).Range

fragment.Select

Jeżeli nie chce się zaznaczyć znaku akapitu, można przed zaznaczeniem fragmentu tekstu użyć metody MoveEnd, aby przesunąć koniec fragmentu tekstu o jeden znak w lewo:

Dim odległość As Long

Dim fragment As Range

Set fragment = ActiveDocument.Paragraphs(1).Range

odległość = fragment.MoveEnd(wdCharacter, -1)

fragment.Select

Na lewo od bieżącego punktu końcowego znajduje się co najmniej jeden znak - znak akapitu jest zawsze obecny, więc fragment tekstu (Range) zawiera co najmniej jeden znak - dlatego funkcja MoveEnd zwróci wartość -1. Przesunięcie odbywa się w lewo, więc wartość jest negatywna..

W poprzednich wersjach VBA nie byłoby innego wyboru jak tylko zadeklarować zmienną od­ległość, a następnie zignorować jej wartość, jak to zostało zrobione w powyższym przykładzie. Obecna wersja VBA pozwala na wyszczuplenie kodu w następujący sposób:

Dim fragment As Range

Set fragment = ActiveDocument.Paragraphs(1).Range fragment.MoveEnd wdCharacter, -1

fragment.Select

Należy podkreślić, że wywołana została funkcja bez określania zwracanej wartości i nie zostały umieszczone para­metry w nawiasach. W ten sposób informuje się VBA, że nie interesuje programistę wartość zwracana przez funkcję.

Wywoływanie podprogramów

Podprogram deklaruje się według następującego wzoru:

[Public lub Private] Sub NazwaPodprogramu (Parametrl As TypDanychl, _ Parametr2 As TypDanych2, ...)

Deklaracja podprogramu w przeciwieństwie do deklaracji funkcji nie zawiera fragmentu As Typ­ZwracanejWartości. Należy zwrócić również uwagę na użycie słowa kluczowego Sub zamiast słowa Function.

Ponieważ podprogramy nie zwracają wartości, nie można używać ich w wyrażeniach. Aby wywo­łać podprogram o nazwie PodprogramA, można napisać:

Call PodprogramA(parametry, ...)

lub po prostu

PodprogramA parametry

Kiedy używa się słowa kluczowego Call, parametry muszą być umieszczone w nawiasach.

Parametry i argumenty

Kiedy rozważyć następujący prosty podprogram, który nie robi nic poza wyświetleniem okna komuni­katu zawierającego nazwisko osoby:

Sub WyświetlNazwisko(sNazwisko As String)

MsgBox "Nazywam się " & sNazwisko

End Sub

Aby wywołać ten podprogram, napisanoby na przykład:

WyświetlNazwisko "Kowalski"

lub

Call WyświetlNazwisko("Kowalski")

Zmienna sNazwisko w deklaracji procedury:

Sub WyświetlNazwisko(sNazwisko As String)

jest nazywana parametrem. Generalnie, kiedy wywołuje się procedurę, parametr musi zostać wy­pełniony. Wartość przekazywana do procedury jest nazywana argumentem. A zatem w powyższym przykładzie argumentem jest łańcuch znaków „Ko­walski".

Warto zauważyć, że wielu programistów używa słów „parametr" i „argument" zamiennie. Należy jednak pamiętać, że parametr jest jak zmienna, natomiast argument jest jak wartość zmiennej. Dla­tego nieodróżnianie parametru od argumentu jest jak nieodróżnianie zmiennej od jej wartości.

Argumenty opcjonalne

Za pomocą słowa kluczowego Optional można określić argument jako opcjonalny. Nie można powiedzieć, że parametr jest opcjonalny: opcjonalne jest przypisanie wartości. Można rozważyć proce­durę przedstawioną w wydruku 6.3. Procedura ta zmienia nazwę i rozmiar czcionki zaznaczonego tekstu.

Wydruk 6.3. Stosowanie argumentu opcjonalnego.

Sub ZmienFormatowanie(NazwaCzcionki As String, _

Optional RozmiarCzcionki As Variant)

'Zmień nazwę czcionki

Selection.Font.Name = NazwaCzcionki

'Zmień rozmiar czcionki,

'jeżeli zostanie podany

If Not IsMissing(RozmiarCzcionki) Then Selection.Font.Size = CInt(RozmiarCzcionki)

End If

End Sub

Drugi parametr został zadeklarowany za słowem kluczowym Optional. Dzięki temu wywołując procedurę, można podać argument dla tego parametru lub go nie podawać:

ZmienFormatowanie "Arial Narrow", 24

lub

ZmienFormatowanie "Arial Narrow"

Warto podkreślić, że funkcja IsMissing użyta w treści procedury służy do określania, czy argument jest obecny. Jeżeli argument jest obecny, rozmiar czcionki zostaje zmieniony. Należy zwrócić również uwagę, że parametr RozmiarCzcionki posiada typ Variant, ponieważ funkcja IsMissing działa tylko z parametrami typu Variant. Za pomocą funkcji Clnt przekonwertowany zostałby typ Variant na typ Integer.

Procedura może mieć dowolną liczbę argumentów opcjonalnych, ale muszą się one znajdować na końcu listy parametrów. Poniższa deklaracja nie jest zatem poprawna:

Sub ZmienFormatowanie(Optional NazwaCzcionki As String, _ RozmiarCzcionki As Single)

Jeżeli w czasie wywoływania procedury opuści się argument w środku listy, musi się dodać spację. Na przykład, jeżeli zadeklarowana została następująca procedura:

Sub ZmienFormatowanie(

Optional NazwaCzcionki As String, _

Optional RozmiarCzcionki As Single, _

Optional PogrubienieCzcionki As Boolean)

End Sub

i wywołując ją chce się podać argumenty jedynie dla parametrów NazwaCzcionki i Pogrubienie­Czcionki, powinno się zrobić to w następujący sposób:

ZmienFormatowanie "Arial", , True

Warto zauważyć, że niektóre procedury wbudowane Worda mają argumenty opcjonalne, a inne nie. Oczywiście można opuścić tylko te argumenty, które w deklaracji są oznaczone jako opcjon­alne.

Argumenty predefiniowane

Niektóre procedury wbudowane mogą zawierać dużą liczbę parametrów. Oto na przykład deklara­cja funkcji ConvertToTable, która konwertuje zaznaczony tekst do postaci tabeli:

ConvertToTable( _

Separator, NumRows, NumColumns, _

InitialColumnWidth, Format, ApplyBorders, _ ApplyShading, ApplyFont, ApplyColor, _

ApplyHeadingRows, ApplyLastRow, _

ApplyFirstColumn, ApplyLastColumn, AutoFit, _ AutoFitBehavior, DefaultTableBehavior)

Wszystkie parametry tej funkcji są opcjonalne i posiadają typ Variant. Oto przykład wywołania tej procedury:

ConvertToTable wdSeparateByTabs, 5, 7, , ,True, True, True, _ ,,True, , ,True

Niezbyt czytelny wiersz, prawda?

Argumenty przedstawione w powyższym wywołaniu funkcji ConvertToTable są nazywane argu­mentami pozycyjnymi, ponieważ ich pozycja informuje VBA, jakie parametry one zastępują. Wła­śnie dlatego brakujący argument musi być wskazany przez spację.

VBA może również używać argumentów predefiniowanych, co pozwala wywołać procedurę Con­vertToTable w następujący sposób:

ConvertToTable _

Separator:=wdSeparateByTabs, NumRows:=5, _

NumColumns:=7, ApplyBorders:=True, _

ApplyShading:=True, ApplyFont:=True, _

­ApplyLastRow:=True, AutoFit:=True

Należy zwrócić uwagę na składnię stosowaną dla argumentów predefiniowanych - zwłaszcza na dwu­kropek przed znakiem równości.

Ten rodzaj wywołania jest znacznie lepszy od poprzedniego (z argumentami pozycyjnymi). Argu­menty predefiniowane są nie tylko czytelniejsze, ale mają dwie inne zalety: nie trzeba wpisywać spacji w miejsce brakujących argumentów i można wpisywać argumenty w dowolnej kolejności. Zaleca się stosowanie argumentów predefiniowanych, ze względu na to, że znacznie poprawiają czytelność kodu. Jednak wymagają one więcej miejsca, dlatego w krótkich przykładach omawia­nych w tej pracy nie będzie się ich zwykle stosować.

Przekazywanie argumentów przez referencję i przez wartość

Argumenty można przekazywać przez referencję (ByRef) lub przez wartość (ByVal).

Aby zrozumieć różnicę, należy rozważyć dwie procedury pokazane w wydruku 6.4. Procedura A przypi­suje zmiennej modułowej x wartość 5, wyświetla tę wartość, wywołuje procedurę DodajJeden z ar­gumentem x i ponownie wyświetla wartość x..

Wydruk G 4. Testowanie stów kluczowych ByVal i ByRef

Sub ProceduraA()

x = 5

MsgBox x

Call DodajJeden(x)

MsgBox x

End Sub

Sub DodajJeden(ByRef i As Integer)

i = i + 1

End Sub

Należy zwrócić uwagę na obecność słowa kluczowego ByRef w deklaracji procedury DodajJeden. Słowo ByRef sprawia, że VBA przekazuje procedurze DodajJeden referencję do zmiennej x. Oznacza to, że procedura DodajJeden zastępuje swój parametr i zmiennąx, dzięki czemu wiersz:

i = i + 1

staje się wierszem:

x = x + 1

A zatem, po wywołaniu procedury DodajJeden zmienna x ma wartość 6

Kiedy zmienić słowo kluczowe ByRefna słowo ByVal:

Sub DodajJeden(ByVal i As Integer)

i = i + 1

End Sub

W tym przypadku VBA nie przekazuje procedurze DodajJeden referencji do zmiennej x, ale war­tość zmiennej. Dzięki temu zmienna i w procedurze DodajJeden po prostu przyjmuje wartość 5. Po dodaniu 1 do tej wartości otrzymuje się 6. Zatem i wynosi 6, ale wartość argumentu x nie zmie­nia się. Dlatego obydwa okna komunikatów w procedurze A wyświetlają dla zmiennej x wartość 5.

Oba sposoby przekazywania argumentów mają swoje zastosowania. Aby zmienić wartość argu­mentu, należy zadeklarować odpowiadający mu parametr za pomocą słowa kluczowego ByRef, dzięki czemu wywoływana procedura ma dostęp do tego argumentu.

Kiedy nie chce się, aby argument został zmieniony, przekazuje się go przez wartość za pomocą sło­wa kluczowego ByVal. W tym przypadku wywoływana procedura otrzymuje jedynie wartość argu­mentu.

Zilustruje to poniższy przykład. Procedura A w wydruku 6.5 otrzymuje tekst aktywnego dokumentu i przekazuje go jako argument funkcji PoliczZnaki. Zwrócona wartość (liczba znaków aktywnego dokumentu) jest wyświetlona w oknie komunikatu.

Wydruk 6.5. Przekazywanie argumentu przez wartość.

Sub ProceduraA()

Dim sTekst As String

sTekst = ActiveDocument.Content.Text

MsgBox PoliczZnaki(sTekst)

End Sub

Function PoliczZnaki(ByVal sTxt as String)

PoliczZnaki = Len(sTxt)

End Function

Funkcja PoliczZnaki nie musi - i nie powinna - zmieniać tekstu. Jej zadaniem jest tylko policzenie liczby znaków w tekście. Dlatego przekazany został argument przez wartość. W ten sposób zmienna sTxt otrzymuje wartość tekstu przechowywaną w argumencie sTekst, czyli otrzymuje kopię tekstu.

Jeśli wyobrazić sobie, że funkcję PoliczZnaki zastąpi się procedurą zawierającą setki lub tysiące wier­szy kodu napisanego przez kogoś, na kim nie można zbytnio polegać. Naturalnie ma się obawę, że ta procedura może zmienić nasz tekst. Nie musi się sprawdzać kodu wiersz po wierszu, ponie­waż widać, że parametr sTxt jest wywoływany przez wartość, dzięki czemu procedura nie ma nawet dostępu do programowanego tekstu - jedynie do kopii tekstu.

Jest jedna wada przekazywania argumentów przez wartość. W powyższym przykładzie, VBA musi pobić kopię tekstu przekazywanego parametrowi sTxt. Zajmuje to dużo pamięci i czasu szczegól­nie w przypadku przekazywania zawartości całego dokumentu. Jeżeli dokument zawiera setki ty­sięcy znaków, procedura może okazać się zbyt wolna.

Podsumowując: jeżeli chce się, aby procedura zmodyfikowała argument, przekazuje się go przez referencję. Jeżeli argument ma pozostać niezmieniony, należy go przekazać przez wartość. Należy pamiętać, że przekazanie argumentu przez wartość może spowolnić program.

Warto zauważyć, że domyślnie argumenty są przekazywane przez referencję. Oznacza to, że war­tości argumentów mogą być zmieniane przez wywoływane procedury, chyba że użyje się słowa kluczowego ByVal.

Wychodzenie z procedury

Aby wyjść z procedury, zanim procedura sama zakończy swoje działanie, należy użyć instrukcji Exit Sub i Exit Function. Na przykład, jeżeli wartość parametru nie jest poprawna, można wyświet­lić komunikat informujący użytkownika o problemie, a następnie zakończyć działanie procedury (wydruk 6.6).

Wydruk 6.6 InstrukcjaExitSub.

Sub WyswietlNazwisko(sNazwisko As String)

If sNazwisko = "" Then

MsgBox "Wpisz nazwisko."

Exit Sub

End If

MsgBox "Wpisałeś nazwisko " & sNazwisko

End Sub

Procedury publiczne i prywatne

Procedury, podobnie jak zmienne i stałe, posiadają zakres. Można deklarować procedury za po­mocą słów kluczowych Public lub Private:

Public Function DodajJeden(i As Integer) As Integer

lub

Private Function DodajJeden(i As Integer) As Integer

Procedura prywatna może być wywołana tylko z modułu, w którym została zdefiniowana; proce­dura publiczna może być wywołana z każdego modułu projektu.

Jeżeli w deklaracji procedury nie występuje ani słowo Public ani słowo Private, procedura jest uznawana za publiczną.

Dodawanie odwołań do projektu

Aby wywołać procedurę publiczną rezydującą winnym projekcie, projekt wywołujący musi mieć odwołanie (referencję) do projektu wywoływanego.

Ogólnie mówiąc, projekt związany z danym dokumentem widzi tylko procedury znajdujące się w tym projekcie, w szablonie dołączonym do dokumentu lub w szablonie Normal.

Aby z danego projektu wywołać procedurę rezydującą w tym samym projekcie, nie musi się doda­wać żadnych odwołań. Również jeżeli z danego projektu chce się wywołać procedurę rezydującą w dołączonym szablonie, nie musi się dodawać żadnych odwołań, ponieważ Word automatycznie dodaje odwołanie do dołączonego szablonu.

Jeżeli natomiast dołączonym szablonem nie jest szablon Normal, a chce się wywołać procedurę re­zydującą w tym szablonie lub jeżeli chce się wywołać procedurę z innego projektu, musi się dodać odwołanie do wywoływanego projektu. W tym celu korzysta się z okna References (dostępnego z menu Tools), przedstawionego na rysunku 6.2.

0x01 graphic

Rysunek 6.2. Okno References.

Warto zauważyć, że jeżeli dołączonym do dokumentu szablonem nie jest szablon Normal, Word nie dołącza automatycznie odwołania do projektu Normal w projekcie dokumentu. Jest to trochę dziwne, ponieważ z dokumentu można wykonać każdą makrodefinicję rezydującą w szablonie Normal (za pomocą podmenu Makra na przykład), ale nie można wywołać takich makr za pomocą kodu w projekcie dokumentu, bez dodania odwołania do projektu Normal.

Pełne nazwy procedur

W różnych modułach mogą znajdować się procedury o identycznych nazwach. W przypadku wy­wołania procedury o niejednoznacznej nazwie, VBA wykona tę, którą znajdzie jako pierwszą. Może się jednak okazać, że nie jest to ta, o którą chodzi programiście.

Rozwiązaniem tego problemu jest stosowanie pełnej nazwy procedury według poniższego wzoru:

NazwaModułu.NazwaProcedury

Na przykład, jeżeli procedura publiczna o nazwie DodajJeden rezyduje w module o nazwie Moje­Procedury, można ją wywołać w następujący sposób:

MojeProcedury.DodajJeden

W razie potrzeby można podać również nazwę projektu:

NazwaProjektu.NazwaModułu.NazwaProcedury

Funkcje i instrukcje

wbudowane

VBA posiada wiele wbudowanych funkcji i podprogramów. W tym rozdziale i następnym omówi­one zostaną te z nich, które są używane najczęściej (przynajmniej w programach pisanych w Wordzie). Oto funkcje VBA:

Abs CVar GetAlISettings IsObject

Array CVDate GetAttr LBound

Asc CVErr GetAutoServerSettings LCase

AscB Date GetObject Left

Asc W DateAdd GetSetting LeftB

Atn DateDiff Hex Len

CBool DatePart Hour LenB

CByte DateSerial IIf LoadPicture

CCur DateValue IMEStatus Loc

CDate Day Impt LOF

CDbI DDB Input Log

CDec Dir InputB LTrim

Choose DoEvents InputBox Mid

Chr Environ InStr MidB

ChrB EOF InStrB Minute

ChrW Error Int MIRR

C Int Exp IRR Month

CLng FileAttr IsArray MsgBox

Command FileDateTime IsDate Now

Cos FileLen IsEmpty Nper

CreateObject Fix IsError NPV

CSng Format IsMissing Oct

CStr FreeFile IsNull Partition

CurDir FV IsNumeric Pmt

PPmt Seek StrConv Trim

PV Sgn String TypeName

QBColor Shell Switch UBound

Rate Sin SYD UCase

RGB SLN Tab Val

Right Space Tan VarType

RightB Spc Time Weekday

Rnd Sqr Timer Year

RTrim Str TimeSerial

Second StrComp TimeValue

Oto instrukcje VBA:

AppActivate Do...Loop Mid Reset

Beep End MidB Resume

Call Enum MkDir Return

ChDir Erase Name RmDir

ChDrive Error On Error RSet

Close Event On...GoSub SavePicture

Const Exit On...GoTo SaveSetting

Date FileCopy Open Seek

Declare For Each...Next Option Base Select Case

DefBool For...Next Option Compare SendKeys

DefByte Function Option Explicit Set

DefCur Get Option Private SetAttr

DefDate GoSub...Return Print# Static

DefDbl GoTo Private Stop

DefDec If...Then...Else Property Get Sub

Deflnt Implements Property Let Time

DefLng Input# Property Set Type

DefObj Kill Public Unload

DefSng Let Put Unlock

Defstr Line Input# RaiseEvent While... Wend

Def Var Load Randomize Width#

DeleteSetting Lock ReDim With

Dim LSet Rem Write#

Przyjęta zostało w tej pracy zasada, że opcjonalne parametry są wskazywane za pomocą nawiasów kwadratowych. Na przykład, drugi parametr w poniższej procedurze jest opcjonalny:

Sub ZmianaFormatu (NazwaCzcionki [, RozmiarCzcionki])

Funkcja MsgBox

Używana już była funkcja MsgBox kilkakrotnie. Nadszedł czas na oficjalną prezentację. Funkcja : MsgBox służy do wyświetlania okna komunikatu z przyciskami, które użytkownik może kliknąć. Oto najczęściej używana składnia tej funkcji:

MsgBox (komunikat [ ,przyciski] [ ,tytuł])

Poza wyżej podanymi parametrami funkcja MsgBox posiada parametry opcjonalne związane z po­mocą kontekstową. Pełną informację na temat funkcji MsgBox można znaleźć w dokumentacji VBA. W podanym przykładzie komunikat jest parametrem typu String zawierającym tekst wyświetlany w oknie komunikatu. Warto zwrócić uwagę, że można stworzyć wielowierszowe komunikaty za pomocą stałej vbCrLf.

Parametr przyciski posiada typ Long i podaje sumę wartości określających różne właściwości okna komunikatów, w tym liczbę i typ wyświetlanych przycisków, styl użytej ikony, przycisk domyślny oraz modalność okna komunikatu. Systemowe okno modalne pozostaje na wierzchu wszystkich otwartych okien i jest gotowe do przyjmowania danych (posiada fokus). Okno modalne aplikacji zostaje na wierzchu okien danej aplikacji i jest gotowe do przyjmowania danych (posiada fokus). W tabeli 7.1 przedstawiono różne wartości przyjmowane przez parametr przyciski. Zostały one zdefiniowane w enumeracji VbMsgBoxStyle.

Tabela 7.1. Wartości przyjmowane przez parametr przyciski funkcji MsgBox.

Cel

Stała

Wartość

Opis

Typy przycisków

vbOKOnly

vbOKCancel

vbAbortRetryIgnore

vbYesNoCancel

vbYesNo

vbRetryCancel

0

1

2

3

4

5

Wyświetla tylko przycisk OK

Wyświetla przyciski OK i Anuluj

Wyświetla przyciski Przerwij, Ponów próbę i Zignoruj

Wyświetla przyciski Tak, Nie i Anuluj

Wyświetla przyciski Tak i Nie

Wyświetla przyciski Ponów próbę i Anuluj Ponów próbę i Zignoruj

Typy ikon

vbCritical

vbQuestion

vbExclamation

vbInformation

16

32

48

64

Wyświetla ikonę wiadomości krytycznej

Wyświetla ikonę przedstawiającą znak zapytania

Wyświetla ikonę wiadomości ostrzegawczej

Wyświetla ikonę wiadomości

Przycisk domyślny

vbDefaultButtonl

vbDefaultButton2

vbDefaultButton3

vbDefaultButton4

0

256

512

768

Domyślnym jest przycisk pierwszy

Domyślnym jest przycisk drugi

Domyślnym jest przycisk trzeci

Domyślnym jest przycisk czwarty

Modalność

vbApplicationModal

vbSystemModal

0

4096

Okno modalne aplikacji

Systemowe okno modalne

Na przykład następujący wiersz kodu:

MsgBox "Kontynuować?", vbQuestion + vbYesNo

wyświetla okno komunikatu zawierające ikonę przedstawiającą znak zapytania oraz dwa przyciski: Tak i Nie (Rysunek 7.1).

Parametr tytuł jest łańcuchem znaków wyświetlanym w pasku tytułowym okna komunikatu. Jeżeli pominąć ten argument, w pasku tytułowym pojawi się napis Microsoft Word (Rysunek 7.1).

0x01 graphic

Rysunek 7.1. Okno komunikatu utworzone za pomocą funkcji MsgBox.

Funkcja MsgBox zwraca liczbę wskazującą przycisk kliknięty przez użytkownika. Wartości - zde­finiowane w enumeracji VBMsgBoxResult - zwracane przez funkcję MsgBox przedstawia tabela 7.2.

Tabela 7.2. Wartości zwracane przez funkcję MsgBox

Stała

Wartość

Opis

vbOK

1

Naciśnięto przycisk OK

vbCancel

2

Naciśnięto przycisk Anuluj

vbAbort

3

Naciśnięto przycisk Przerwij

vbRetry

4

Naciśnięto przycisk Ponów próbę

vbIgnore

5

Naciśnięto przycisk Zignoruj

vbYes

6

Naciśnięto przycisk Tak

vbNo

7

Naciśnięto przycisk Nie

Funkcja InputBox

Funkcja InputBox umożliwia użytkownikowi wprowadzanie danych. Oto często używana (chociaż niepełna) składnia tej funkcji:

InputBOx (komunikat, [, tytuł] [, WartośćDomyślna])

W powyższym przykładzie komunikat jest tekstem wyświetlanym w okienku dialogowym, tytuł - ­tekstem wyświetlanym w jego pasku tytułowym, WartośćDomyślna - tekstem wyświetlanym w po­lu tekstowym. Na przykład wiersz kodu:

sNazwisko = InputBox("Wpisz nazwisko", "Nazwisko", "Malinowski")

wyświetli okno dialogowe przedstawione na rysunku 7.2.

0x01 graphic

Rysunek 7.2. Okno dialogowe wygenerowane za pomocą funkcji InputBox.

Funkcja InputBox zwraca łańcuch znaków wpisany w polu tekstowym przez użytkownika. A zatem w przykładzie łańcuch znaków będzie przechowywany w zmiennej sNazwisko.

Należy zwrócić uwagę, że funkcja InputBox umożliwia użytkownikowi wpisywanie liczb. W takim przypadku zwrócony przez funkcję łańcuch znaków (taki jak „12,55'') należy przekonwertować do postaci liczby (12,55) za pomocą funkcji Val, opisanej w dalszej części tego rozdziału.

Funkcje umożliwiające operacje na łańcuchach znaków

Oto garść użytecznych funkcji umożliwiających wykonywanie operacji na łańcuchach znaków (za­równo stałych, jak i zmiennych):

Funkcja Len

Funkcja Len zwraca długość łańcucha znaków, czyli liczbę znaków w łańcuchu. Wiersz kodu:

Len("Styczeń")

zwraca liczbę 7.

Funkcje UCase i LCase

Funkcje te konwertują łańcuch znaków odpowiednio na duże i małe litery. Składnia tych funk­cji wygląda tak:

UCase(ŁańcuchZnaków)

LCase(ŁańcuchZnaków)

Na przykład wiersz kodu:

MsgBox UCase("Malinowski")

wyświetli łańcuch znaków „MALINOWSKI"

Funkcje Left, Right i Mid

Funkcje te zwracają fragment łańcucha znaków, a mianowicie funkcja:

Left(ŁańcuchZnaków, x)

zwraca x znaków z lewej strony łańcucha znaków, natomiast funkcja:

Right(ŁańcuchZnaków, x)

zwraca x znaków z prawej strony łańcucha znaków. Na przykład:

MsgBox Right("Alicja Kwiatkowska", 11)

wyświetla łańcuch znaków „Kwiatkowska". Funkcja Mid ma następującą składnię:

Mid(ŁańcuchZnaków, Początek, x)

Funkcja ta zwraca x znaków łańcucha znaków ŁańcuchZnaków, zaczynając od znaku podane­go w parametrze Początek. Na przykład wiersz kodu:

Mid("Biblioteka.doc", 12, 3)

zwraca łańcuch „doc". Jeżeli nie podano wartości dla parametru x:

Mid("Biblioteka.doc", 12)

funkcja zwraca resztę łańcucha znaków rozpoczynając od znaku określonego w parametrze Początek.

Funkcja InStr

Oto składnia tej niezwykle pożytecznej funkcji:

InStr(Początek, ŁańcuchPrzeszukiwany, ŁańcuchDoZnalezienia)

Funkcja InStr zwraca liczbę określającą pozycję początku łańcucha ŁańcuchDoZnalezienia w łańcuchu ŁańcuchPrzeszukiwany. Przeszukiwanie rozpoczyna się od pozycji określonej w parametrze Początek. Jeżeli nie podano wartości tego parametru, funkcja rozpoczyna prze­szukiwanie na początku łańcucha ŁańcuchPrzeszukiwany. Na przykład wiersz kodu:

MsgBox InStr(1, "Alicja Kwiatkowska", "Kwiatkowska")

wyświetla 8, ponieważ łańcuch znaków „Kwiatkowska" rozpoczyna się na ósmej pozycji w łańcuchu „Alicja Kwiatkowska".

Funkcje Str i Val

Funkcja Str konwertuje liczbę na łańcuch znaków. Na przykład kod:

Str(123)

zwraca łańcuch znaków „123". Funkcja Val konwertuje łańcuch znaków reprezentujący liczbę na liczbę, dzięki czemu można wykonywać na nim działania arytmetyczne. Na przykład, wiersz kodu:

Val("4.5")

zwraca liczbę 4,5, natomiast kod:

Val("1234 Ulica Szeroka")

zwraca liczbę 1234. Warto podkreślić, że funkcja Val nie rozpoznaje znaków dolara ($) i prze­cinka (,). A zatem wiersz kodu:

val("$12,00") zwraca 0, nie 12,00

Funkcje Trim, LTrim i RTrim

Funkcja LTrim usuwa wiodące spacje z łańcucha znaków. Funkcja RTrim usuwa spacje wy­stępujące po łańcuchu znaków. Funkcja Trim usuwa zarówno spacje wiodące, jak i występu­jące po łańcuchu znaków.

Oznacza to, że wiersz kodu:

Trim(" dodatkowe ")

zwraca łańcuch znaków „dodatkowe ".

Funkcje String i Space

Funkcja String umożliwia utworzenie łańcucha znaków składającego się z jednego znaku po­wtórzonego wielokrotnie. Na przykład wiersz kodu:

sTekst = String(25, "A")

przypisuje zmiennej sTekst łańcuch znaków składający się z 25 znaków „A". Funkcja Space zwraca łańcuch znaków składający się z danej liczby spacji. Na przykład kod:

sTekst = Space(25)

przypisuje zmiennej sTekst łańcuch znaków składający się z 25 znaków spacji.

Operator Like i funkcja StrComp

Operator Like służy do porównywania dwóch łańcuchów znaków. Można oczywiście użyć znaku równości:

ŁańcuchZnakówl = ŁańcuchZnaków2

Powyższe wyrażenie jest prawdziwe, jeżeli dwa łańcuchy znaków są identyczne. Jednak opera­tor Like umożliwia porównywanie uwzględniające duże i małe litery oraz sprawdzanie zgodno­ści łańcucha znaków ze wzorem.

Wyrażenie:

ŁańcuchZnaków Like Wzór

zwraca wartość True, jeżeli łańcuch znaków ŁańcuchZnaków jest zgodny ze wzorem, nato­miast False - jeżeli nie jest. Właściwie wyrażenie może zwrócić Null, ale nie będzie się oma­wiać tego zagadnienia, ponieważ częściej występuje ono w aplikacji Access niż Word. Co to jest wzór (pattern), wyjaśnione zostanie za chwilę.

Typ porównywania łańcuchów znaków stosowany przez operator Like zależy od ustawienia instrukcji Option Compare. Są dwie możliwości:

Option Compare Binary

Option Compare Text

Jedną z powyższych instrukcji należy umieścić w sekcji deklaracji modułu kodu (tuż pod in­strukcją Option Explicit). Należy zwrócić uwagę, że domyślną opcją jest Option Compare Binary. Kiedy stosuje się Option Compare Binary, porównywanie łańcuchów znaków odbywa się w porządku określonym przez kody znaków ANSI:

A<B<...<Z<a<b<...<z<Ą<...<Ó<ą<...<ó

Kiedy stosuje się Option Compare Text, porównywanie łańcuchów znaków nie jest wrażliwe na duże i małe litery i zależy od lokalnych ustawień systemu. Oznacza to, że znaki są sorto­wane w następującym porządku:

A=a<Ą=ą<B=b<...<Z=z<Ó=ó

Nawiasem mówiąc, ostatnim znakiem jest znak [ posiadający wartość ANSI 91. Oznacza to, że jeżeli chce się umieścić jakiś element jako ostatni w porządku alfabetycznym, należy umieścić go w nawiasach kwadratowych.

Używając operatora Like do sprawdzenia zgodności łańcucha znaków ze wzorem, można stosować symbole wieloznaczne, takie jak:

? zastępuje dowolny znak

* zastępuje zero lub więcej znaków # zastępuje dowolną cyfrę (0 - 9)

/charlist/ zastępuje pojedynczy znak w charlist

/charlist/ zastępuje pojedynczy znak nie znajdujący się w charlist

Więcej szczegółów można znaleźć w dokumentacji VBA.

Funkcja StrComp również porównuje dwa łańcuchy znaków. Oto jej składnia:

StrComp(ŁańcuchZnakówl, ŁańcuchZnaków2 [, compare])

Funkcja ta zwraca wartość wskazującą, czy ŁańcuchZnaków1 jest równy, większy lub mniej­szy niż ŁańcuchZnaków2. Dokumentacja VBA zawiera więcej szczegółów na temat tego za­gadnienia.

Różne funkcje i instrukcje

Funkcja Immediate If

Funkcja Immediate If ma następującą składnię;

IIf(Wyrażenie, CzęśćPrawdziwa, CzęśćFałszywa)

Funkcja ta zwraca jedną z dwóch części: jeżeli Wyrażenie ma wartość True, funkcja zwraca część CzęśćPrawdziwa; jeżeli Wyrażenie ma wartość False, funkcja zwraca część CzęśćFał­szywa. Na przykład następujący kod wyświetla okno komunikatu informujące, czy pierwszy akapit w aktywnym dokumencie jest zbyt długi, tj. czy zawiera ponad 100 słów:

Dim cSłowa As Long

cSłowa = ActiveDocument.Paragraphs(1).Range.Words.Count MsgBox "Pierwszy akapit jest " & _

IIf(cSłowa > 100, "za długi", "w sam raz")

Należy pamiętać, że funkcja Ilf zawsze ocenia obie części, ale zwraca tylko jedną z nich. Mu­si się, zatem być przygotowani na niepożądane efekty uboczne. Na przykład, poniższy kod wywoła błąd dzielenia przez zero, ponieważ wyrażenie 1/x jest oceniane we wszystkich przy­padkach, nawet gdy x = 0

x = 0

y = IIf (x = 0, x ^ 2, 1 / x)

Funkcja Switch

Oto składnia funkcji Switch:

Switch(wyrażl, wartośćl, wyraż2, wartość2,..., wyrażN, wartośćN)

gdzie wyrażX i wartośćX to wyrażenia. Wystarczy jedna para wyrażenie-wartość, ale stoso­wanie tej funkcji ma większy sens, jeżeli są przynajmniej dwie takie pary.

Funkcja Switch ocenia każde wyrażenie wyrażX. Kiedy napotyka pierwsze wyrażenie przyj­mujące wartość True, zwraca odpowiadającą jej wartość. Podobnie jak funkcja Ilf, funkcja Switch zawsze ocenia wszystkie wyrażenia. Jeżeli żadne wyrażenie nie jest prawdziwe, funkcja zwraca Null. Aby sprawdzić, czy funkcja Switch zwraca Null, można skorzystać z funkcji IsNull.

Na przykład, procedura przedstawiona w wydruku 7.1 wyświetla typ dokumentu Worda (doku­ment czy szablon) w zależności od jego rozszerzenia.

Wydruk 7.1. Funkcja Switch.

Sub WyświetlTypDokumentu(RozszerzenieDokumentu As String) Dim TypDokumentu As Variam

TypDokumentu = Switch(RozszerzenieDokumentu = "dot", "Szablon", _

RozszerzenieDokumentu = "doc", "Dokument")

'Wyświetl rezultat

If Not IsNull(TypDokumentu) Then

MsgBox TypDokumentu

Else

MsgBox "Typ nieznany" End If

End Sub

Warto zwrócić uwagę na jedną rzecz w powyższym kodzie. Ponieważ funkcja Switch może zwrócić wartość Null, nie można przypisać zwracanej wartości do zmiennej typu String w następujący sposób:

Dim TypDokumentu As String

TypDokumentu = Switch(RozszerzenieDokumentu = "dot", "Szablon", _

RozszerzenieDokumentu = "doc", "Dokument")

Jeżeli RozszerzenieDokumentu przyjmie wartość inną niż dot lub doc, pojawi się komunikat o błędzie „Invalid use of Null” (niepoprawne użycie Null). Rozwiązaniem tego problemu jest zadeklarowanie zmiennej TypDokumentu jako typ Variant. Typ Variant może przechowywać każdy rodzaj danych, w tym również brak danych, co wskazuje słowo kluczowe Null. Można uniknąć całego tego problemu stosując instrukcję Select Case, która zostanie omówiona w następnym rozdziale.

Konwersja jednostek

Funkcja InchesToPoints konwertuje miarę podaną w calach na miarę podaną w punktach (punkt to jednostka drukarki; każdy cal to 72 punkty). Funkcja ta jest ważna, ponieważ wiele wartości Worda jest podawanych w punktach.

Na przykład właściwość LeftIndent służy do ustawiania wartości lewego wcięcia akapitu i wy­maga wartości w punktach. Zatem aby ustawić lewe wcięcie pierwszego akapitu w aktywnym dokumencie Worda na 0,25 cala, należałoby napisać:

ActiveDocument.Paragraphs(1).LeftIndent = InchesToPoints(0.25)

Funkcja PointsTolnches natomiast służy do wyświetlania w calach wartości zwracanej przez funkcję w punktach.

Oprócz wyżej wymienionych, Word posiada następujące funkcje konwersji jednostek:

CentimetersToPoints i PointsToCentimeters

MillimetersToPoints i PointsToMillimeters

LinesToPoints i PointsToLines (1 linia = 12 punktów = 1/6 cala)

PicasToPoints i PointsToPicas (1 pica = 12 points = 1/6 cala)

Instrukcja Beep

Instrukcja Beep o prostej składni

Beep

generuje dźwięk za pomocą głośników komputera. Można użyć tej instrukcji, aby zwrócić uwagę użytkownika na coś ważnego. Nie należy jednak przesadzać ze stosowaniem instrukcji Beep. Jej efekt w głównej mierze zależy od sprzętu użytkownika i może się tak zdarzyć, że Beep nie wywoła żadnego dźwięku. Lepszym rozwiązaniem, nie kolidującym z wykonywa­niem programu, jest wyświetlanie informacji w pasku stanu Worda.

Instrukcje kontrolujące przepływ programu

Omawianie VBA zostanie zakończone prezentacją instrukcji kontrolujących przepływ programu.

Instrukcja If ... Then

Instrukcja If...Then warunkowo wykonuje blok kodu. Oto jej składnia:

If Warunek Then

'blok instrukcji

ElseIf InnyWarunek Then

'blok instrukcji

Else

'blok instrukcji

End If

Należy zwrócić uwagę, że można użyć więcej części ElseIf i że zarówno części ElseIf, jak i Else są opcjonalne. Można również zmieścić wszystkie części tej instrukcji w jednym wierszu, ale z prak­tycznego punktu widzenia jest to możliwe tylko w przypadku braku części ElseIf i Else.

Za przykład niech posłuży poniższy kod, który usuwa bieżące zaznaczenie w aktywnym dokumen­cie jeżeli zawiera ono wyraz „Bartok"

Dim sTekst As String

sTekst = Selection.Text

If InStr(sTekst, "Bartok") Then Selection.Delete

Poniższy kod zmienia rozmiar czcionki zaznaczonego tekstu w zależności od jego stylu. Jeżeli styl jest różny od Nagłówek 1, Nagłówek 2 lub Nagłówek 3, rozmiar czcionki zostaje zmieniony na 11 punktów:

If Selection.Style = "Nagłówek 1" Then

Selection.Font.Size = 24

E1seIf Selection.Style = "Nagłówek 2" Then Selection.Font.Size = 18

E1seIf Selection.Style = "Nagłówek 3" Then Selection.Font.Size = 19

Else

Selection.Font.Size = 11

End If

Pętla For

Instrukcja For...Next umożliwia wielokrotne wykonanie bloku kodu (tj. jednego lub więcej wierszy kodu). Pętla ta jest nazywana po prostu pętlą For. Oto jej podstawowa składnia:

For licznik = start To koniec

'blok kodu

Next licznik

Kiedy blok kodu jest wykonywany po raz pierwszy, zmienna licznik (nazywana zmienną pętli) otrzymuje wartość start. Każde wykonanie pętli powoduje zwiększenie wartości zmiennej licznik o 1. Kiedy wartość zmiennej licznik jest większa od wartości koniec, wykonywanie pętli zostaje przer­wane. Zatem pętla jest wykonywana koniec - start +l razy, za każdym razem z inną wartością zmiennej licznik.

Można opuścić słowo licznik w ostatnim wierszu pętli For (zastępując Next licznik wierszem Next). Dzięki temu wykonanie pętli może być szybsze, ale kod staje się mniej czytelny.

Poniższy kod przechodzi przez kolekcję wszystkich akapitów w aktywnym dokumencie Worda. Jeżeli akapit posiada styl Nagłówek 1, styl zostaje zmieniony na Nagłówek 2:

Dim i As Integer

Dim akapit As Paragraph

For i = 1 To ActiveDocument.Paragraphs.Count

'Weź następny akapit

Set akapit = ActiveDocument.Paragraphs(i)

'Zmień styl z Nagłówek 1 na Nagłówek 2

If akapit.Style = "Nagłówek 1" Then

akapit.Style = "Nagłówek 2" End If

Next i

Pętle For często są używane do inicjalizowania tablic. Poniższy kod:

For i = 0 To 10

iTablica(i) = 0

Next i

przypisuje wartość 0 każdemu z 11 elementów tablicy iTablica.

ExitFor

Instrukcja Exit For umożliwia wyjście z pętli, kiedy zostanie spełniony jakiś warunek. Na przy­kład, poniższy kod wyszukuje w aktywnym dokumencie pierwszy akapit, którego pierwszym wyra­zem jest wyraz „Dziękuję". Po znalezieniu tego wyrazu, VBA opuszcza pętlę For, a akapit zostaje pogrubiony:

Dim i As Integer

Dim akapit As Paragraph

For i = 1 To ActiveDocument.Paragraphs.Count

'Weź następny akapit

Set akapit = ActiveDocument.Paragraphs(i)

'Jeżeli pierwszy wyraz to "Dziękuję",

'wyjdź z pętli For

If Trim(akapit.Range.Words(1)) _ "Dziękuję" Then Exit For

Next i

akapit.Range.Bold = True

Należy zwrócić uwagę na użycie funkcji Trim, ponieważ dla Worda wyraz zawiera również spacje, które występują po nim.

Pętla For Each

Pętla For Each, odmiana pętli For, służy do przechodzenia przez obiekty kolekcji (jak również elementy tablicy) i jest zwykle wydajniejsza niż tradycyjna pętla For. Jej podstawowa składnia to:

For Each ZmiennaObiektowa In NazwaKolekcji

'blok kodu

Next Zmienna0biektowa

W powyższym przykładzie ZmiennaObiektowa to zmienna tego samego typu, co obiekty kolekcji. Blok kodu zostanie wykonany dla każdego obiektu w kolekcji.

Oto jak wygląda kod zmieniający styl Nagłówek I na Nagłówek 2 z zastosowaniem z pętli For Each:

Dim akapit As Paragraph

For Each akapit In ActiveDocument.Paragraphs

'Zmień styl z Nagłówek 1 na Nagłówek 2

If akapit.Style = "Nagłówek 1" Then

akapit.Style = "Nagłówek 2"

End If

Next akapit

Jak można zauważyć, kod jest znacznie bardziej zwięzły.

Zatem w przypadku przechodzenia przez kolekcję obiektów są dwa rozwiązania:

For Each obiekt In Kolekcja

'blok kodu

Next obiekt

lub

For i = 1 To Kolekcja.Count

'blok kodu

Next i

Należy jednak podkreślić, że pętla For Each może być znacznie szybsza niż pętla For w przecho­dzeniu przez obiekty kolekcji Worda. Jest to więc preferowany sposób, z wyjątkiem małych kolek­cji.

Instrukcji For Each można również używać do przejścia przez kolekcje elementów, które nie są obiektami. Na przykład, kolekcja FontNames zawiera nazwy wszystkich dostępnych czcionek. Jest to więc kolekcja łańcuchów znaków. Aby przejść przez tę kolekcję, należy napisać:

Dim NazwaCzcionki As Variam

For Each NazwaCzcionki In Application.FontNames

'blok kodu

Next NazwaCzcionki

Trzeba zwrócić uwagę, że zmienna NazwaCzcionki musi być zadeklarowana jako Variam, ponie­waż zmienną pętli For Each może być tylko zmienna obiektowa lub zamienna typu Variam. Zmienna typu String byłaby najwydajniejsza, ale VBA nie pozwala na jej użycie w tym kontekście.

Pętla Do

Pętla Do posiada kilka odmian. Aby je opisać, używaj notacji:

{While I Until}

która reprezentuje albo słowo kluczowe While, albo słowo kluczowe Until, ale nie oba jednocześnie. Oto przykładowa składnia pętli Do:

Do {While I Until} warunek

'blok kodu

Loop

lub

Do

'blok kodu

Loop {While I Until} warunek

Można się też pozbyć części warunek:

Do

'blok kodu

Loop

Różnice między niektórymi odmianami pętli Do mogą być bardzo subtelne. Na przykład poniższy kod przechodzi przez akapity aktywnego dokumentu, dopóki akapity zawierają jakieś znaki (poza znakiem końca akapitu):

'Weź pierwszy akapit

Set akapit = ActiveDocument.Paragraphs(1)

Do While akapit.Range.Characters.Count

'Blok kodu

'Weź następny akapit

Loop

Rozważając następujący kod, którego cel jest podobny:

'Weź pierwszy akapit

Set akapit = ActiveDocument.Paragraphs(1)

Do

'Blok kodu

'Weź następny akapit

Loop While akapit.Range.Characters.Count > 1

Różnica między tymi dwoma odmianami polega na tym, że w pierwszym przypadku warunek jest sprawdzany zanim jakikolwiek kod pętli Do zostanie wykonany. Jeżeli pierwszy akapit nie zawiera żadnego tekstu (tj. zawiera tylko znak końca akapitu), liczba znaków w tym akapicie będzie wyno­sić 1 i warunek nie zostanie spełniony. A zatem żaden kod pętli Do nie zostanie wykonany.

W drugim przypadku warunek jest sprawdzany po każdym przejściu pętli, więc pętla zostanie wykonana co najmniej raz, nawet jeżeli akapit nie zawiera żadnego tekstu.

W poniższym przykładzie pętla Do została użyta, aby sformatować kursywą każdy wyraz akapitu aż do momentu dojścia do wyrazu pogrubionego (zadanie to można wykonać również za pomocą pętli For):

Dim akapit As Paragraph Dim fragment As Range

Dim iWyraz As Long

Dim iLicznikWyrazów As Long

'Inicjalizuj

iWyraz = 1

'Weź pierwszy akapit

Set akapit = ActiveDocument.Paragraphs(1)

'Oblicz liczbę wyrazów w akapicie

iLicznikWyrazów = akapit.Range.Words.Count

'Wykonuj pętlę, dopóki są wyrazy

Do While iWyraz <= iLicznikWyrazów

'Weź wyraz

Set fragment = akapit.Range.Words(iWyraz)

'Wyjdź z pętli, jeżeli wyraz jest pogrubiony

If fragment.Bold = True Then Exit Do

'Sformatuj wyraz kursywą

fragment.Italic = True

'Następny wyraz

iWyraz = iWyraz + 1

Loop

Należy zwrócić uwagę na instrukcję Exit Do, która jest analogiczna do instrukcji Exit For.

Pętle nieskończone

Powinno się zachować ostrożność kodując pętle Do, ponieważ źle napisana pętla Do może wyko­nywać się bez końca. Pętlę nieskończoną może spowodować użycie niewłaściwego warunku, który ma pętlę zakończyć.

Pętla nieskończona może powstać również w pętli For, ale zdarza się to znacznie rzadziej, ponie­waż wymagałoby to zmiany licznika pętli. Natomiast stosunkowo łatwo popełnić błąd w pętli Do i wywołać w ten sposób pętlę nieskończoną.

Oto prosty przykład. Załóżmy, że każdy akapit w aktywnym dokumencie powinien mieć nagłówek wskazujący numer tego akapitu. Oznacza to, że poniższy dokument zawierający cztery wiersze:

Pierwszy wiersz dokumentu.

Drugi wiersz dokumentu.

Trzeci wiersz dokumentu.

Czwarty wiersz dokumentu.

powinien zostać przekształcony do postaci następującej:

Akapit 1:

Pierwszy wiersz dokumentu.

Akapit 2:

Drugi wiersz dokumentu.

Akapit 3:

Trzeci wiersz dokumentu.

Akapit 4:

Czwarty wiersz dokumentu.

Rozważmy poniższy kod, który ma wykonać to zadanie. Spróbujmy znaleźć błąd, który sprawia, że kod nigdy nie przerwie swojego działania.

iAkapit = 1

'Wykonuj pętlę, dopóki są akapity

Do While iAkapit <= ActiveDocument.Paragraphs.Count

'Weź n-ty akapit

Set akapit = ActiveDocument.Paragraphs(iAkapit)

'Dodaj nagłówek z numerem akapitu akapit.Range.InsertBefore "Akapit" _

& Format(iAkapit) & ":" & vbCrLf

'Następny akapit

iAkapit = iAkapit + 1

Loop

Problem polega na tym, że dodanie nagłówka powoduje dodanie nowego akapitu do dokumentu, co zwiększa wartość ActiveDocument.Paragraphs.Count, więc warunek:

iAkapit <= ActiveDocument.Paragraphs.Count

jest zawsze prawdziwy, ponieważ wartość lewej strony wzrasta wraz z prawą stroną.

Powyższy przykład ilustruje, jak niebezpieczne jest umieszczanie wartości podlegającej zmianie w części warunek pętli Do (i jakiejkolwiek innej pętli). Patrząc jeszcze raz na poprzedni przy­kład, który formatuje kursywą każdy wyraz do momentu dojścia do wyrazu pogrubionego. Można zauważyć następujący kod:

'Oblicz liczbę wyrazów w akapicie

iLicznikWyrazów = akapit.Range.Words.Count

'Wykonuj pętlę, dopóki są wyrazy

Do While iWyraz <= iLicznikWyrazów

Pierwszy wiersz oblicza liczbę wyrazów i umieszcza ją w zmiennej. Zmienna ta, której wartość kontroluje programista a nie VBA, nie zmienia się (ponieważ on jej nie zmienia), dzięki czemu może być bezpiecznie użyta w części warunek pętli Do.

Instrukcja Select Case

Instrukcja If...Then służy do wykonywania różnych zadań w zależności od różnych warunków. Alternatywną instrukcją, często znacznie czytelniejszą, jest Select Case o następującej składni:

Select Case wyrażenie

Case wartośćl

'blok instrukcji wykonywany, jeżeli wyrażenie = wartośćl

Case wartość2

'blok instrukcji wykonywany, jeżeli wyrażenie = wartość2

...

Case Else

'blok instrukcji wykonywany w innym przypadku

End Select

Należy zwrócić uwagę, że część Case Else jest opcjonalna. Jako ilustrację można rozważyć poniższy kod, który jest wersją wcześniejszego przykładu zmieniającego rozmiar czcionki różnych nagłówków, tym razem z zastosowaniem instrukcji Select Case. Jak widać, w tej wersji kod jest czytelniejszy niż w wersji poprzedniej:

Select Case Selection.Style

Case "Nagłówek 1"

Selection.Font.Size = 24

Case " Nagłówek 2"

Selection.Font.Size = 18

Case " Nagłówek 3"

Selection.Font.Size = 14

Case Else

Selection.Font.Size = 11

End Select

Ostatnie uwagi o VBA

Długo jeszcze można by omawiać VBA - podręcznik do VBA zawiera około 300 stron. Jednak odstawowe zagadnienia potrzebne do rozpoczęcia programowania w Wordzie zostały już wyja­śnione.

Na dobrą sprawę, wykonanie wielu programistycznych zadań w Wordzie wymaga poznania jedy­nie wybranych funkcji VBA. Prawdopodobnie więcej problemów sprawia model obiektowy Worda niż język VBA.

Funkcje związane z plikami i folderami

VBA posiada wiele funkcji umożliwiających operacje na plikach i folderach. Niektóre z nich to:

Dir - wyszukuje plik o podanej nazwie.

FileLen - odczytuje rozmiar pliku.

FileTimeDate - odczytuje datę pliku.

FileCopy - kopiuje plik.

Kill - usuwa plik.

Name - zmienia nazwę pliku lub folderu.

RmDir - usuwa folder.

MkDir - tworzy nowy folder.

VBA posiada również funkcje i instrukcje służące do tworzenia plików tekstowych, w których można zapisywać dane. Oto uproszczona składnia instrukcji Open:

Open ScieżkaPliku For Tryb As [#]NumerPliku

Kiedy plik jest otwarty, można z niego odczytać dane jak również je w nim zapisać. Warto podkre­ślić, że instrukcja Open otwiera i tworzy pliki tekstowe, a nie dokumenty Worda.

Funkcje związane z datą i czasem

Oto niektóre funkcje VBA, dzięki którym można manipulować datami i czasem:

Date, Now, Time - odczytują bieżącą datę i czas.

DateAdd, DateDiff, DatePar t- obliczają daty.

DateSerial, DateValue - zwracają datę.

TimeSerial, TimeValue-zwracajączas.

Date, Time - zwracają datę lub czas.

Timer - mierzy trwanie procesu.

Funkcja Format

Funkcja Format służy do formatowania łańcuchów znaków, liczb i dat. Tabela 8.1 zawiera kilka przykładów zastosowania tej funkcji.

Tabela 8.1. Przykłady zastosowania funkcji Format.

Wyrażenie

Zwracana wartość

Format(Date, "Long Date")

czwartek, kwiecień 29, 2000

Format(Time, "Long Time")

15:24:45

Format(Date, "mm/dd/yy hh:mm:ss")

04/29/00 15:25:56

Format(1234,5 "$##,##0.00")

$1 234,50

Format("WITAJCIE", "<")

witajcie

Błędy

Programista piszący programy profesjonalne powinien koniecznie zapoznać się z technikami sto­sowanymi w obsłudze błędów. Można zaproponować książkę Concepts of Object-Oriented Programming in Visual Basic wydawnictwa Springer-Verlag, która zawiera rozdział poświęcony temu zagadnieniu. Jeżeli jednak pisze się programy na własny użytek, kod obsługujący błędy nie ma tak wielkiego znaczenia. Kiedy wystąpi błąd, VBA zatrzyma wykonywanie programu, wyświetli komunikat o błędzie i wyróżni wiersz, który wywołał błąd. Wtedy można przystąpić do usuwania błędu. Nie można jednak oczekiwać, że użytkownicy programów napisanych przez programistę będą usuwać błędy z jego kodu.

BHP

WSTĘP

Rewolucja informatyczna sprawiła, że miliony ludzi z hal fabrycznych przenoszą się przed monitory komputerowe. Nie grozi im już śmierć w trybach maszyny, ale pojawiają się inne zagrożenia dla zdrowia. Tym większe, że mało kto zdaje sobie z nich sprawę.
Najbardziej znany jest problem uciążliwości wpływu monitora na oczy (patrz: CHIP 4/99, s. 40). Problemy ze wzrokiem to najpowszechniejsza dolegliwość, dokuczająca jednak nie tylko miłośnikom pecetów. "Wśród osób pracujących przy komputerach dominują schorzenia oczu, głównie przewlekłe zapalenia spojówek. Jednak na tę dolegliwość cierpi większość naszego społeczeństwa - czy pracuje przy komputerze, czy nie" - wyjaśnia dr Anna Wróblewska, specjalista medycyny pracy. W ostatnich latach sytuacja użytkowników komputerów pod tym względem uległa olbrzymiej poprawie.
Praktycznie wszystkie współczesne monitory spełniają surowe międzynarodowe standardy, określające dopuszczalne promieniowanie elektromagnetyczne i gamma oraz minimalną częstotliwość poziomego odświeżania obrazu. Użytkownik Windows musi jedynie sprawdzić, czy system poprawnie rozpoznał model monitora i optymalnie ustawił istotne parametry pracy. Warto tu przypomnieć, że zgodnie z najnowszą szwedzką normą TCO 99 zalecane, uznane za nie psujące wzroku odświeżanie obrazu wynosi 85 herców (patrz:
CHIP 3/99, s. 73). Zdaniem prof. Marii Konarskiej, szefowej Zakładu Ergonomii

0x08 graphic

Centralnego Instytutu Ochrony Pracy, wysokie standardy bezpieczeństwa, spełniane przez niemal wszystkie obecne na rynku modele monitorów, sprawiają, że stosowanie dodatkowych filtrów staje się niepotrzebne. Filtry mogą być wręcz szkodliwe! "Monitory powinny spełniać normy bezpieczeństwa, które czynią filtry zbędnymi. Na nałożonym filtrze osadza się kurz, co pogarsza ostrość oraz efektywną rozdzielczość obrazu i przyczynia się do szybszego zmęczenia wzroku" - tłumaczy dr Wróblewska.-";Najlepsze są filtry wbudowywane w ekran, bo są one hermetycznie zamknięte, co niweluje możliwość rozpraszania obrazu. Klasyczny filtr może jedynie poprawiać samopoczucie użytkownika, który ma wówczas wrażenie, że jest lepiej zabezpieczony". Wiele osób korzystających z dodatkowych filtrów pamięta o wycieraniu kurzu tylko z ich zewnętrznej części, zapominając o stronie wewnętrznej i szybie monitora.


Bez ekwilibrystyki przy pracy! Poprawne ustawienie dłoni i przedramion podczas pracy przy komputerze może uchronić przed przewlekłymi schorzeniami. W zachowaniu właściwej pozycji mogą pomóc klawiatury ergonomiczne.

Jak wynika z badań CIOP, nie ma sensu stosowanie modnych ostatnio okularów antyrefleksyjnych i antyradiacyjnych. Odblaskom należy zapobiegać właściwym ustawieniem stanowiska pracy. Promieniowanie nowych monitorów jest znikome, a w przypadku starszych urządzeń niezbędne są filtry. Wbrew obiegowym opiniom zakład pracy nie ma obowiązku refundacji takich okularów - rozporządzenie Ministra Pracy nakłada natomiast na pracodawcę obowiązek zwrotu części kosztów okularów korekcyjnych.

PIERWSZA OFIARA RSI

Choć zagrożenie dla wzroku jest mniejsze niż kilka lat temu, nie znaczy to jednak, że komputer stał się narzędziem bezpiecznym. Dopiero teraz zaczynają się ujawniać długotrwałe negatywne skutki wieloletniej pracy przy klawiaturze. Ofiarą takiej bomby z opóźnionym zapłonem padł jeden ze współpracowników CHIP-a. Po kilku latach pracy przy komputerze zauważył, że rano drętwieją mu palce wskazujące. W ciągu następnych miesięcy cierpnięcie objęło całe dłonie, a wreszcie sięgnęło barków. Towarzyszyła temu pogarszająca się sprawność kończyn górnych: coraz mniejszy zakres ruchów palców i słabnąca siła chwytu. W końcu prowadzenie samochodu stało się niemożliwe, a do rangi problemu urosło nawet spożycie posiłku.
Dzięki przeprowadzonym w Internecie poszukiwaniom nasz współpracownik zaraz po wystąpieniu pierwszych objawów ustalił nazwę schorzenia. Nazywa się ono fachowo "zespół cieśni nadgarstka", znane też pod nazwą RSI (Repetitive Strain Injury) oraz Cumulative Trauma Disorder. Pojawia się, gdy dłonie przez wiele godzin są odgięte do góry - np. podczas szybkiego wprowadzania danych za pomocą klawiatur wymagających minimalnej siły nacisku, a więc pozwalających nie poruszać przedramionami. Także korzystanie z myszki bez oparcia nadgarstka na specjalnej podkładce może prowadzić do opisanych kłopotów zdrowotnych. Pojawia się wówczas postępujące podrażnienie głównego nerwu dłoni.
Jednak właściwe leczenie naszego współpracownika nie rozpoczęło się szybko. Kolejni lekarze-specjaliści nie wierzyli, że ich pacjenta dotknęło mało znane schorzenie. Następujące po sobie, wielotygodniowe sesje lasero- i krioterapii nie przynosiły poprawy. Gdy po dwóch latach, w 1997, roku przeprowadzono badania z użyciem elektromiografu, które wykazały, że po raz pierwszy w Polsce wystąpił wywołany pracą przy komputerze przypadek RSI, na wszelkie formy terapii było za późno. Jedynym ratunkiem był nóż chirurga.
Przypadek ten pokazuje, że ofiary schorzeń pojawiających się wraz z postępującymi zmianami cywilizacyjnymi i technologicznymi, nawet znając źródło problemów i zwracając się do specjalistów, mogą mieć trudności z uzyskaniem pomocy medycznej. Strach pomyśleć, co stałoby się, gdyby był on nieświadomym źródła swych kłopotów mieszkańcem prowincji, skazanym na pomoc gminnego ośrodka zdrowia.

UWAGA NA RĘCE

"Zespół cieśni nadgarstka był dotychczas w naszym kraju chorobą zawodową malarzy, pianistów i maszynistek" - tłumaczy prof. Konarska. Schorzenie to ujawnia się po ok. 10-12 latach codziennej wielogodzinnej pracy w warunkach niezgodnych z zasadami ergonomii. Ponieważ masowa komputeryzacja rozpoczęła się w naszym kraju po 1989 roku, można się spodziewać, że w najbliższych latach pojawiać się będzie coraz więcej ofiar RSI oraz innych schorzeń, których źródło leży w niezgodnej z zaleceniami specjalistów pracy z klawiaturą i myszą.
W początkowych stadiach schorzenia można mu zaradzić serią zabiegów fizjoterapii. Jeśli kolejne objawy zostaną zlekceważone lub - jak w opisanym przypadku - źle zdiagnozowane, niezbędne staje się chirurgiczne nacięcie tzw. wiązadła przedniego nadgarstka. Konsekwencją operacji jest kilkutygodniowe unieruchomienie ręki w gipsie oraz wielomiesięczna rekonwalescencja. Tymczasem aby uniknąć problemów, wystarczy dobrze przygotować stanowisko pracy oraz robić przerwy na prostą gimnastykę palców i nadgarstka. "Skuteczną profilaktyką jest przeciągnięcie się, strzepnięcie dłoni i krótki spacer, podczas którego odpoczywają napięte w czasie pracy mięśnie przedramion i dłoni" - mówi szefowa Zakładu Ergonomii CIOP. Co kilka minut warto zrobić krótką przerwę na rozluźnienie dłoni, ramion i barków, a co godzinę - dłuższą na bardziej kompleksową gimnastykę. Zalecane jest także uprawianie sportów ogólnorozwojowych, np. pływania. Może to stanowić skuteczną profilaktykę zapobiegającą nie tylko RSI, ale także innym "komputerowym" dolegliwościom. Niewskazany jest natomiast tenis ziemny czy stołowy.
Zespół cieśni nadgarstka to tylko jedno z wielu groźnych schorzeń rąk, które stanowią zagrożenie dla osób pracujących przy klawiaturze. Dzięki właściwej pozycji przy pracy i odpowiednio częstym przerwom na gimnastykę można jednak tych wszystkich chorób uniknąć.

NIE GARB SIĘ

Innym, rzadko wiązanym z pracą przy klawiaturze, schorzeniem są zmiany zwyrodnieniowe szyjnego odcinka kręgosłupa. "Większość osób zgłasza się z dolegliwościami oczu, ale to schorzenia kręgosłupa są głównym przeciwwskazaniem dla pracy przy komputerze, gdyż wykluczają wielogodzinne przebywanie w pozycji siedzącej" - wyjaśnia dr Wróblewska. Przestrzegając przepisów BHP, można uniknąć takich problemów. Wystarczy w czasie pracy co godzinę zrobić 10 minut przerwy lub co 2 godziny - 20 minut. Praca przy klawiaturze nie musi być jednak bezpośrednią przyczyną kłopotów z kręgosłupem. Mogą one mieć podłoże genetyczne lub zostać zapoczątkowane na wiele lat przed tym, nim człowiek pierwszy raz siądzie przed monitorem. Czynników wywołujących chorobę może być wiele - a komputer jedynie pogarsza stan zdrowia.

OŚWIETLENIE STANOWISKA PRACY

Codzienna, wielogodzinna praca przy komputerze może się przyczyniać do osłabienia, a nawet uszkodzenia wzroku. Zmuszanie mięśni oka do ciągłego wysiłku powoduje ich zmęczenie, a łzawienie, zaczerwienienie i pieczenie należy traktować jako sygnał ostrzegawczy. Winę za problemy ze wzrokiem w dużej mierze ponosi nieprawidłowe oświetlenie miejsca pracy.

Ekstremalnie nieprawidłowo ustawiony monitor: odbicia źródła światła (lampy i okna) powodują powstanie szkodliwego lśnienia. Wyraźnie widoczne odbicie użytkownika wymusza na oku ciągłą zmianę ostrości widzenia. Stojąca obok lampka wprawdzie oświetla biurko, ale także powoduje konieczność zwiększenia kontrastu, co negatywnie wpływa na komfort pracy.

0x08 graphic


Przy tworzeniu nowego stanowiska pracy z komputerem powszechną praktyką jest ustawianie urządzenia na biurku w miejscu, w którym jest akurat wolny kawałek powierzchni. Jeśli nawet wcześniej oświetlenie było prawidłowe, w żaden sposób nie uwzględniamy zmienionej specyfiki pracy. Z czasem nowa organizacja miejsca powszednieje i użytkownik przestaje zauważać wady takiego ustawienia. Jednak wszelkie nieprawidłowości stopniowo pogarszają stan narządu wzroku.
Sytuacja nie jest jednak beznadziejna. Najczęściej wystarczy dokonać niewielkich zmian na naszym stanowisku pracy, by osiągnąć dużą poprawę komfortu widzenia. Przeważnie nie wymaga to żadnych nakładów finansowych, a efekty będą natychmiastowe i długotrwałe. Najwygodniej jest poprosić o ocenę aktualnego stanowiska pracy firmę specjalizującą się w określaniu prawidłowości oświetlenia, ale zaskakująco dużą poprawę można uzyskać samodzielnie.

ERGONOMIA-LOKALIZACJA I OŚWIETLENIE STANOWISKA PRACY

By spełnić wymagania dotyczące prawidłowego oświetlenia stanowiska pracy, niezbędne jest dobre rozplanowanie jego usytuowania w pomieszczeniu. Na wybór pokoju nie mamy zwykle wpływu, jeśli jednak moglibyśmy wybierać, należy na gabinet zarezerwować pomieszczenie nie wyższe niż 3 metry, najlepiej z oknami od strony północnej. Okna te nie powinny być zbyt duże; dobrze, jeśli są tylko w jednej płaszczyźnie. Nie ma oczywiście mowy o przeszklonych ścianach.

Stanowisko komputerowe ustawiamy tak, by ekran znajdował się na tle ściany bezokiennej, bokiem do okna, ale w odległości nie mniejszej niż 1 metr. Przy samym oknie możemy ulokować stanowisko pracy nie wyposażone w komputer. W żadnym wypadku okno - zwłaszcza od strony innej niż północna - nie powinno znajdować się za plecami użytkownika. Monitor należy tak ustawić, by żaden fragment okna nie odbijał się od ekranu pod kątem większym niż 45° od osi wzroku. Jeśli nie da się tego osiągnąć, warto zadbać o odpowiedniej wielkości przegrodę zasłaniającą okno. Przegroda taka nie musi być wysoka, powinna tylko zasłaniać dostęp bezpośredniego światła z okna do ekranu.

DZIAŁANIE PRĄDU NA ORGANIZM LUDZKI

Prąd elektryczny przepływający przez ciało człowieka wywołuje w nim zmiany chemiczne i biologiczne groźne dla zdrowia i życia. Działanie prądu może się objawiać w postaci zmian elektrolitycznych , oparzeń oraz zaburzeń czynności fizjologicznych. Niebezpieczeństwo porażenia prądem elektrycznym zależy od jego wartości , czasu rażenie (przepływu prądu przez organizm) oraz częstotliwości. Najniebezpieczniejsze są prądy o częstotliwości sieciowej 50-60Hz, gdyż jest ona zbliżona do częstotliwości bioprądów w organizmie. Niebezpieczeństwo porażenia prądem elektrycznym jest mniejsze dla prądu stałego oraz zmniejsza się wraz ze zwiększeniem częstotliwości ponad 50-60 Hz.

Prąd przepływający przez ciało człowieka jest proporcjonalny do napięcia dotykowego

( napięcie między dwoma elementami przewodzącymi, które znajdują się w zasięgu ręki) i odwrotnie proporcjonalny do rezystancji ciała. Rezystancja ciała człowieka zmienia się w szerokim zakresie i jest zależna od: warunków środowiskowych; stanu naskórka; indywidualnych cech człowieka.

Przy prądzie przemiennym płynącym przez ciało człowieka powinno się uwzględniać nie tylko rezystancję, lecz również reaktancję, ale dla uproszczenia przy obliczeniach jej wartości jest pomijana. Wypadkowa rezystancja ciała człowieka składa się z rezystancji skóry i rezystancji wewnętrznej organizmu. Rezystancja wewnętrzna jest niewielka i wynosi od 500 do 1000 SZ. Rezystancja skóry natomiast zmienia się w szerokich granicach. Przy suchym naskórku wynosi od 5000 S2 do 100 000 S~2 i może zmniejszać się pod wpływem wilgotności, przedłużającego się czasu rażenia i wzrostu napięcia rażeniowego.

Na tej podstawie przyjęto, że minimalna niebezpieczna dla człowieka wartość prądu płynącego przez ciało wynosi : 30mA prądu przemiennego i 10mA prądu stałego. Korzystając z prawa Ohma i podstawiając do wzoru niebezpieczne wartości prądu płynącego przez ciało człowieka oraz rezystancję ciała w danych warunkach środowiskowych (przyjmując najniższą wartość) otrzymuje się maksymalne wartości napięć dopuszczalnych dla człowieka - napięci dotykowe bezpieczne. W warunkach środowiskowych, w których rezystancja ciała człowieka w stosunku do ziemi wynosi co najmniej 1000 SZ (pomieszczenie o wilgotności względnej nie przekraczającej 75% i podłożu nieprzewodzącym), za napięcie bezpieczne uznaje się napięci 50 V dla prądu przemiennego i 100V dla prądu stałego. Gdy rezystancja ciała jest mniejsza niż 1000 S~, napięcie bezpieczne wynosi 25 V dla prądu przemiennego i 50 V dla prądu stałego.

ŚRODKI OCHRONY PRZECIWPORAŻENIOWEJ

Ochrona przeciwporażeniowa w instalacjach i urządzeniach elektrycznych ma na celu niedopuszczenie do przepływu przez ciało człowieka prądu rażeniowego lub ograniczenie czasu przepływu prądu przez szybkie wyłączenie zasilania, aby zapobiec powstaniu groźnych dla zdrowia i życia skutków.

Ochronę przeciwporażeniową można podzielić na trzy grupy:

1. Ochronę przez stosowanie napięć bezpiecznych,

2. Ochranę przed dotykiem bezpośrednim do części czynnych obwodu elektrycznego

(ochrona podstawowa),

3. Ochronę przed dotykiem pośrednim do części przewodzących dostępnych, na których w wyniku uszkodzenia izolacji pojawiło się napięcie dotykowe o wartości mogącej spowodować w danych warunkach środowiskowych przepływ prądu rażeniowego (ochrona dodatkowa).

Zgodnie z przepisami w sprawie ochrony przeciw porażeniowej należy stosować w zależności od zagrożenia następujące środki:

1. Ochronę podstawową,

2. Ochronę dodatkową,

Ochrona podstawowa ma zapobiegać:

• Zetknięciu się człowieka z przewodzącymi elementami obwodów elektrycznych, znajdujących się pod napięciem;

• Udzielaniu się napięcia przedmiotom lub elementom przewodzącym, które normalnie nie powinny znajdować się pod napięciem;

• Szkodliwemu działaniu na otoczenie łuku elektrycznego, który mógłby wystąpić przy pracy urządzeń.

Ochrona podstawowa polega więc przede wszystkim na umieszczeniu elementów znajdujących się pod napięciem poza. zasięgiem ręki człowieka, a wiec stosowanie przegród, siatek lub poręczy z materiału izolacyjnego.

Ochrona dodatkowa ma zapobiegać utrzymywaniu się niebezpiecznego napięcia dotykowego. Polega ona na zastosowaniu, poza ochroną podstawową jednego z następujących środków:

• Uziemienia ochronnego;

• Zerowania;

• Sieci ochronnej;

Uziemienia ochronne stanowią najbardziej rozpowszechniony rodzaj ochrony dodatkowej, stosowane do maszyn i urządzeń elektrycznych. Celem stosowania uziemienia ochronnego jest zrównanie potencjału uziemionych przedmiotów z potencjałem ziemi.

Zerowanie może być stosowana w przystosowanych do tego sieciach trójfazowych o napięciu poniżej 300 V. Polega ono na połączeni dostępnych części metalowych urządzeń z uziemionym przewodem zerowym.

Sieć przewodów ochronnych wolno stosować w urządzeniach przemiennoprądowych i stałoprądowych niezależnie od napięcia. Wszystkie dostępne części metalowe nie znajdujące się pod napięciem, oraz dostępne metalowe konstrukcje wsporcze i osłony powinny być połączone z przewodem ochronnym .

0x08 graphic

Przykładowe rozmieszczenie stanowisk pracy: biurka z komputerami znajdują się w drugim i trzecim rzędzie daleko od okien, bokiem do nich. Oprawy oświetlenia ogólnego umieszczone są nad przejściami, a nie bezpośrednio nad stanowiskami. Dla niektórych miejsc pracy może być konieczne ustawienie niskich ścianek działowych, ograniczających odbicia. Oprawy oświetleniowe muszą być kierunkowe, by nie oślepiać osób pracujących w końcach sali.


Oświetlenie ogólne (oprawy i lampy sufitowe) nie powinno znajdować się bezpośrednio nad stanowiskiem pracy, lecz z boku. Jeśli pokój z kimś dzielimy, najlepiej je umieścić nad przejściem między biurkami. Nie jest specjalnie istotne, czy do oświetlenia wybierzemy świetlówki czy lampy żarowe (ciepłe), jeśli tylko nie występuje efekt migotania. Warto zauważyć, że światło świetlówek wymaga nieco większego natężenia oświetlenia niż światło żarowe. Na płaszczyźnie roboczej biurka natężenie oświetlenia powinno wynosić ok. 500 luksów.
Oprawy oświetlenia ogólnego powinny być tak dobrane, by nie świeciły bezpośrednio na ekran, lecz kierunkowo w stronę podłogi lub blatu biurka. W pomieszczeniu najjaśniejszy powinien być sufit, ściany nieco ciemniejsze, a podłoga wyraźnie ciemniejsza. W razie potrzeby należy tak doświetlić ścianę za ekranem, by uzyskać odpowiedni stosunek luminacji tła do luminacji ekranu. Należy jednak unikać stosowania nisko umieszczonych kinkietów ze względu na możliwość wystąpienia trudnego do wyeliminowania źródła olśnienia.
Choć lepiej jest lokalnie doświetlać zbyt ciemne obszary pracy, niż zwiększać poziom oświetlenia ogólnego, to powinniśmy zdawać sobie sprawę, że nasze dodatkowe lampki mogą spowodować przykre odbicia w monitorach współpracowników.
Na koniec warto chwilę uwagi poświęcić oknom: nie przesłonięte niczym są bardzo jaskrawe w dzień, a w nocy stanowią czarną płaszczyznę. Obie sytuacje są niekorzystne, dlatego w domu należy powiesić firanki, a w biurze, gdzie firanki z różnych względów nie są używane, powinny się znaleźć pionowe żaluzje, najlepiej wykonane z tkaniny. Żaluzje materiałowe przy ustawieniu prostopadłym do płaszczyzny okna nie przeszkadzają w swobodnym wyglądaniu na zewnątrz, a jednocześnie redukują szkodliwe odbicia.

Bibliografia:

  1. Word Makrodefinicje, Steven Roman.

  2. Visual Basic dla Aplikacji 5 w zastosowaniach, Paul Sanna i inni.

  3. CHIP i inne czasopisma poświęcone tematyce kopmuterowej.

62



Wyszukiwarka

Podobne podstrony:
praca word
WORD TI formatowanie tekstu moja praca
word praca z tekstem
Praca karty magnet, Nowy Dokument programu Microsoft Word
Hurtownia papierosow - baza w SQL + opis w Word, Praca
Praca ucz w kl 1, pliki do ćwiczeń, word, edytor tekstu
Zagadnienia do egzaminu z teoretycznych podstaw pracy socjalnej - Word 97, PRACA SOCJALNA, Pedagogik
INSTRUKCJA BHP - praca na WYSOKOCI, Instrukcje word
Praca sprawdzająca opanowanie możliwości?ytora WORD
Tabela ocen - Word - Praca domowa na 06.02.2008, Informatyka
Praca Domowa - Word - na 30.01.2008, Informatyka
praca lic WORD drama, naukowe, aps
Microsoft Word Praca Anna Brzytwa 1
Microsoft Word praca
praca z uczniem zdolnym i słabym 2
Praca psychoterapeutyczna z DDA wykład SWPS
PRACA NA 4 RECE (aga)(1)[1]
praca 4

więcej podobnych podstron