Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - První objektová aplikace ve VBA - Hello object world

V minulé lekci, Úvod - Objektově orientované programování ve VBA, jsme si představili objektově orientované programování. Vysvětlili jsme si, jak funguje a rozebrali pojmy třída, funkce, procedura a zapouzdření.

V dnešním VBA tutoriálu si naprogramujeme jednoduchý program Hello object world, který nás bude zdravit. Objektově!

Již víme, že objekty mají vlastní proměnné, procedury a funkce. Také víme, že k inicializaci objektu potřebujeme nejprve vytvořit třídní modul, který je vzorem a podle kterého následně tvoříme jeho instance.

Vytvoření třídního modulu

Vytvoříme si nový Excel sešit. Poté v něm pomocí klávesové zkratky Alt+F11 otevřeme programovací IDE sešitu a necháme si zobrazit okno Project Explorer (Průzkumník projektu), pokud se nám tedy již nezobrazuje.

Okno Project Explorer zobrazíme buď pomocí klávesové zkratky Ctrl+R, anebo z nabídky View -> Project Explorer.

V okně Project Explorer se nám zobrazují jednotlivé listy Excelu a modul ThisWorkbook.

Nyní pravým tlačítkem myši klikneme kdekoli v okně Project Explorer a z roletové nabídky zvolíme Insert => Class Module:

Objektově orientované programování (OOP) ve VBA

Po vložení třídního modulu se ještě ujistíme, že máme otevřené okno Properties Window (Okno vlastností). Toho docílíme klávesou F4, nebo z nabídky View -> Properties Window. Jedná se o okno zakroužkované červenou barvou na následujícím výstřižku:

Objektově orientované programování (OOP) ve VBA

Náš nově vytvořený třídní modul byl implicitně pojmenován jako Class1, což se nám ale moc nelíbí. Jak je již tradice v tutoriálech na stránkách ITnetwork, vytváříme si objekt, který nás i objektově pozdraví. Řekněme, že by se třídní modul mohl jmenovat Clovek.

Moduly pojmenováváme bez použití diakritiky pomocí takzvané velbloudí notace (Camel Case), kdy modul začíná na velké písmeno. Pokud se jeho název sestává z vícero slov, píšeme je dohromady a každé nové slovo opět s velkým písmenem. V identifikátorech nikdy nepíšeme diakritiku.

Nyní si třídní modul přejmenujeme z Class1 na Zdravic. To lze provést pouze v okně Properties Window, kde klikneme na položku (Name). Přejmenujeme modul na Zdravic a potvrdíme:

Vytváření nové třídy ve VBA - Objektově orientované programování (OOP) ve VBA

Podle tohoto třídního modulu později vytvoříme objekt zdravic, který nás bude umět pozdravit. Vidíme, že se na program již díváme úplně jinak. Za každou akci je zodpovědný nějaký objekt a nestačí pouze něco "nabušit" do jedné procedury v modulu, nebo v listu. V našem případě nám to může přijít zbytečné, ale u složitějších aplikací si to budeme pochvalovat :)

Naše IDE nám ve třídním modulu Zdravic vygenerovalo Option Explicit, který si tam ponecháme.

Vytvoření procedury Pozdrav()

Nyní si do třídního modulu Zdravic přidáme proceduru Pozdrav(), která bude veřejně viditelná a nebude mít žádnou návratovou hodnotu ani parametry.

Deklarace procedury ve VBA je tedy následující:

[modifikátor přístupu] Sub [JmenoProcedury]

Před proceduru píšeme tzv. modifikátor přístupu, v našem případě Public (veřejný).

Kdybychom modifikátor vynechali, VBA by proceduru přesto chápalo jako Public (veřejnou). Doporučuji ale minimálně pro přehlednost modifikátory vždy uvádět. Pokud bychom chtěli s procedurou pracovat pouze uvnitř třídního modulu a nechtěli bychom, aby byla viditelná zvenčí, použili bychom modifikátor Private (neveřejný).

Dále bude následovat samotný název procedury. Procedury píšeme, stejně jako třídní moduly, velbloudí notací s velkým počátečním písmenem. Postup, jak deklarovat procedury s parametry, si ukážeme za chvíli.

Do těla procedury Pozdrav() zapíšeme tento kód pro výpis na konzoli:

Option Explicit

Public Sub Pozdrav()
    Debug.Print "Hello object world!"
End Sub

