Provázané TextBoxy na formuláři

Provázané TextBoxy na formuláři potřebujeme v případě, kdy například mají sloužit jako převodník mezi fyzikálními jednotkami (tlak, GPS souřadnice, …). Pokud je vazba jednosměrná, stačí v události Change prvního prvku měnit obsah druhého. Jestliže ale nechcete uživatele omezovat v tom, který prvek si vybere jako vstupní, pak už to s kódem VBA nebude tak jednoduché. A co když se navzájem ovlivňují tři textová pole na formuláři?

Hned zkraje je potřeba si uvědomit, že Application.EnableEvents nezahrnuje události ovládacích prvků na formuláři. V obecném případě si definujeme globální proměnnou (např. blnUdalostiZapnuty) a v událostních procedurách prvků testujeme její stav. Velmi často při spouštění formuláře (procedura UserForm_Initialize) plníme prvky výchozími hodnotami. Už změna obsahu prvního z nich přesune probíhající kód do událostní procedury Change tohoto prvku. Pokud v ní pracujeme s dalším prvkem, může dojít k řetězové reakci událostí Change. Proto je UserForm_Initialize prvním místem, kde bychom měli s naší globální proměnnou pracovat (přiřadit False na začátku a True na konci).

V praxi je běžné, že se ovlivňuje více prvků navzájem. Tady už si s jednou globální proměnnou nevystačíme.

Příklad ukazuje převodník mezi délkovými jednotkami metr (m) – stopa (ft) – yard (yd). Samotné výpočty se řídí prostou trojčlenkou.

1 yd = 3 ft
1 ft = 0,3048 m
1 yd = 0,9144 m

Provázané TextBoxy - návrh
Provázané TextBoxy – návrh

Pro každý prvek založíme na úrovni modulu vlastní proměnnou (jakýsi přepínač).

1
2
3
Private blnMetrStopUdalost As Boolean
Private blnStopaStopUdalost As Boolean
Private blnYardStopUdalost As Boolean

Při startu formuláře „vypneme“ u všech prvků kromě jednoho události a u tohoto prvku si zajistíme, aby jeho událost proběhla. O to se postará naplnění prvku (u TextBoxu přiřazení hodnoty do vlastnosti Text, u jiných prvků jako je ComboBox metoda AddItem).

1
2
3
4
5
6
7
8
9
10
11
12
13
Private Sub UserForm_Initialize()

    'povoleni udalosti pro prvni prvek
    blnMetrStopUdalost = False
    'zakaz udalosti pro ostatni prvky
    blnStopaStopUdalost = True
    blnYardStopUdalost = True

    'prirazeni hodnoty do prvniho prvku
    'a vynuceni udalosti
    txtMetr.Text = 1

End Sub

Zpracování událostních procedur jednotlivých textových polí pak bude mít následující podobu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Private Sub txtMetr_Change()

    'je povolena udalost pro tento prvek?
    If blnMetrStopUdalost = False Then

        'zakaz udalosti pro ostatni prvky
        blnStopaStopUdalost = True
        blnYardStopUdalost = True

        'prepocet ostatnich prvku
        txtStopa.Text = Format(txtMetr.Text / 0.3048, "0.00000")
        txtYard.Text = Format(txtMetr.Text / 0.9144, "0.00000")
       
        'povoleni udalosti pro ostatni prvky
        blnStopaStopUdalost = False
        blnYardStopUdalost = False

    End If

End Sub

Private Sub txtStopa_Change()

    'je povolena udalost pro tento prvek?
    If blnStopaStopUdalost = False Then

        'zakaz udalosti pro ostatni prvky
        blnMetrStopUdalost = True
        blnYardStopUdalost = True

        'prepocet ostatnich prvku
        txtMetr.Text = Format(0.3048 * txtStopa.Text, "0.00000")
        txtYard.Text = Format(txtStopa.Text / 3, "0.00000")

        'povoleni udalosti pro ostatni prvky
        blnMetrStopUdalost = False
        blnYardStopUdalost = False

    End If

End Sub

Private Sub txtYard_Change()

    'je povolena udalost pro tento prvek?
    If blnYardStopUdalost = False Then

        'zakaz udalosti pro ostatni prvky
        blnMetrStopUdalost = True
        blnStopaStopUdalost = True

        'prepocet ostatnich prvku
        txtMetr.Text = Format(0.9144 * txtYard.Text, "0.00000")
        txtStopa.Text = Format(3 * txtYard.Text, "0.00000")

        'povoleni udalosti pro ostatni prvky
        blnMetrStopUdalost = False
        blnStopaStopUdalost = False

    End If

End Sub
Provázané TextBoxy - vstupní TextBox č. 1
Provázané TextBoxy – vstupní TextBox č. 1
Provázané TextBoxy - vstupní TextBox č. 2
Provázané TextBoxy – vstupní TextBox č. 2
Provázané TextBoxy - vstupní TextBox č. 3
Provázané TextBoxy – vstupní TextBox č. 3

Funguje to vlastně velmi jednoduše. Procedura zjistí, je-li událost v rámci daného prvku povolena. Pokud ano, zakáže události všem ostatním, vykoná na nich, co potřebuje, a na konci blokaci odstraní.

Proč u TextBoxu pracujeme s vlastností Text a ne Value? Je to proto, že vlastnost Value nezohledňuje české prostředí a například desetinnou čárku. Čísla zde zaokrouhlujeme na pět desetinných míst.

Nyní už by pro vás nemělo být těžké nechávat kupříkladu uživatele vyplnit libovolná tři textová pole pro výpočet charakteristik trojúhelníku a dopočítávat zbylé parametry.

Příloha:
provazane_textboxy.zip