Zmienne

Z Henryk Dąbrowski
Wersja z dnia 22:36, 18 wrz 2022 autorstwa HenrykDabrowski (dyskusja | edycje) (1 wersja)
(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Przejdź do nawigacji Przejdź do wyszukiwania
16.10.2020



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

Korzystanie ze zmiennych

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, PublicGlobal. 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


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                   Strona główna