VBA – 5# Lekce – Debug proces

Ještě než se pustíme do slibovaného příkazu „Select Case“ chtěl bych Vám ukázat tzv. Debug v MS Excel. Je to nástroj, který prochází krok po kroku námi napsaný kód. Je to dobré, pokud máme delší kód a někde máme chybu. Nebo také k lepšímu pochopení chodu programu.

Debug

Tak a teď jak na to. Nejdříve si spustíme námi napsaný prográmek třeba z minulé lekce s podmínkami IF. Jak jsme již zvyklí, přepneme se do vývojového prostředí. Debug pustíme tlačítkem F8 nebo také v záložce Debug -> položka Step Into. Aby vše fungovalo, musíme mít kurzor nakliknutý v jakékoliv části námi napsaného programu. Postupným mačkáním F8 debug prochází jednotlivé řádky našeho kódu aktuálně „projížděný“ řádek je podbarven žlutě. Pokud potřebujeme vědět, jaké data se nám aktuálně načetly do proměnné, stačí najet kurzorem na danou proměnnou a zobrazí se nám, co obsahuje. Toto platí pro všechny proměnné v kódu ne jenom na tu podbarvenou.

Závěr

S tímto nástrojem jsem Vás chtěl seznámit zejména kvůli pochopení chodu programu. Aby jste viděli, co se kam kdy načítá a měli tak větší kontakt s napsaným kódem a uměli si vše líp představit. Závěrem si dáme úkol projít všechny námi doposud napsané programy tímto postupem a znovu se zamyslet jak program funguje zejména pak programy z minulé lekce kde jsme se poprvé setkali s IF.

VBA – 4# Lekce – Podmínky IF

V této lekci se podíváme na větvení programu pomoci podmínek IF (do češtiny přeloženo KDYŽ). Podmínky jsou nedílnou součástí každého programu pomáhají nám ošetřovat různé možnosti na základě podmínek. Pomocí těchto příkazu jsme potom schopni větvit program v závislosti na vstupních okolnostech.

Obecná syntaxe podmínky

Syntaxe podmínek if vypadá takto.

IF podmínka Then

Blok příkazů VBA

ElseIf

Blok příkazů

End If

Tento příklad ukazuje jenom samostatný blok podmínek a po zkopírování vám nebude fungovat. Kompletní příklady si ukážeme později v této lekci.

If volba = "a" Then
MsgBox "ahoj", vbOKOnly + vbInformation, "Zpráva" 
ElseIf volba = "b" Then MsgBox "nazdar", vbOKOnly + vbInformation, "Zpráva"
Else MsgBox "končím program", vbOKOnly + vbInformation, "Zpráva"
end
End If

Teď si tento kód rozebereme : První řádek by se dal přečíst takto. Pokud (if)  jakákoliv proměnná ( volba) se rovná ( = )  “a“  potom vykonej (then). Pokud tato podmínka nenastane program přeskočí řádky pod ní a zastaví se u řádku elseif . Elseif je obdoba if ale v podmínce ho můžeme využít kolikrát chceme kdežto if se dává jenom na začátek dané podmínky. Z toho vyplývá že třetí řádek se čte úplně stejně jako první. Else značí něco jako „cokoliv jiného“. Takže pokud se volba bude rovnat cokoliv jiného než „a“ nebo „b“ program vykoná řádky pod else. V Tomto případe vykoná příkaz end, který ukončí celý program. Podmínky nemusí vždy obsahovat else nebo elseif. Každý podmínkový blok ale musí být ukončen řádkem End If. A teď již pár slibovaných kompletních příkladů na procvičení podmínek.

Příklady


Sub cisla()
Dim Cislo As Double
Dim Vysledek As String
Cislo = InputBox("zadej číslo")

If Cislo > 0 Then
        Vysledek = "kadné"
    ElseIf Cislo < 0 Then
        Vysledek = "záporné"
    Else  Vysledek = "nula"
End If
MsgBox "Číslo je " + Vysledek
End Sub

Sub porovnání()
Dim a As Double
Dim b As String
a = InputBox("zadej číslo a")
b = InputBox("zadej číslo b")

If a > b Then
      Vysledek = "a je vetší než b"
   ElseIf b > a Then
      Vysledek = "b je vetší než a"
   Else Vysledek = "a = b"
End If

MsgBox Vysledek
End Sub

U tohoto příkladu je v podmínce použitý textový řetězec proto podmínka vypadá if heslo=“vba“(každý textový řetězec se ohraničuje uvozovkami) kdyby to nebylo v uvozovkách program by to bral jako proměnnou. Zkuste si dát zadat do inputboxu textový řetězec vba a potom cokoliv jiného.


