# Makra

K usnadnění automatizace opakujících se úkolů se v Excelu používají **Makra** (ve VBA označovány jako `Sub` - z anglického subroutine (podprogram)). Tyto makra představují sadu instrukcí a kódu, které počítač při spuštění makra splní.

```vb
'Ukázka kódu nadefinovaného makra
Sub [název_makra]()
    'Na toto místo patří kód makra
End Sub
```

## Zaznamenání maker v Excelu

Jak již bylo řečeno v úvodní kapitole, VBA je primárně určeno k automatizaci akcí, které uživatel v aplikaci Excel používá neustále dokola. Tyto činnosti lze "nahrát" v rámci aplikace Excel jako postup VBA příkazů. Tyto příkazy lze později upravit a měni dle potřeby v editoru VBA. 

### Postup vytvoření nahrávaného makra

1. Zvolte kartu `Vývojář`
2. Stiskněte tlačítko `Zanamenat Makro` nacházející se na levé straně karty
3. Zadejte název vašeho makra do pole `Název makra` - Například ```MojeNahraneMakro```. Při vytváření názvu nikdy nepoužívejte české znaky nebo mezery, protože by to mohlo způsobovat problémy.
4. Pokud chcete přiřadit v sešitu klávesovou zkratku pro toto makro, přidejte písmeno do `Klávesová zkratka`. Pokud zmáčknete klávesu `Ctrl` a vaše písmeno, makro se spustí.
5. Vyberte v rámci nastavení `Uložit makro do` místo, kde bude nově vzniklé makro uloženo. Makro lze uložit do jedné z možností: `Tento sešit`, `Nový sešit` a `Osobní sešit maker`.
6. Přidejte `Popis`, který slouží jako nápověda pro použití vašeho makra. Popis není nutné přidávat, ovšem je dobré jej použít v případě, kdy makro sdílíte s ostatními uživateli.
7. Potvrďte vytvoření tlačítkem `OK`.
8. Excel nyní nahrává všechny akce, které uživatel udělá. Udělejte postup, který chcete do makra zaznamenat.
9. Po dokončení postupu stačí ukončit záznam na kartě `Vývojář` pomocí tlačítka `Zastavit záznam`.

#### Relativní odkazy

Možnost `Použít relativní odkazy` mění chování záznamenávání makra. Pokud je tato možnost zvolená, do postupu, který Excel zaznamenává, se místo konkrétních pozic buněk (např. A6) budou zapisovat pozice s odsazením od aktuálně vybrané buňky (například buňka o 4 sloupce dále).

![Alt text](media/01-02-zaznamenavani_maker-relativni_odkazy.png)

Tato funkce je vhodná použít v případě, kdy je potřeba vytvořit a použít makro na odsazení od buňky a nikoliv na konkrétní místo v sešitě.

## Vytvoření makra pomocí kódu

1. Otevřete nový prázdný dokument v Excelu
2. Zvolte kartu `Vývojář`
3. Stiskněte tlačítko `Makra` nacházející se na levé straně karty
4. Zadejte název vašeho makra do pole `Název makra` - Například ```MojeMakro```. Při vytváření názvu nikdy nepoužívejte české znaky, protože by to mohlo způsobovat problémy.
5. Stiskněte tlačítko `Vytvořit`

Po dokončení kroku 5 se otevře Microsoft VBA Editor s novým modulem obsahující definici vámi pojmenovaného makra, například: 

```vb
Sub MojeMakro()
    
End Sub
```

## Spuštění makra

Makro se dá spustit několika způsoby:
V editoru VBA stačí stisknout tlačítko spustit (`Run Sub/UserForm`) se zelenou šipkou nebo stisknout (s kurzorem na pozici v daném makru) klávesu `F5`.

Z programu Excel:
1. Vyberte kartu `Vývojář` a stiskněte tlačítko `Makra`
2. Vyberte vaše makro ze seznamu
3. Klikněte na tlačítko `Spustit`

Po spuštění makra proběhne zavolání makra, následně se provedou všechny příkazy, které jsou v rámci makra napsané. Tyto příkazy ovlivňují dokument Excelu postupně od vrchního příkazu po nejspodnější příkaz. Po dokončení posledního příkazu se nic nestane.

![Diagram způsobu fungování makra](media/01-01-makra-diagram_makra.png)

<p class="text-center">Diagram způsobu fungování makra</p>

## Uložení maker

Ukládání souboru do normálního excel dokumentu `Sešit Excelu` (.xls) způsobí, že vytvořená makra se v souboru neuloží. K uložení dokumentu včetně maker je potřeba soubor uložit jako typ `Sešit Excelu s podporou maker` (.xlsm).

![Alt text](media/01-01-makra_ulozeni_makra.png)

## [Ukázka] "Zdravím, světe!"

```vb
Public Sub MojeMakro()
    'Kod makra
    MsgBox ("Zdravím, světe!")
End Sub
```
*Výsledek:*

![Výsledek příkladu](media/01-01-makra_vysledek_priklad.png)

# Funkce

Funkce ve VBA jsou bloky kódu, které vrací po svém provedení `Návratovou hodnotu`. Tímto primárním principem se odlišují od dříve použitých maker. Funkce nelze zavolat ze seznamu maker, ale volají se přímo z buňky Excelu (stejně jako funkce Excelu, například funkce `SUMA()`), nebo z jiné funkce/makra ve VBA Editoru.

![Alt text](media/01-03-funkce-diagram_funkce.png)

<p class="text-center"> Diagram funkce ve VBA</p>