Zde jsme prozatím skončili. Ještě nám ale zbývá instanci našeho nově vytvořeného třídního modulu Zdravic nadeklarovat a nadefinovat.

Vytvoření standardního modulu

Klikneme pravým tlačítkem myši kdekoli v okně Project Explorer a z roletové nabídky zvolíme Insert => Module. Pojmenujeme si ho třeba jako Main.

Vytvoření procedury Main()

Do modulu Main si poté napíšeme soukromou proceduru, kterou si opět nějak pojmenujeme, například také jako Main().

Nyní si v těle této procedury Main() vytvoříme instanci třídního modulu Zdravic. Bude to tedy ten objekt zdravic, se kterým budeme pracovat. Objekty se ukládají do proměnných. Název třídního modulu slouží jako datový typ. Instance má zpravidla název třídního modulu, jen má první písmeno malé. Deklarujme si proměnnou a následně v ní založme novou instanci třídního modulu Zdravic:

Dim Zdravic As Zdravic
Set Zdravic = New Zdravic()

Asi jsme si správně všimli, že název instance i třídního modulu začíná velkým písmenem. Je to kvůli nedokonalosti našeho IDE. Zkusme si u názvu instance změnit první písmeno na malé. Naše IDE nám automaticky změní na malé písmeno rovněž počáteční písmeno názvu našeho třídního modulu v deklaraci. Je to taková malá vada na kráse. Té bychom se vyhnuli, pokud bychom instanci pojmenovali jinak, než třídní modul.

První řádek říká: "Chci (deklaruji) proměnnou zdravic, ve které bude instance třídního modulu Zdravic". S proměnnými jsme vlastně již takto pracovali.

Na druhém řádku je klíčové slovo New, které nám založí novou instanci třídního modulu Zdravic. Tuto instanci přiřadíme do naší proměnné. Klíčovým slovem Set říkáme, že instanci definujeme (nastavujeme).

Celý zápis můžeme samozřejmě zkrátit na:

Dim Zdravic As New Zdravic()

Jelikož v proměnné nyní máme opravdu instanci třídy Zdravic, můžeme instanci nechat pozdravit. Zavoláme na ni proceduru Pozdrav(), a to jako Zdravic.Pozdrav(). Kód procedury Main() bude tedy nyní vypadat následovně:

Private Sub Main()
    Dim Zdravic As Zdravic
    Set Zdravic = New Zdravic()
    Zdravic.Pozdrav()
End Sub

Program nyní spustíme.

Před každým spuštěním musíme mít kurzor umístěný uvnitř procedury Main(). Program se spouští z menu Run => Run Sub/UserForm nebo klávesou F5.

Na konzoli se nám právě vypsal text Hello object world!

Pokud konzoli nevidíme, stiskněme současně klávesy Ctrl+G. Objeví se okno Immediate, kde si můžeme číst naše výpisy na konzoli.

Máme tedy svou první objektovou aplikaci!

Procedura s parametrem

V třídním modulu Zdravic dejme nyní naší proceduře Pozdrav() parametr jmeno. Dále upravme text, který vypisujeme na konzoli tak, aby dokázala pozdravit konkrétního uživatele:

Public Sub Pozdrav(jmeno As String)
    Debug.Print "Ahoj uživateli " + jmeno
End Sub

Vidíme, že syntaxe parametru procedury je stejná, jako je syntaxe proměnné. Pouze vynecháme klíčové slovo Dim. Kdybychom chtěli parametrů více, oddělujeme je čárkou. V modulu Main nyní upravíme nyní naši proceduru Main():

Private Sub Main()
    Dim Zdravic As Zdravic
    Set Zdravic = New Zdravic()
    Zdravic.Pozdrav ("Karle")
    Zdravic.Pozdrav ("Petře")
End Sub

Náš kód je nyní v proceduře a my ho můžeme jednoduše pomocí parametrů volat znovu s různými parametry. Nemusíme 2x opisovat "Ahoj uživateli...".

Program spustíme:

Konzolová aplikace
Ahoj uživateli Karle
Ahoj uživateli Petře

Kód budeme odteď dělit logicky do procedur.

Proměnná třídního modulu

Třídnímu modulu Zdravic přidáme nějakou proměnnou. Nabízí se text, kde bude uložen text pozdravu. Proměnné v třídním modulu se definují stejně jako lokální proměnné s tím rozdílem, že vždy u nich musíme uvést modifikátor přístupu. My použijeme Public, protože s ním chceme pracovat zvenčí třídy.