Sub heslo()
Dim heslo As String
heslo = InputBox("zadej heslo")
If heslo = "vba" Then
        MsgBox "Zobrazení přísně tajné zrávy :D", vbOKOnly + vbInformation, "TOP sectret"
    Else
        MsgBox "spatně zadané heslo", vbOKOnly + vbInformation, "Smůla"
End If
End Sub

Toto je jenom obdoba předešlého příkladu. Chybí zde příkaz else. Sami se podívejte na rozdíl mezi oběma příklady


Sub heslo_update()
Dim heslo As String
heslo = InputBox("zadej heslo")
If heslo = "vba" Then
        MsgBox "Zobrazení přísně tajné zrávy :D", vbOKOnly + vbInformation, "TOP sectret"
End If
End Sub

Závěr

Tím naše lekce končí podmínky jsou velmi důležitou součástí programování takže jestli něčemu nerozumíte klidně se ptejte v komentářích pod článkem. V příští lekci se podíváme na další možnosti dělení programu pomocí příkazu Select Case.

#3 Operátory a operandy

V další lekci programování v C se podíváme pouze na všechny možné operátory, které v jazyce C existují. Na některých z nich si ukážeme několik příkladů.

Dodatek k deklaraci proměnné

V předchozí lekci jsme se zapomněli zmínit o tom, že jméno funkce nemůže obsahovat jakékoliv slovo. V jako každém jiném programovacím jazyce i v C existují určitá rezervovaná slova, která nelze použít jako jméno pro proměnné, či názvy vlastních funkcí. Zde je výčet všech těchto rezervovaných slov:

auto break case char const
continue default do double else
enum extern float for goto
if inline int long register
return short signed sizeof static
struct switch typedef union unsigned
void volatile while _Bool _Complex

Příklad:

int return; // tento nazev nelze pouzit
int Return; // tento nazev je mozne pouzit

Tři pojmy na úvod

  • Výraz = posloupnost operandů a operátorů
  • Operand = proměnná či hodnota
  • Operátor = určuje druh operace, která bude ve výrazu provedena nad operandy

Operátory

V jazyce C existuje 15 prioritních skupin, do kterých se jednotlivé operátory řadí. Směr sdružení nebo také asociativita může být buď zleva nebo zprava. Operátory dělíme do skupin podle toho, kolik potřebují operandů.

Unární operátory

OPERÁTOR POPIS PRIORITA ASOCIATIVITA
+ hodnota operandu se nemění 2 zprava
změní hodnotu operandu na z kladné na zápornou a opačně 2 zprava
++ inkrementace 2 zprava
dekrementace 2 zprava
! logická negace 2 zprava
~ změna bitu z 0 na 1 a opačně 2 zprava
& reference 2 zprava
* dereference 2 zprava
(datovy_typ) přetypování operandu 2 zprava
sizeof počet bytů které operand zabírá v paměti 2 zprava

Na příkladu si ukážeme využití operátoru přetypování:

#include <stdio.h>

int main(void)
{
    int x = 5, y = 2;
    float vysledek;

    vysledek = x / y;
    printf("%.1f\n", vysledek); //presnost na 1 desetinne misto
    /*
    pokud delime celociselne promenne vysledek take bude
    celociselny a tim ze jej priradime do realneho typu
    tak se vypise i s desetinnou carkou ale vysledek bude
    vypocitan spatne nebo spise jinak nez jsme chteli
    */

    vysledek = (float)x / y;
    printf("%.1f\n", vysledek);

    vysledek = x / (float)y;
    printf("%.1f\n", vysledek);

    vysledek = (float)x / (float)y;
    printf("%.1f\n", vysledek);
    /*
    pokud alespon jeden operand x nebo y pretypujeme na realny tak vysledek bude spravny  
    */
    
    return 0;
}

Binární operátory

Aritmetické

OPERÁTOR POPIS PRIORITA ASOCIATIVITA
* násobení 3 zleva
/ dělení 3 zleva
% modulo (zbytek po dělení) 3 zleva
+ sčítání 4 zleva
odčítání 4 zleva

Můžeme si také ukázat, jak vlastně funguje priorita operátorů. Použijeme stejný kód jako u předešlého příkladu.

#include <stdio.h>

