V dnešním dílu si ukážeme některé často používané příkazy z VB, např. FOR..NEXT
,
IF..THEN
atd. V další kapitole se dozvíte, jak vytvářet procedury a funkce ve VB,
co to jsou události a vlastnosti a jak je používat.
V minulém dílu jsme chybně uvedli čísla kapitol. Tímto se omlouváme a pokud máte zájem, zkopírujte si opravenou verzi.
6. Základní příkazy
6.1. Příkazy cyklu
6.2. Větvení programu
6.3. Dialogy
7. Procedury, funkce, události
7.1. Procedury a funkce
7.2. Vlastnosti
7.3. Události
V této kapitole se vás budeme snažit naučit nejběžněji používané příkazy ve VB. Půjde o příkazy cyklu, tedy iterační příkazy a o příkazy, které umožňují větvení programu. Také, aby bylo naše programování alespoň trochu spojeno s okny, vám ukážeme dvě funkce pro použití dialogů.
Chcete-li vyzkoušet příklady uvedené v této kapitole, vytvořte nový projekt, a vložte kód příkladu do události Form_Load formuláře Form1. Pokud si už nevzpomínáte jak na to, klikněte dvakrát na Form1 a hned se Vám otevře kód této události. Příklad je potom proveden při startu aplikace. Můžete také na formulář vložit tlačítko (CommandButton) a vložit kód do jeho události Click. Kód se potom provede při jeho stisku.
VB má mnoho možností, jak vytvořit opakující se cyklus. Dalo by se říci, že ze všech jazyků má nejvíce způsobů pro jeho vytvoření (možná až příliš mnoho).
FOR .. NEXT
For pocitadlo = zacatek To konec [Step krok]
[příkazy]
[Exit For]
[příkazy]
Next [pocitadlo]
pocitadlo je proměnná, která nabývá hodnot od zacatek po konec. Nepovinná
část Step krok
určuje, o kolik se bude pocitadlo zvětšovat. Standardně
je to 1. Příkaz Exit For
způsobí ukončení cyklu a skok na řádek za příkazem
Next
.
Příklad:
Dim x As Long
'vypíše do okna Immediate hodnoty 1, 2, 3, ... , 9, 10
For x=1 to 10
Debug.Print x
Next x
'vypíše do okna Immediate hodnoty 0, 5, 10, 15, 20
For x=0 to 20 Step 5
Debug.Print x
Next x
'vypíše do okna Immediate hodnoty 1, 2, 3
For x=1 to 5
Debug.Print x
If x=3 Then Exit For
Next x
DO .. LOOP
VB nemá příkaz Until
. Cykly, které jsou v jiných jazycích dělány pomocí
Until
a While
, se ve VB dělají pomocí Do .. Loop
.
Do [{While | Until} podmínka]
[příkazy]
[Exit Do]
[příkazy]
Loop
nebo
Do
[příkazy]
[Exit Do]
[příkazy]
Loop [{While | Until} podmínka]
Vykonává příkazy uvedené mezi Do
a Loop
, dokud platí podmínka
uvedená za While
, tzn. její vyhodnocení je True, nebo, v případě
použití Until
, dokud není vyhodnocení podmínky True. While
nebo
Until
mohou být uvedeny buď za Do
nebo za Loop
. Obojí
zároveň není možné. Stejně jako u For .. Next
je i zde možno z cyklu
vyskočit, a to pomocí Exit Do
.
Příkaz lze také použít bez Until
i While
, takže cyklus
bude probíhat neustále. Ukončit půjde pouze pomocí Exit Do
.
Příklad:
Dim x As Long
'Do okna Immediate vypíše hodnoty 1, 2, 3, 4
x=1
Do While x<5
Debug.Print x
x=x+1
Loop
'Do okna Immediate vypíše hodnoty 1, 2, 3, 4
x=1
Do
Debug.Print x
x=x+1
Loop While x<5
WHILE .. WEND
Příkaz je zjednodušenou obdobou příkazu Do .. Loop
.
While podmínka
[příkazy]
Wend
Dokud platí podmínka, jsou vykonávány příkazy mezi While
a
Wend
.
Příklad:
'Vypíše do okna Immediate hodnoty 1, 2, 3, 4, 5
Dim x As Long
x=1
While x<=5
Debug.Print x
x=x+1
Wend
VB má dva základní příkazy pro větvení programu. Příkaz If
a příkaz
Select
. If
je lépe použít pro méně větví, Select
naopak
pro více.
IF .. THEN .. ELSE
If podmínka Then [příkazy] [Else příkazy]
nebo
If podmínka Then
[příkazy]
[ElseIf podmínka-n Then
[příkazy]
[Else
[příkazy]
End If
Příkaz vykoná ten blok programu, pro nějž je platná podmínka. podmínka-n v části
ElseIf
znamená, že tato část se může opakovat vícekrát. Ze syntaxe příkazu vyplývá,
je-li příkaz na jeden řádek, nemusí být ukončen End If
.
Příklad:
'V závislosti na hodnotě x vypíše do okna Immediate buď "prvni" nebo "druhy"
Dim x As Long
Randomize 'Inicializuje generátor náhodných čísel
x = Int((2 * Rnd) + 1) 'Generuje náhodné celé číslo od 1 do 2
If x=1 Then Debug.Print "prvni" Else Debug.Print "druhy"
nebo zapsáno přehledněji
If x=1 Then
Debug.Print "prvni"
Else
Debug.Print "druhy"
End If
'Stejně jako předchozí příklad zapíše do okna Immediate hodnotu závislou na hodnotě x
Dim x As Long
Randomize 'Inicializuje generátor náhodných čísel
x = Int((4 * Rnd) + 1) 'Generuje náhodné celé číslo od 1 do 4
If x=1 Then
Debug.Print "prvni"
ElseIf x=2 Then
Debug.Print "druhy"
ElseIf x=3 Then
Debug.Print "treti"
Else
Debug.Print "ctvrty"
End If
SELECT
Příkaz Select
vykonává prakticky stejnou funkci jako If
. Je lepší
ho použít v případě více variant testované podmínky a ve stejném případě také pro lepší čitelnost zdrojového kódu.
Select Case testovaný_výraz
[Case seznam1
[příkazy-1]]
[Case seznam2
[příkazy-2]]
.
.
[Case Else
[příkazy-n]]
End Select
testovaný_výraz je proměnná nebo výraz, na jehož základě se program dále rozděluje
na více bloků. seznam1, seznam2 atd. jsou možné varianty testované proměnné nebo
výrazu. Za každým slovem Case
může být jedna hodnota nebo více hodnot oddělených
čárkou. Můžete zadat také interval, např. 1 to 10
.
Pro lepší pochopení si opět pomůžeme příkladem.
'Stejně jako příklad pro IF zapíše do okna Immediate hodnotu závislou na hodnotě x
Dim x As Long
Randomize 'Inicializuje generátor náhodných čísel
x = Int((4 * Rnd) + 1) 'Generuje náhodné celé číslo od 1 do 4
Select Case x
Case 1
Debug.Print "prvni"
Case 2,3
Debug.Print "prostredni"
Case 4
Debug.Print "posledni"
End Select
'Vyhodnotí výraz a vypíše zprávu do okna Immediate. V tomto případě je vhodnější použít příkaz IF
Dim x As Long
Randomize 'Inicializuje generátor náhodných čísel
x = Int((10 * Rnd) + 1) 'Generuje náhodné celé číslo od 1 do 10
Select Case x < 5
Case True
Debug.Print "X je mensi nez 5"
Case False
Debug.Print "X je vetsi nebo rovno 5"
End Select
Do této kapitoly by se daly zařadit ještě další příkazy které existují ve VB. Nemá příliš
velký význam uvádět jejich syntaxi a jak se používají, to můžete zjistit z nápovědy. Abyste
alespoň věděli kde hledat, jsou to tyto příkazy: Choose
,
IIf
a Switch
.
Funkce MsgBox
Tato funkce slouží pro zobrazení dialogu s textem a tlačítky které si vyberete.
Vrací hodnotu typu Integer
, která indikuje, které tlačítko uživatel
stiskl. Funkce může být volána i jako procedura.
MsgBox(text[, tlačítka] [, titulek] [, nápověda, kontext])
text
je zpráva, která se zobrazí přímo v okně.
tlačítka
je číslo, které je součtem všech hodnot, určujících zobrazená
tlačítka a ikony. Zde je nejlépší použít konstanty.
titulek
je zpráva, která se zobrazí v záhlaví okna. Pokud neuvedete
tento parametr, zobrazí se v titulku název projektu.
nápověda
je cesta k souboru nápovědy.
kontext
je číslo, které specifikuje část nápovědy, která se má
zobrazit.
Příklad:
'Ukáže dialog s tlačítkem OK (standardně) a textem "Moje zpráva"
MsgBox "Moje zpráva", , "Zpráva"
'Ukáže dialog s tlačítkem OK, s ikonou I v kolečku
MsgBox "Moje zpráva", vbInformation
'Zobrazí dialog s tlačítky Ano a Ne a ikonou otazníku v kolečku
'Pokud uživatel zvolí Ano, ukončí se program
If MsgBox("Ukončit program?", vbQuestion + vbYesNo, "Dotaz") = vbYes Then End
'Stejný příklad jako výše, pouze lépe čitelný
Dim i As Integer
i=MsgBox("Ukončit program?", vbQuestion + vbYesNo, "Dotaz")
If i=vbYes Then
End
End If
Funkce InputBox
Funkce zobrazí dialog s textovým polem, a čeká na uživatele. Pokud stiskne OK, vrací řetězec, který je obsahem textového pole, tedy toho, co uživatel napsal, stiskne-li Cancel, je navrácená hodnota rovna "", prázdný řetězec.
InputBox(zpráva[, titulek] [, default] [, x] [, y] [, nápověda, kontext])
Není třeba vysvětlovat parametry, které jsou stejné s funkcí MsgBox
. Další
parametry znamenají:
default
je hodnota, která je předvyplněna v textovém poli.
x
je hodnota na ose x obrazovky, kam bude umístěn levý horní roh dialogu.
y
je stejné jako x, pouze na ose y.
Příklad:
'Zobrazí výzvu pro vložení jména
Dim jmeno As String
jmeno=InputBox("Vložte jméno", "Jméno")
If jmeno="" Then
MsgBox "Nebylo vloženo žádné jméno"
Else
MsgBox jmeno
End If
'Zobrazí výzvu pro vložení data s nastaveným dnešním datem na pozici x=10, y=20
'Dnešní datum vrací funkce Now
Dim datum As String 'pouze pro názornost, lépe samozřejmě použít typ date
datum=InputBox("Vložte datum", "Datum", Now, 10, 20)
7. Procedury, funkce, události
Vzhledem k tomu, že VB je poměrně členitý jazyk, je název této kapitoly poměrně zavádějící. V kapitole bude zabráno trochu širší spektrum. Správný název, i když ne až tak srozumitelný by mohl znít Způsoby členění kódu a jejich použití.
K čemu slouží procedury a funkce by mělo být každému čtenáři tohoto seriálu jasné. Proto pouze krátkou rekapitulaci. Procedury a funkce slouží pro strukturované rozdělení programu na menší logické části. Tyto jsou vhodné především pro takové části programu, které se často opakují nebo jsou používány ruznými částmi programu, případně i jinými aplikacemi. Rozdíl mezi funkcemi a procedurami je jednodduchý, funkce vrací hodnotu a procedura ne.
Procedury a funkce můžeme ve VB dělit podle způsobu a místa použití (nebudeme zde brát příliš zřetel na to, kdy se spíše jedná o klasickou proceduru z pohledu strukturovaného programování a kdy jde již o metodu z pohledu OOP).
7.1. Procedury a funkceVýskyt:Form, MDIForm, Module, ClassModule, User Control, Property Page
Funkce:
[Private|Public] [Static] Function jméno_funkce (argumenty) [As type]
[Exit Function]
End Function
Procedura:
[Private|Public] [Static] Sub jméno_funkce (argumenty)
[Exit Sub]
End Sub
Klauzule Private
a Public
stejně jako u proměnných určují zdali jsou na úrovni daného modulu (nechápejte zde modul jako Module, ale pouze jako volné označení rámce vymezujícího kód v rámci nějakého prvku jako Form, PropertyPage nebo i Module.) privátní či veřejné. To znamená, že určují, zdali budou přístupné z vnějšku daného modulu.
V další části se nachází slovo Static
. V případě, že se objeví v deklaraci, znamená to, že všechny proměnné v ní deklarované jsou Static
, čímž si uchovávají svou hodnotu i v době, kdy není daná funkce či procedura prováděna.
Po indikátoru, který určuje zdali se jedná o funkci či proceduru, následuje jméno funkce. Za tímto jsou argumenty, které se mezi sebou oddělují čárkou.
[Optional] [ByRef|ByVal] jméno_argumentu [AS datový_typ]
Klauzule Optional
určuje zdali je parametr nepovinný. Je li použito nepovinných parametrů, mohou být v deklaraci uvedeny až po posledním povinném argumentu. Testování, zdali byl parametr zadán, je možné provádět funkcí IsMissing()
, která vrací hodnotu True, jestliže parametr nebyl zadán. Slova ByRef
a ByVal
stanovují jakým způsobem bude parametr předán. V prvním případě je argument předán odkazem, což znamená, že je předán odkaz do paměti. Díky tomu je možné, aby funkce nebo procedura změnila její hodnotu. Přesto, že tento způsob je ve VB standardní, pro optimalizaci kódu je vhodnější zvolit druhou možnost. V tomto případě je předávána pouze kopie, takže při změně hodnoty argumentu se tato změna projeví jen na této kopii. Stejně jako u každé proměnné se definuje typ i u argumentů. V případě, že je vynechán, je automaticky přiřazen typ Variant. Stejně tomu je i u funkcí, kde se narozdíl od procedur definuje i typ návratové hodnoty.
ParamArray jméno_pole_argumentů()
Jestliže je počet argumentů pohyblivý, a použití klauzule Optional
by bylo značně nepraktické, je možno použít pole parametrů. Tento typ parametrů se deklaruje slovem ParamArray
. Typ jeho prvků je vždy a jedině Variant. Pro jeho použití navíc platí pravidla, že může být uveden až jako poslední argument, a předcházet mu mohou jedině parametry povinné. Když pak budeme chtít ve funkci nebo proceduře procházet jednotlivé prvky pole, je nejlepší a nejrychlejší metoda, znázorněná v příkladu.
Public Function Suma(ParamArray pole()) As Long
Dim Soucet As Long
For Each prvek In pole
Soucet = Soucet + prvek
Next
Suma = Soucet
End Function
Nedílnou součástí této kapitoly je i volání procedur a funkcí z kódu. VB zde nabízí několik možností. První dvě možnosti platí pro funkce, kde není důležitá návratová hodnota a pro procedury.
jméno_funkce první_argument, druhý argument
Call jméno_funkce(první_argument, druhý argument)
U funkcí, kde je třeba získat návratovou hodnotu se použije jednoduché přiřazení jako u proměnných. Je li návratovým typem objekt nesmíme zapomenout na klíčové slovo Set
.
jméno_proměnné = jméno_funkce(první_argument, druhý argument)
Set jméno_proměnné = jméno_funkce(první_argument, druhý argument)
Poslední dvě možnosti se týkájí způsobu zadávání nepovinných parametrů. V případě, že chceme některý z prostředních parametrů vynechat, může to vypadat takto (obě uvedená použití jsou ekvivalentní).
Public Function Suma3(Optional a As Long, Optional b As Long, Optional c As Long) As Long
...
Print Suma3(22,,6)
Print Suma3(22,c:=6)
Z uvedeného je zřetelné, že buď hodnotu parametru prostě nenapíšeme nebo přiřadíme identifikátoru argumentu pomocí ":=
" hodnotu.
Výskyt:Form, MDIForm, Module, ClassModule, User Control, Property Page
Už v minulém díle jsme se zmínili o vlastnostech objektu. Tato možnost velice zpřehledňuje kód. Kdyby jsme měli například nastavení barvy realizovat pomocí metod (pro naši věc ji můžeme nazvat i funkcí), mohlo by to vypadat asi takto.
x=Objekt.GetBarva()
Objekt.SetBarva(x)
Jelikož se navenek jeví jako proměnné příslušející nějakému objektu, je zápis mnohem přehlednější. Posuďte sami, o co lépe vypadá uvedený kód napsaný při využití vlastností.
x=Objekt.Barva
Objekt.Barva=x
Ačkoli to tak nevypadá, nevyhneme se rozdělení kódu vlastnosti na dvě části (ve výjmečných případech dokonce na tři). První část se stará o zjištění hodnoty vlastnosti a druhá o její nastavení. Ani zde nesmíme zapomenout na případy, kdy je vlastnost typu objekt a nastavovat a psát vlastnosti s ohledem na to.
[Private|Public] [Static] Property Get jmeno_vlastnosti(1,..., n) As typ
[Private|Public] [Static] Property Let jmeno_vlastnosti(1,..., n, n+1)
[Private|Public] [Static] Property Set jmeno_vlastnosti(1,..., n, n+1)
Co se týče deklarace vlastností, ničím zásadním se od procedur a funkcí neliší, pouze identifikátor je Property Get|Let|Set
. Dalším rysem je rozdíl v počtu argumentů mezi částmi, kde se hodnota zjišťuje a kde se nastavuje. U Property Get
je n parametrů vlastnosti a její návratový typ musí být shodný s typem parametru n+1 u Property Let|Set
. Tento poslední parametr se narozdíl od jiných nachází za rovnítkem a zprostředkovává předání hodnoty pro kód. Pro snadnější pochopení uvedu kód, na kterém uvidíte způsob použití vlastností.
'První část kódu je modul třídy s názvem Pole
Private mMax as Long 'Maximální počet prvků v poli
Private mPoleVar() As Variant 'Dynamické pole pro uložení prvků libovolného typu
'První vlastnost slouží pro určení počtu prvků pole.
Public Property Get Maximum() As Long
Maximum=mMax
End Property
Public Property Let Maximum(NoveMax As Long)
mMax=NoveMax
Redim Preserve mPoleVar(1 to mMax) 'Změna velikosti pole
End Property
'Tato vlastnost se stará o ukládání a získávání prvků pole. Jelikož může jít o proměnnou jednoduchého typu nebo o objekt má jak část Let tak i Set.
Public Property Get PoleVariant(Index As Long) As Variant
If Index<=mMax Then PoleVariant=mPoleVar(Index)
End Property
Public Property Let PoleVariant(Index As Long, NovyPrvek As Variant)
If Index<=mMax Then mPoleVar(Index)=NovyPrvek
End Property
Public Property Set PoleVariant(Index As Long, NovyPrvek As Variant)
If Index<=mMax Then Set mPoleVar(Index)=NovyPrvek
End Property
'Tato část kódu se nachází například v modulu formuláře
...
Dim i As Long
Dim Pokus As New Pole
Pokus.Maximum=10
Pokus.PoleVariant(1) = "Hello, world!"
...
Pokus.PoleVariant(10) = 666
For i=1 To Pokus.Maximum 'Prochází prvky vlastnosti PoleVariant
Print Typename(Pokus.PoleVariant(i)) 'Tiskne typ proměnné
Next i
...
Události dávají objektům schopnost, která jim umožňuje přenechat reakci na určitou akci či změnu stavu (může přicházet od uživatele, systému nebo od jiných objektů) na programátorovi. Ten může obsloužit událost libovolným způsobem. Samozřejmě nemusí na událost reagovat vůbec. Toto je znamenitý způsob, jak spolu mohou spolupracovat a reagovat na sebe nezávislé objekty.
Součástí většiny ActiveX prvků ve VB jsou události, které vám umožní spojit s nimi kód a tím je také obsloužit. Ve vlastních objektech můžete vytvářet i vlastní události a to tak, že buď "přesměrujete" události jiných objektů a nebo uděláte svoji, která se třeba vyvolá při změně stavu.
Pro příklad přesměrování události vytvořte nový projekt, přidejte ActiveX Control (menu Project | Add User Control) a na něj umístíte dvě tlačítka. První se bude jmenovatcmdOK
a druhé cmdStorno
.
Do vlastnosti Caption zapíšete u prvního "OK" a u druhého "Storno". Hotový prvek vložíte na formulář,
pojmenujete ho jako Pokus
a doplníte následující kód. Poté aplikaci můžete spustit (prvek přidáte
na formulář jeho vybráním v okně nástrojů a standardním umístěním někde na formulář).
'Tato část kódu se nachází v modulu vytvořeného ActiveX Control
'Deklarace vlastních událostí
Event OK()
Event Storno()
Private Sub cmdOK_Click()
RaiseEvent OK() 'Vyvolá událost OK
End Sub
Private Sub cmdStorno_Click()
RaiseEvent Storno() 'Vyvolá událost Strono
End Sub
'Následující část kódu se nachází v modulu formuláře
Private Sub Pokus_OK()
MsgBox "Uživatel zmáčkl OK."
End Sub
Private Sub Pokus_Storno()
MsgBox "Uživatel zmáčkl Storno."
End Sub
Syntaxe deklarace události vypadá takto. Dále je uvedena hlavička pro obsloužení události.
[Public] Event jméno_události [(argumenty)]
[Private] Sub názevobjektu_názevudálosti [(argumenty)]
Podtržítko u hlavičky události je nutné pro oddělení názvu objektu a události. Jinak platí
stejná pravidla jako u procedur a funkcí.
Určitě jste si všimli, že když vytvoříte třídu a použijete ji třeba v modulu formuláře, nevidíte v
horních rozbalovacích nabídkách ani její název ani vytvořené události. V tomto případě je třeba v deklaraci
instance uvést klíčové slovo WithEvents
. To způsobí, že se události objeví v horních
nabídkách a je možno s těmito událostmi pracovat.
Pro lepší pochopení uvedu příklad. Po jeho vytvoření se můžete podívat, zdali se v nabídkách
objevila instance třídy a její události. Vytvořte třídu a nazvěte ji "Zasobnik". Na formulář vložte
tlačítko se jménem cmdRun
a do vlastnosti caption vložte text "Spusť". Dála vložte
na formulář ListBox a nazvěte jej lstEvents
. Poté přidejte do projektu následující
kód.
'Tento kód patří do třídy Zasobnik
Private zas(1 To 10) As Long 'Pole pro zásobník
Private pocet As Long 'Pocet hodnot v zásobníku
'Událost nastávající při přetečení zásobníku
Event Pretekl()
'Událost nastávající při nemožnosti odebrat hodnotu z prázdného zásobníku
Event Prazdny()
'Událost nastávající při vložení hodnoty
Event Vlozeno(hodnota As Long)
'Událost nastávající při odebrání hodnoty
Event Odebrano(hodnota As Long)
Public Sub Vloz(hodnota As Long)
If pocet = 10 then
RaiseEvent Pretekl
Else
pocet = pocet + 1
zas(pocet) = hodnota
RaiseEvent Vlozeno(hodnota)
End If
End Sub
Public Function Odeber() As Long
If pocet = 0 then
RaiseEvent Prazdny
Else
Odeber = zas(pocet)
RaiseEvent Odebrano(zas(pocet))
pocet = pocet - 1
End If
End Sub
'Tento kód patří do modulu formuláře
'Deklarace instance třídy včetně událostí
Private WithEvents z As Zasobnik
Private Sub Form_Load()
Set z = New Zasobnik
End Sub
Private Sub cmdRun_Click()
Dim i As Long
Randomize
'Naplnění zásobníku
For i = 1 To 11
z.Vloz Clng(Rnd*1000)
Next
'Vyprázdnění zásobníku
For i = 1 To 11
z.Odeber
Next
End Sub
Private Sub z_Odebrano(hodnota As Long)
lstEvents.AddItem "Byla odebrána tato hodnota:" & hodnota
End Sub
Private Sub z_Prazdny()
lstEvents.AddItem "Zásobník je prázdný. Nelze odebrat hodnotu."
End Sub
Private Sub z_Pretekl()
lstEvents.AddItem "Zásobník přetekl. Nelze přidat hodnotu."
End Sub
Private Sub z_Vlozeno(hodnota As Long)
lstEvents.AddItem "Byla vložena tato hodnota:" & hodnota
End Sub