Zmienne pojawiły się już wcześniej w toku kursu. Podstawiałem pod zmienne różne wartości liczbowe lub wskazywały na różne obiekty Excela. Zmienna odpowiada miejscu w pamięci operacyjnej komputera i przechowuje pewną wartość, lub cały zestaw wartości. Każda zmienna jest identyfikowana przez swoją nazwę.
W zakresie widoczności zmiennej (o czym za chwilę) może istnieć tylko jedna zmienna o danej nazwie. Zmiennym możemy przypisywać różne wartości, odczytywać je, zmieniać oraz przepisywać wartość jednej zmiennej do innej.
Jak zwykle zachęcam do uruchamiania poniższych przykładów.
Deklarowanie zmiennych, typy
Każda zmienna powinna być zadeklarowana. Mówimy w ten sposób Excelowi, żeby zarezerwował w pamięci kawałek miejsca i od teraz do tej części pamięci będziemy się odwoływać przez wskazaną przez nas nazwę. Deklarując zmienną podajemy jeden z wbudowanych typów Excela. Każdy z typów zajmuje odpowiednią ilość pamięci i jest przeznaczony do przechowywania odpowiedniego typu informacji. VBA udostępnia nam poniższe typy.
Typ | Rozmiar w piamięci | opis | Zakres wartości |
---|---|---|---|
Byte | 1 bajt | Wartości dodatnie | 0 do 255 |
Boolean | zależnie od systemu |
Dwie wartości | True lub False |
Integer | 2 bajty | wartości całkowite | -32,768 do +32,767 |
Long | 4 bajty | wartości całkowite |
-2,147,483,648 do +2,147,483,647 |
Single | 4 bajty | Liczby rzeczywiste | -3.4e38 do +3.4e38 |
Double | 8 bajtów | Liczby rzeczywiste | -1.8e308 do +1.8e308 |
Currency | 8 bajtów | Liczby rzeczywiste o stałej ilości miejsc po przecinku | -922,337,203,685,477.5808 do +922,337,203,685,477.5807 |
Date | 8 bajtów | Typ przeznaczony dla dat | 1 styczeń 100 to 31 grudzień 9999 |
Object | 4 bajty | Wskaźnik na obiekt | wskaźnik na dowolny obiekt |
String | zależnie od zawartości |
Zestaw znaków o zmiennej długości | Zmienny – Do 2 bilionów znaków |
Variant | 16 bajtów | Może przechowywać dowolną z powyższych wartości |
Wybierając typ balansujemy pomiędzy zwiększonym zużyciem pamięci oraz odpowiednią pojemnością. Oczywiście zasoby komputera są na tyle duże, że zdecydowanie częściej należy kierować się drugim z tych wskaźników.
Jeżeli chcemy, żeby nasza zmienna przechowywała zawsze wartości całkowite, wybierzemy Byte, Integer lub Long. Jeżeli ma przyjmować tylko dwie wartości prawda/fałsz wybierzemy Boolean. Do przechowywania numeru wiersza w Excelu 2007 wybierzemy Long, ponieważ w Integer numer wiersza może przekroczyć maksymalną wartość typu.
Deklaracje zmiennych są bardzo proste i rozpoczynają się od słowa kluczowego Dim:
1 2 3 4 |
Dim MojaNazwa As String Dim NumerWiersza As Long Dim Licznik As Integer Dim PracaZakonczona As Boolean |
Dim, pochodzi od angielskiego słowa dimension, czyli wymiar. Używając tego słowa nadajemy konkretny rozmiar zmiennej.
Każda zmienna typu wbudowanego w momencie deklaracji jest równa zero, zawiera pusty ciąg znaków lub nie wskazuje na żaden obiekt.
Deklaracja zmiennej może się też zaczynać od słowa Static lub Private, zamiast Dim. O tym powiem na końcu.
Operator przypisania
Wartości zmiennym nadaje się przy pomocy operatora przypisania „=”. Zmienna po lewej stronie operatora przyjmuje wartość wyliczoną po prawej stronie operatora. Takie przypisanie często nazywa się ustawianiem zmiennej lub nadawaniem wartości.
1 |
Option Explicit |
Niebezpieczną cechą VBE jest fakt, że nie wymusza on przy domyślnych ustawieniach deklarowania zmiennych. Zarówno kod.
1 2 |
Dim lv_i as integer lv_i = 2 |
jak i kod
1 |
lv_i = 2 |
są poprawne. w pierwszym przypadku Excel rezerwuje dwa bajty dla naszej zmiennej i od tej pory będzie traktował lv_i jako liczbę całkowitą. W drugim przypadku natrafiając na pierwsze użycie zmiennej lv_i przypisuje jej najbardziej „obszerny” typ, czyli Variant, zajmujący aż 16 bajtów.
Jeżeli chcemy, aby Excel wymuszał na nas deklarowanie zmiennych należy na początku modułu wpisać dyrektywę Option Explicit, lub dzięki ustawieniom poprosić Excela, aby zawsze wpisywał ją sam.
- W VBE kliknij w górnym menu tools/options.
- W nowym oknie na zakładce Editor zaznacz Require Variable declaration
Po skonfigurowanie tej opcji kod:
1 2 3 4 |
option explicit sub test() lv_i = 2 end sub |
wygeneruje błąd przy próbie uruchomienia, ponieważ próbujemy coś przypisać do zmiennej, która nie została wcześniej zadeklarowana.
Poprawnie wykona się kod:
1 2 3 4 5 |
option explicit dim lv_i as integer sub test() lv_i = 2 end sub |
Trochę więcej napiszę o option explicit w kolejnej części kursu. W tym miejscu chciałbym tylko podkreślić, że włączenie powyższej opcji jest absolutnie niezbędne i moim zdaniem Microsoft wyrządził krzywdę początkującym programistom nie włączając jej domyślnie.
Stałe
Stałe są specyficzną odmianą zmiennych. Przypisuje się im te same typy co zwykłym zmiennych i także przechowują pewne wartości, jednak ich zawartość może być określona tylko raz podczas deklaracji.
1 2 3 |
Const SzerokoscWiersza As Integer = 1 Const IloscPowtorzen As Long = 1000 Const NazwaNowegoArkusza As String = "NowyArkusz" |
Próby przypisania wartości do stałej wywołają błąd.
1 |
NazwaNowegoArkusza = "Nowy" |
Więcej o stałych i ich zaletach w następnej części kursu.
Literały
Literałami nazywamy bezpośrednie umieszczenie wartości w kodzie. Dlaczego literały nie powinny być używane poza deklaracjami stałych (pierwsza linia poniżej) w części kursu o dobrych praktykach progamowania.
1 2 3 4 5 6 |
Const DrugaPozycja As Byte = 1 MojaZmienna = 3 InneZmienna = MojaZmienna + 1 Const MojZakres As String = "D4:D100" MojeImie = "Michał" MsgBox Split(ActiveCell(1).Address(1, 0), "$")(0) |
Zmienne obiektowe
Zmienne mogą przechowywać nie tylko wartości liczbowe i ciągi znaków ale też obiekty. Mogą być to obiekty naszych klas (o czym w przyszłości) lub elementy modelu obiektowego Excela. Przypisywanie obiektów Excela do naszych zmiennych obiektowych może znacznie uprościć kod.
Zmienne obiektowe przypisuję się przy pomocy słowa kluczowego Set.
1 2 3 4 5 |
Dim NowyArkusz As Worksheet Set NowyArkusz = Worksheets.Add(Worksheets(1), , 1) Dim MojZakres As Range Set MojZakres = ActiveSheet.Range("A1") |
Oczywiście taka zmienna obiektowa ma teraz wszelkie atrybuty i właściwości swojego typu obiektu.
1 2 3 |
Dim MojSkoroszyt As Workbook Set MojSkoroszyt = ActiveWorkbook MsgBox "Ten skoroszyt ma nazwę: " & MojSkoroszyt.Name |
Zmienne obiektowe w momencie deklaracji nie wskazują na nic. Próba wywołania jakieś metody takiej zmiennej przed jej ustawieniem przy pomocy set wywoła błąd.
Widoczność zmiennych
Ostatnim ważnym elementem dotyczącym zmiennych, który chciałbym poruszyć w tej części kursu jest ich widoczność. Jest ona związana z miejscem i sposobem deklaracji zmiennej. Określa w której części pliku można tej zmiennej używać i nie spowoduje to błędu Variable not definied.
VBA udostępnia trzy poziomy widoczności. Pierwszym jest widoczność w ramach procedury. Tego typu zmienne określa się jako zmienne lokalne.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Sub ProceduraA() Dim i As Integer i = 1 MsgBox i End Sub Sub ProceduraB() Dim i As Integer i = 2 MsgBox i End Sub Sub ProceduraC() MsgBox i End Sub |
W procedurze A i B zadeklarowana została zmienna i. Są to tak naprawdę dwie różne zmienne, które nie mają na siebie wpływu. Próba uruchomienia ProceduraC wywoła błąd, ponieważ ta metoda nie zna zmiennej i.
Zwykle pamięć używana przez zmienne lokalne jest zwalniana wraz z końcem jej działania i ich zawartość przepada. W większości przypadków jest to pożądane działanie. Możemy jednak zamiast słowa kluczowego Dim użyć słowa Static. Uzyskujemy wtedy zmienną statyczną. Jest zawartość jest przechowywana pomiędzy kolejnymi wywołaniami funkcji.
1 2 3 4 5 6 7 |
Sub DodajArkusz() Static LicznikArkuszy As Integer Worksheets.Add Worksheets(1) LicznikArkuszy = LicznikArkuszy + 1 MsgBox "Dodałeś już " & LicznikArkuszy & " arkuszy." End Sub |
Przy każdym wywołaniu arkuszy zmienna LicznikArkuszy jest zwiększana o jeden. Zmienne statyczne są resetowane w przypadku:
- Pojawienia się błędu,
- Zmodyfikowania modułu,
- Zamknięcia Excela,
- Przerwania działania procedury przez zatrzymanie.
Drugim poziomem widoczności jest widoczność na poziomie modułu. Takie zmienne najczęściej określane ją jako zmienne modułowe. Są one widoczne dla wszystkich procedur umieszczonych w danym module, ale nie widoczne gdzie indziej.
Zmienne takie poprzedzamy słowem Dim lub Private i umieszczamy na górze modułu, przed definicją pierwszej procedury. Można te słowa stosować zamiennie, jednak warto pisać Private i Dim zachować dla zmiennych lokalnych. Kod jest wtedy bardziej czytelny.
1 2 3 4 5 6 7 8 9 10 11 |
Option Explicit Private j As Integer Sub ProceduraA() j = 2 End Sub Sub ProceduraB() MsgBox j End Sub |
Jeżeli najpierw wywołam procedurę A, to procedura B wyświetli liczbę 2.
Najbardziej obszernym poziomem widoczności są zmienne globalne. Są one widoczne w całym pliku. Deklaruje się je słowem Public. Zmienna globalna może być zadeklarowana w dowolnym module. Jeżeli nadamy takiej zmiennej wartość w jednym module, możemy ją odczytać w innym,
Należy pamiętać, że poziomy widoczności nakładają się.
Możemy zadeklarować zmienną o tej samej nazwie na każdym z trzech poziomów jednocześnie. Każda z tych zmiennych zajmie inne miejsce w pamięci i będzie mogła zawierać inną wartość.
- Jeżeli w jednym module zadeklarujemy zmienną globalną a w drugim modułową, to zmiana zmiennej modułowej nie wpłynie na globalną.
- Podobnie zmiana zmiennej lokalnej nie wpłynie na zmienną globalną, czy modułową o tej samej nazwie.
Spójrzmy na poniższy przykład.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
Option Explicit Private j Sub ProceduraA() j = 2 MsgBox j End Sub Sub ProceduraB() Dim j As Integer j = 3 MsgBox j End Sub Sub ProceduraC() MsgBox j End Sub Sub test() ProceduraA ProceduraB ProceduraC End Sub |
Po wywołaniu procedury test pojawią się trzy okienka.
W pierwszy i ostatnim pojawi się 2, ponieważ ProceduraB pracuje na zmiennej lokalnej innej niż procedury A i C.
Wyjątkiem jest zadeklarowanie zmiennej globalnej i modułowej o tej samej nazwie w jednym module, to wywoła błąd.
W kolejnej części kursu napiszę więcej o praktycznym zastosowaniu widoczności.
Subskrybuj RSS, lub polub blog na Facebooku aby otrzymywać najnowsze informacje o rozwoju kursu.
Comments 3
Świetny kurs! Wielkie gratulacje i ogromne podziękowanie za czas włożony w opisanie tego wszystkiego. Nawet nie wiesz jak bardzo mi tym pomogłeś 🙂 Dzięki takim ludziom jak Ty aż chce się uczyć nowych rzeczy! Jeszcze raz gratulacje i wielkie dziękuje!
Damian
Bardzo dziękuję za komplementy. Dzięki ludziom jak Ty, chce mi się dalej pisać!
Super wyjasnione! dziekuje