Zmienne
Korzystanie ze zmiennych
Deklarowanie zmiennych nie jest obowiązkowe, ale jest to niebezpieczne i kto tego nie czyni, ten sam sobie szkodzi. Deklarowanie zmiennych można wymusić dodając instrukcję
Option Explicit
w pierwszej linii każdego modułu.
Linki:
Instrukcja Option Explicit
Using Procedures, Functions and Properties
Typy zmiennych
Integer: liczby całkowite od -32768 do 32767 (czyli od -215 do 215-1) Long: liczby całkowite od -2147483648 do 2147483647 (czyli od -231 do 231-1) Single: liczby wymierne od 3,402823 x 10E38 do 1,401298 x 10E-45 Double: liczby wymierne od 1,79769313486232 x 10E308 do 4,94065645841247 x 10E-324 String: ciągi znakowe o długości do 65535 znaków Boolean: wartości logiczne: TRUE (prawda) lub FALSE (fałsz) (liczba zero odpowiada wartości FALSE, każda liczba różna od zera odpowiada wartości TRUE) Date: informacje o dacie i godzinie (dacie 31.12.1899 odpowiada wartość liczbowa 1) Currency: liczby w formacie walutowym (z symbolem waluty) Object: zmienna typu obiekt Variant: do zmiennej typu Variant można przypisać każdy rodzaj wymienionych wyżej danych
Deklarowanie zmiennych wewnątrz procedury lub funkcji
Każdą zmienną należy deklarować oddzielnie. Jeżeli nazwy zmiennych oddzielimy przecinkami, to tylko ostatnia zmienna zostanie zadeklarowane zgodne z podanym typem. Pozostałe zmienne będą zmiennymi typu Variant. W poniższych procedurach typy zmiennych a1, a2, a3 oraz typy zmiennych x1, x2, x3 są (odpowiednio) jednakowe.
Sub Zmienne1()
'zmienne a1, a2, a3 są zadeklarowane tak samo, jak zmienne x1, x2, x3
Dim a1, a2, a3 as Long
Dim x1 as Variant
Dim x2 as Variant
Dim x3 as Long
a1 = 1
a2 = "abcd"
a3 = "xyz"
x1 = 1
x2 = "abcd"
x3 = "xyz"
MsgBox "a1=" & a1 & " a2=" & a2 & " a3=" & a3 & Chr(10) & _
"x1=" & x1 & " x2=" & x2 & " x3=" & x3
'a1=1 a2=abcd a3=0
'x1=1 x2=abcd x3=0
End Sub
Sub Zmienne2()
'zmienne a1, a2, a3 są zadeklarowane tak samo, jak zmienne x1, x2, x3
Dim a1 as Long, a2 as Long, a3 as Long
Dim x1 as Long
Dim x2 as Long
Dim x3 as Long
a1 = 1
a2 = "abcd"
a3 = "xyz"
x1 = 1
x2 = "abcd"
x3 = "xyz"
MsgBox "a1=" & a1 & " a2=" & a2 & " a3=" & a3 & Chr(10) & _
"x1=" & x1 & " x2=" & x2 & " x3=" & x3
'a1=1 a2=0 a3=0
'x1=1 x2=0 x3=0
End Sub
Link:
Instrukcja Dim
Deklarowanie typu funkcji oraz typu parametrów procedury lub funkcji
Typ funkcji oraz typy parametrów w procedurze lub funkcji deklarujemy według schematu:
Function NazwaFunkcji(Parametr1 as TypZmiennej, ..., ParametrN as TypZmiennej) as TypZmiennej
Przykładowo:
Function PoleProstokata(a as Double, b as Double) as Double
UWAGA:
Nie powinniśmy wywoływać funkcji z parametrem innego typu niż typ zadeklarowany w funkcji. Jednak ludzie popełniają błędy i należy wiedzieć, co się stanie w takim przypadku. Musimy pamiętać, że LibreOffice nie zgłosi automatycznie błędu w przypadku wykrycia niezgodności typów, ale podejmie próbę konwersji użytej zmiennej na typ zgodny z zadeklarowanym w kodzie funkcji. Poniższa tabela przedstawia, jakie wartości otrzymamy w zależności od zadeklarowanego typu parametru i jego pierwotnej wartości:
Integer | Long | Single | Double | String | Boolean | Date | Currency | |
---|---|---|---|---|---|---|---|---|
"abc" | 0 | 0 | 0 | 0 | "abc" | X | X | X |
"357" | 357 | 357 | 357 | 357 | "357" | True | X | 357.0000 |
"3.57" | 4 | 4 | 3,57 | 3,57 | "3.57" | True | X | 3.5700 |
123 | 123 | 123 | 123 | 123 | "123" | True | 02.05.1900 | 123.0000 |
456.789 | 457 | 457 | 456,789 | 456,789 | "456,789" | True | 31.03.1901 18:56:09 | 456.7890 |
True | -1 | -1 | -1 | -1 | "True" | True | 29.12.1899 | -1.0000 |
False | 0 | 0 | 0 | 0 | "False" | False | 00:00:00 | 0.0000 |
DateSerial(2000, 12, 30) | Y | 36890 | 36890 | 36890 | "30.12.2000" | True | 30.12.2000 | 36890.0000 |
Symbole X oraz Y oznaczają, że wystąpi błąd i pojawią się następujące komunikaty o błędzie:
X – Niedopuszczalna wartość lub typ danych. Niezgodne typy danych. Y – Niedopuszczalna wartość lub typ danych. Przepełnienie.
Zmienne statyczne
Zmienne statyczne deklarujemy poleceniem:
Static NazwaZmiennej as TypZmiennej
Zmienna statyczna jest widoczna tylko w obrębie procedury lub funkcji, w której została zadeklarowana. Po zakończeniu działania procedury lub funkcji, w której zmienna statyczna została zadeklarowana, wartość zmiennej statycznej nie ginie, ale będzie stanowiła wartość początkową tej zmiennej przy kolejnym wywołaniu procedury lub funkcji. Inaczej mówiąc, zmienna statyczna zachowuje wartość między kolejnymi wywołaniami procedury / funkcji.
Sub StaticTest()
'zmienna a po zadeklarowaniu przyjmie wartość 0
Dim a as Long
'zmienna statyczna s po zadeklarowaniu przyjmie wartość 0 lub wartość, jaką miała
'w momencie zakończenia działania procedury lub funkcji, w której została zadeklarowana
Static s as Long
MsgBox "a=" & a & " s=" & s
a = a + 1
s = s + 1
End Sub
Sub Zmienne3()
Call StaticTest() 'a=0 s=0
Call StaticTest() 'a=0 s=1
Call StaticTest() 'a=0 s=2
End Sub
Link:
Instrukcja Static
Deklarowanie zmiennych poza procedurą lub funkcją
Istnieją trzy instrukcje, za pomocą których deklarujemy zmienne poza podprogramem: Private, Public i Global. W przypadku deklaracji Public i Global zmienna zadeklarowana poza podprogramem jest widoczna we wszystkich modułach. W przypadku deklaracji Private sytuacja jest bardziej skomplikowana i zależy również od tego, w ilu modułach zmienna została zadeklarowana.
Uwaga:
Jeżeli w module umieścimy kilka deklaracji zmiennej jako Private / Public / Global (co może się zdarzyć w wyniku błędu lub w czasie testowania), to o typie zmiennej decyduje ostatnia z wypisanych deklaracji.
Uwagi i oznaczenia
Jeżeli w jakimkolwiek module zostanie wywołany podprogram, wewnątrz którego zmienna Zmn została zadeklarowana instrukcją Dim, to deklaracja wewnątrz podprogramu jest nadrzędna. Oznacza to, że jest inicjowana nowa zmienna o nazwie Zmn, która będzie istniała do czasu zakończenia wykonywania tego podprogramu, a w tym czasie zmienna zdefiniowana na zewnątrz będzie niedostępna (zostanie przesłonięta przez nową zmienną).
Oznaczenia:
ModuleA – moduł, w którym znajduje się uruchamiany program (program główny)
ProgA – program główny uruchamiany przez użytkownika, który znajduje się w module o nazwie ModuleA
Zmn – nazwa zmiennej, która nie jest zadeklarowana wewnątrz ProgA i musi zostać zadeklarowana jako Private / Public / Global, aby system nie wykazał błędu
ModuleFrst – nazwa pierwszego z modułów, w którym występuje deklaracja Private zmiennej Zmn
ModuleLst – nazwa ostatniego z modułów, w którym występuje deklaracja Public lub Global zmiennej Zmn
Zauważmy, że ProgA może zakończyć działanie:
- nie odwołując się do żadnych innych podprogramów
- odwołując się jedynie do podprogramów z ModuleA
- odwołując się do dowolnych podprogramów, z których przynajmniej jeden znajduje się w module innym niż ModuleA
- nie odwołując się do żadnych innych podprogramów
Private
Private Zmn as TypZmiennej
Jeżeli w danym module zmienna Zmn nie jest zadeklarowana jako Private, to każde wywołanie podprogramu z tego modułu (w którym to podprogramie zmienna Zmn nie została zadeklarowana instrukcją Dim), nie wpływa na zmienną Zmn i jest ona cały czas dostępna zgodnie z wcześniejszą deklaracją i poprzednią wartością.
Opis działania deklaracji Private sprowadza się do dwóch przypadków:
A. Zmienna Zmn jest zadeklarowana jako Private w ModuleA
W tym przypadku deklaracja zmiennej Zmn obowiązuje tak długo, dopóki nie zostanie wywołany podprogram z innego modułu, w którym zmienna Zmn jest zadeklarowana jako Private. Od tej chwili system tworzy kolejną zmienną o tej samej nazwie, która będzie istniała do momentu opuszczenia tego modułu.
B. Zmienna Zmn nie jest zadeklarowana jako Private w ModuleA
W tym przypadku zmienna Zmn zostanie zadeklarowana zgodnie z deklaracją zmiennej Zmn znajdującą się w ModuleFrst. Podobnie jak w przypadku A. deklaracja zmiennej Zmn obowiązuje tak długo, aż nie zostanie wywołany podprogram z innego modułu, w którym zmienna Zmn jest zadeklarowana jako Private. Od tej chwili system tworzy kolejną zmienną o tej samej nazwie, która będzie istniała do chwili opuszczenia tego modułu. Nie dotyczy to wywołania podprogramu z ModuleFrst – w tym przypadku nie zostanie utworzona nowa zmienna.
Zauważmy, że zmienna zadeklarowana jako Private tylko w jednym z modułów jest widoczna we wszystkich modułach. Może spowodować to niezamierzone skutki:
- jeżeli użyjemy zmiennej o takiej samej nazwie wewnątrz podprogramu, to system nie ostrzeże nas o niezadeklarowaniu zmiennej
- przypadkowe zadeklarowanie tej samej zmiennej w innym module jako Private może doprowadzić do błędu w obliczeniach
Public
Public Zmn as TypZmiennej
Zmienna zadeklarowana jako Public jest widoczna we wszystkich modułach. Po wykonaniu procedury lub funkcji jej wartość zostaje zresetowana. Jeżeli zamieścimy wiele deklaracji zmiennej Zmn jako Public, to zmienna Zmn zostanie zadeklarowana zgodnie z deklaracją umieszczoną w ModuleLst.
Link:
Instrukcja Public
Global
Global Zmn as TypZmiennej
Zmienna zadeklarowana jako Global jest widoczna we wszystkich modułach. Po zakończeniu programu ProgA jej wartość nie jest resetowana i jest dostępna przy kolejnym wywołaniu dowolnej procedury lub funkcji. Jeżeli zamieścimy wiele deklaracji zmiennej Zmn jako Global, to zmienna Zmn zostanie zadeklarowana zgodnie z deklaracją umieszczoną w ModuleLst.
Uwaga:
Jeżeli usuniemy deklarację zmiennej jako Global zamieszczoną w ModuleLst, to LibreOffice tego nie nie zauważy i nie nastąpi zmiana typu zmiennej. Musimy ponownie załadować plik, korzystając z opcji: Plik ➔ Załaduj ponownie (lub sekwencją klawiszy: Lewy Alt + [p] [w] [Enter])
Link:
Instrukcja Global
Wnioski
Z powyższej analizy wynika, że najdogodniej jest posługiwać się zmiennymi zadeklarowanymi jako Public. Jeżeli dodatkowo przyjmiemy zasadę, że wszystkie te zmienne deklarujemy w pierwszym module zaraz pod instrukcją Option Explicit, to prawdopodobieństwo utraty kontroli nad tymi zmiennymi i popełnienia błędu będzie znikome.
Uwaga:
Czytelnik może spotkać się z deklaracją zmiennych na zewnątrz procedur lub funkcji przy pomocy słowa Dim. Taka deklaracja jest równoważna deklaracji przy pomocy słowa Private i nie należy jej stosować, bo po pierwsze cierpi na tym czytelność napisanego kodu, a po drugie nie mamy żadnej gwarancji, że ten sposób deklarowania zmiennych na zewnątrz podprogramów zostanie w przyszłości utrzymany.
LibreOffice Calc – makra – przykłady Strona główna