Před použitím funkce v Excelu nebo kódu jiné funkce či makra je potřeba danou funkci prvně definovat. Funkce se definuje obdobně jako Makro. Funkce musí mít jedinečný název v rámci excelu, aby nedocházelo ke kolizím mezi názvy v rámci sešitu Excel. Toto zahrnuje i česky a anglicky definované základní funkce Excelu.

V uvedeném kódu je zobrazena standardní kostra funkce ve VBA. Definování funkce probíhá klíčovým slovem `Function`, které následuje názvem funkce a kulatými závorkami. Konec funkce je označen pomocí příkazu `End Function`.

```vb
'Ukázka kódu nadefinované funkce
Function <nazev_funkce>(<parametr_1>, <parametr_2>, ... , <parametr_n>)
    'Kód funkce

    'Návratová hodnota funkce
    <nazev_funkce> = <navratova_hodnota>
End Function
```

### Návratová hodnota

Každá funkce musí vrátit `Návratovou hodnotu`. Náratová hodnota funkce se vrátí pomocí přiřazení názvu funkce hodnotou nebo proměnnou, která obsahuje hodnotu. Ve většině případů se návratová hodnota přiřazuje až na konci funkce.

```vb
'Přiřazení návratové hodnoty funkce
<nazev_funkce> = <navratova_hodnota>
```

Pokud se ovšem funkce větví, může nastat případ, kdy se návratová hodnota může vrátit před dokončením všech řádků funkce. Pro předčasné ukončení funkce nebo makra použijte příkaz `Exit Function` nebo `Exit Sub`. Návratová hodnota se musí přiřadit před tímto příkazem, protože po provedení tohoto příkazu je funkce ukončena a hodnota se již nepřiřadí.

```vb
'Přiřazení návratové hodnoty funkce s předčasným ukončením funkce
<nazev_funkce> = <navratova_hodnota>
Exit Function
```

>   Při ukončování funkce je nutná obezřetnost, protože příkazy `End Function` a `Exit Function` nemají stejnou funkci. Příkaz `End Function` označuje konec kódu funkce, zatímco příkaz `Exit Function` ukončuje provádění funkce v daném bodě.

### Vstupní parametry funkce

Vstupní parametry funkce jsou proměnné s hodnotami, které funkce potřebuje k dosažení svého potřebného výsledku.. Hodnoty těchto parametrů zadává ten, kdo funkci volá. Funkce může mít *0* až *n* vstupních parametrů. Parametry funkcí potom v rámci funkce vystupují jako proměnné.

### Nepovinné vstupní parametry

Při psaní funkcí ve VBA se může stát, že je zapotřebí použít parametr, který není povinný pro uživatele funkce definovat, ale pokud jej uživatel má, může se do postupu zakomponovat. Když jej uživatel nemá, může se přiřadit výchozí hodnota. Tento parametr je nazýván jako `Volitený parametr`. V hlavičce funkce je tento parametr označen pomocí klíčového slova `Optional`.

```
'Ukázka kódu užití volitelného parametru, který má výchozí hodnotu číslo 0
Function funkceSVolitelnymParametrem(Optional parametr = 0)
    'Kód funkce
    funkceSVolitelnymParametrem = parametr
End Function
```

V příkladu funkce `funkceSVolitelnymParametrem` je parametr s názvem `parametr`. Funkce po zavolání vrátí hodnotu parametru. Když uživatel nevloží žádný parametr, funkce vrátí nulu. Pokud uživatel vloží jiný parametr, funkce mu vrátí tento parametr.

### [Ukázka] Vlastní funkce
*Zadání: * Vytvořte funkci s názvem "MojeFunkce". Funkce bude přijímat minimálně jeden parametr pojmenovaný "Jmeno" a volitelný druhý parametr s názvem "Prijmeni". Pokud volitelný parametr nebude zadán, vyplní se hodnotou "ve VBA". Výstupní hodnota této funkce bude kombinace Jmena a Prijmeni.

```vb
'Nadefinovana funkce s názvem "MojeFunkce"
Function MojeFunkce(Jmeno, Optional Prijmeni = "ve VBA")
    'Návratová hodnota funkce - Vrátí vložené jméno a příjmení, pokud bylo vloženo
    MojeFunkce = Jmeno & " " & Prijmeni
End Function
```

*Výsledek:*

### Předávácí mechanismus parametrů

- `ByVal` - 
- `ByRef` - 

Pokud je při deklaraci argumentu použito klíčové slovo ByVal, argument je z volající procedury předán jako zkopírovaná hodnota. Deklarovaná procedura pak nemodifikuje původní proměnnou mimo proceduru. 

Pokud nebyla zvolena indikace způsobu předávání proměnné nebo bylo při deklaraci použito klíčové slovo ByRef, argument je z volající procedury předán jako reference na jeho proměnnou. Deklarovaná procedura pak modifikuje i původní proměnnou mimo proceduru. 

### Proměnlivé množství parametrů

`ParamArray`

### Úroveň přístupu

Každá procedura má nadefinovanou úroveň přístupu, která určuje odkud z projektu může být k proceduře přístup. Pokud úroveň není určena pomocí modifikátoru přístupu, automaticky se přiřadí modifikátor `Public`. 

- `Public` - zveřejňuje proceduru do všech modulů.
- `Private` - umožňuje přístup k proceduře pouze v rámci modulu, kde je procedura nadefinovaná.
- `Friend`

### Atribut Static

Pokud se deklaruje procedura s atributem Static, lokální proměnné jsou zachovány ve stejném stavu mezi jednotlivými voláními procedury. Tato změna se netýká globálních proměnných, i když jsou v proceduře použity.