Upravme si tedy náš třídní modul Zdravic takto:

Option Explicit

Public text As String

Public Sub Pozdrav(jmeno As String)
    Debug.Print text + jmeno
End Sub

Text nyní musíme pochopitelně nastavit vytvořené instanci v proceduře Main() v modulu Main:

Option Explicit

Private Sub Main()
    Dim Zdravic As Zdravic
    Set Zdravic = New Zdravic()
    Zdravic.text = "Ahoj uživateli "
    Zdravic.Pozdrav ("Karle")
    Zdravic.Pozdrav ("Petře")
    Zdravic.text = "Vítám Tě tu, programátore  "
    Zdravic.Pozdrav ("Richarde")
End Sub

Když program spustíme dostaneme tento výstup:

Konzolová aplikace
Ahoj uživateli Karle
Ahoj uživateli Petře
Vítám Tě tu, programátore Richarde

Vrácení hodnoty z funkce

Vzhledem k objektovému návrhu není nejvhodnější, aby si každý objekt ovlivňoval vstup a výstup, jak se mu zachce. Pochopitelně narážím na naše vypisování do konzole. Každý objekt by měl mít určitou kompetenci a tu by neměl překračovat. Pověřme náš objekt pouze sestavením pozdravu a jeho výpis si zpracujme již mimo, v našem případě v proceduře Main(). Výhodou takto navrženého objektu je vysoká univerzálnost a znovupoužitelnost.

Objekt doposud umí jen psát do konzole. My ho však přizpůsobíme tak, aby daná funkce text pouze vracela a bylo na jeho příjemci, jak s ním naloží. Takto můžeme pozdravy ukládat do souborů, psát na webové stránky, nebo dále zpracovávat.

Jelikož chceme, aby procedura vracela hodnotu, a to typu String, zaměníme klíčové slovo Sub za Function, čímž jsme proceduru změnili na funkci. Za kulaté závorky připíšeme As String, kterým určujeme, že funkce vrátí datový typ String. K návratu hodnoty použijeme název této funkce spolu s rovnítkem Pozdrav =.

V třídním modulu Zdravic změníme tedy proceduru Pozdrav() na funkci Pozdrav():

Public Function Pozdrav(jmeno As String) As String
    Pozdrav = text + jmeno
End Function

Tělo procedury Main() v modulu Main pak změníme následovně:

Private Sub Main()
    Dim Zdravic As Zdravic
    Set Zdravic = New Zdravic()
    Zdravic.text = "Ahoj uživateli "
    Debug.Print Zdravic.Pozdrav("Karle")
    Debug.Print Zdravic.Pozdrav("Petře")
    Zdravic.text = "Vítám Tě tu, programátore  "
    Debug.Print Zdravic.Pozdrav("Richarde")
End Sub

Program spustíme. Dostaneme tento výstup:

Konzolová aplikace
Ahoj uživateli Karle
Ahoj uživateli Petře
Vítám Tě tu, programátore Richarde

Vytvořili jsme si objekt Zdravic, kterému jsme nastavili text používaný pro pozdrav. Na objektu Zdravic jsme posléze vyvolali funkci Pozdrav(), které jsme jako parametr předali jméno toho, koho chceme pozdravit - tj. Karla. Vzápětí jsme vyvolali tu samou funkci, ale tentokrát jsme jí jako parametr předali jméno jiné osoby - tj. Petra. Nakonec jsme změnili text pozdravu text a nechali jsme pozdravit Richarda novým pozdravem.

A jsme u konce. Námi napsaný program má již nějakou úroveň, i když toho zatím vlastně moc nedělá.

V příští lekci, Hrací kostka ve VBA - Zapouzdření, konstruktor a Randomize, se naučíme používat konstruktor a generátor náhodných čísel Randomize. Naprogramujeme si objektovou hrací kostku, první část naší arény.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 23x (27.19 kB)
Aplikace je včetně zdrojových kódů

 

Předchozí článek
Úvod - Objektově orientované programování ve VBA
Všechny články v sekci
Objektově orientované programování (OOP) ve VBA
Přeskočit článek
(nedoporučujeme)
Hrací kostka ve VBA - Zapouzdření, konstruktor a Randomize
Článek pro vás napsal Michal D.
Avatar
Uživatelské hodnocení:
10 hlasů
Autor se věnuje tvorbě mobilních aplikací.
Aktivity