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
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 |
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