int main(void)
{
    int x = 5, y = 2;
    float vysledek;

    vysledek = (float)x / y;
    printf("%.1f\n", vysledek);
    /* vime ze pretypovani ma vetsi prioritu nez deleni
      takze se tento vyraz vyhodnoti spravne, pokud
      bychom ale vynutili aby se deleni provedlo nejdrive
      tak uz vysledek bude jiny
      */

    vysledek = (float)(x / y); //vynuceni priority pomoci zavorek
    printf("%.1f\n", vysledek); //chybny vysledek, vidime ze priorita operatoru je dulezita

    return 0;
}

Přiřazovací

OPERÁTOR PRIORITA ASOCIATIVITA
= 14 zprava
+= 14 zprava
-= 14 zprava
*= 14 zprava
/= 14 zprava
%= 14 zprava
<<= 14 zprava
>>= 14 zprava
&= 14 zprava
^= 14 zprava
|= 14 zprava

U těchto operátoru dojde nejprve k provedení operace, která se nachází před (=) a následně se tento výpočet přiřadí do hodnoty která je vlevo.

Příklad:

int cislo1 = 11;
int cislo2 = 2;
cislo1 %= cislo2; //zmena promennych: cislo1 = 1 a cislo2 = 2 (zustane stejne)

Porovnávací

OPERÁTOR POPIS PRIORITA ASOCIATIVITA
< menší než 6 zleva
> větší než 6 zleva
<= menší nebo rovno než 6 zleva
>= větší nebo rovno než 6 zleva
== rovnost 7 zleva
!= nerovnost 7 zleva

Logické

OPERÁTOR POPIS PRIORITA ASOCIATIVITA
<< bitový posun vlevo 5 zleva
>> bitový posun vpravo 5 zleva
& logický součet po bitech 8 zleva
^ nonekvivalence po bitech 9 zleva
| logický součin po bitech 10 zleva
&& logický součet 11 zleva
|| logický součin 12 zleva

Ternární operátory

Existuje pouze jeden operátor, který potřebuje 3 operandy a tím je Podmíněný výraz. Sdružuje zprava a priorita je 13. Zápis vypadá takto:

podminka ? hodnota1 : hodnota2

Nejprve se vyhodnotí podmínka, pokud je splněna (hodnota <> 0), výsledkem bude hodnota1, při nesplněné podmínce (hodnota = 0), výsledkem bude hodnota2.

Ostatní operátory

OPERÁTOR POPIS PRIORITA ASOCIATIVITA
() zavolání funkce 1 zleva
[] výběr hodnoty z pole 1 zleva
. výběr prvku ze struktury 1 zleva
-> výběr prvku ze struktury zadané pomocí ukazatele 1 zleva
, jednotné provedení výrazů 15 zleva

Operátor (,) čárka slouží k jednotnému provedení výrazů. Občas potřebujeme operaci kde je více výrazů, ale syntaxe dovoluje pouze jeden výraz. Operátor čárka tyto jednotlivé výrazy odděluje a v podstatě je sloučí do jednoho. Používá se například u cyklů.

Operandy

  • Proměnná – známe již z předchozí lekce
  • Konstanta – definují se pomocí direktivy preprocesoru #define nebo lze použít klíčové slovo const při deklaraci proměnné
  • Výpočet funkce – samotné zavolání funkce je možné použít jako operand, za podmínky, že funkce nemá návratový typ void

Vysvětlíme si používání konstantních operandů:

Konstanta pomocí  #define

  • obecný tvar = #define NAZEV hodnota
  • podle konvence by název konstanty měl být velkými písmeny
#include <stdio.h>
#define PI 3.14

int main(void)
{
    int polomer = 10;
    float objem;

    objem = 4.0/3.0 * PI * polomer;
    printf("Objem koule o polomeru %d je %.2f\n", polomer, objem);

    return 0;
}

Pomocí direktivy #define se dají vytvářet i makra:

#include <stdio.h>
#define PLUS(a,b) ((a)+(b))

int main(void)
{
    printf("Soucet = %d\n", PLUS(1,2));
    return 0;
}

Konstanta pomocí const

Pokud použijeme klíčové slovo const, tak jediná možnost jak proměnnou inicializovat je ihned při její deklaraci, pozdější inicializace není možná.

#include <stdio.h>

int main(void)
{
    const int cislo = 10;
    cislo = 15; //error
    printf("%d\n", cislo);
    return 0;
}

Program neprojde překladem, kvůli chybnému přiřazení do konstantní proměnné na řádku 6

main.c:6: error: assignment of read-only variable 'cislo'

To by bylo vše k této lekci o operátorech a operandech. Příště se naučíme pracovat s podmíněnými výrazy a cykly.