cool web a perfektni rs- Doporucuji

Sunday, April 29, 2007

Procházení podmnožiny ovládacích prvků na formuláři

Když máte na formuláři všelijaké ovládací prvky, potřebujete často projít v cyklu nějakou jejich podmnožinu
(například nastavit nějaké vlastnosti všech ovládacích prvků typu popisek (Label), nastavit písmo všech
přístupných ovládacích prvků na kurzívu apod.). V naší konkrétní úloze by se nám cyklus hodil pro naplnění
popisků vylosovanými čísly i pro otestování, zda uživatel vyhrál. (Nebereme přitom v úvahu výkonnost – tj.
neřešíme problém, zda je některý postup rychlejší než jiný).
VB6. Dříve poskytoval Visual Basic k tomuto účelu řadu technik a každý programátor měl
v oblibě nějakou jinou. V následujícím výčtu uvedu alespoň některé, protože jsou možná někteří
z vás na nějakou z nich zvyklí a budete si muset odvyknout.

Labels:

Thursday, April 26, 2007

O konstrukci If

ve spojení s logickými operátory se zde rozepisuji podrobněji proto, že opět (jako skoro
všude jinde) došlo ve Visual Basic.NET k významné změně. Při logických operátorech se totiž používá tzv.
zkrácené vyhodnocování. V podstatě jde o to, že jakmile je jasné, že návratová hodnota podmínky bude True,
další výrazy se už nevyhodnocují. Snad bude srozumitelnější jednoduchý příklad.
Ve Visual Basicu 6.0 skončí kód:
Dim a, b As Integer
a = 4
b = 0
If a = 4 Or a / b = 1 Then
MsgBox "prošlo"
End If
chybou při běhu 11 (dělení nulou), kdežto ve Visual Basic.NET kód projde (musíte ovšem řádek výpisu
zapsat v jiném tvaru, například takto:
messagebox.Show("prošlo")
Informace o vypisování zpráv uživateli v dialogovém okně viz oddíl „Přidání formuláře parametrů“.

Labels:

Sunday, April 22, 2007

Zda uživatel vyhrál – provizorní kritéria

Kritéria, která určí, zda uživatel vyhrál, stanovíme pochopitelně my. Přirozeně bychom měli ohlídat, abychom
nezkrachovali. Otázkou stanovení finanční výše výher vzhledem k vsazené částce se budeme zabývat
později. Teď si zvolíme nějaké velmi jednoduché kritérium, abychom mohli prototyp aplikace rychle otestovat.
Jakmile máme vygenerovaná čísla, můžete do událostní procedury Click tlačítka s nápisem Roztočit přidat
kód, který zjistí, zda uživatel vyhrál (například první číslo je 1 nebo je druhé 2 nebo je třetí 3). Jestliže
vyhrál, zobrazíme obrázek a pípneme. Náš test může proto vypadat takto:
If lblCislo1.Text = "1" Or _
lblCislo2.Text = "2" Or _
lblCislo3.Text = "3" Then
picVýhra.Visible = True
End If
Také pro tuto úlohu se nabízí zpracování v nějakém cyklu. Rozbor některých postupů pro zpracování
množiny ovládacích prvků v cyklu viz oddíl „Procházení podmnožiny ovládacích prvků na formuláři“.
Jak už jsem se zmínil, když začnete ve Visual Basicu pást nějaký kód, editor kódu při tom asistuje
a nabízí různé pomůcky (jednu z nich jste viděli už výše v souvislosti s příkazem Option Strict v oddílu
„Vylosování čísel“.
Další šikovnou pomůckou – zvláště když chcete nahradit jednu variantu kódu jinou, ale nejste si jisti, zda
se nebudete později chtít vrátit k té původní – jsou tlačítka Comment Block a Uncomment Block na panelu nástrojů
Edit. Umožňují pohodlně převádět vybrané řádky kódu na komentář, resp. komentáře zase zpětně převádět
na kód (při jednom klepnutí se přidá, resp. odstraní ve vybraných řádcích jeden uvozující apostrof).
Jakmile napíšete název objektu a tečku, rozvine editor kódu (za předpokladu, že jste pomůcky nevypnuli)
seznam vlastností a metod tohoto objektu (viz okénko nad kódem na levé straně obrázku na příští straně).
Vpravo dole připomínám na obrázku opět situaci, kdy si už nemůžete dovolit implicitní konverzi (číslici musíte
zapsat jako řetězec, abyste sjednotili datové typy levé a pravé strany).

Labels:

Saturday, April 21, 2007

Pomocné výpisy mezivýsledků

Když ve Visual Basicu testujete nějaké algoritmy, postupy, funkce apod., běžně potřebujete někam si vypisovat
mezivýsledky. Jednou ze základních možností je dialogové okno zpráv, s nimiž se seznámíte později,
v procedurách uvedených v oddílu „Formulář parametrů“.
Druhým běžným způsobem je, že si mezivýsledky a další pomocné výstupy zapíšete do výstupního okna
(Output). K tomuto účelu se používá několik metod třídy Debug z pojmenovaného prostoru System.
Diagnostics. Například, chcete-li si pro kontrolu vypsat horní mez pole Trojice a jeho aktuální
hodnoty, dá se to udělat takto:
Dim i as Integer
System.Diagnostics.Debug.WriteLine(CStr(Ubound(Trojice)))
System.Diagnostics.Debug.Write("Vylosované hodnoty: ")
For i = 0 To Ubound(Trojice)
System.Diagnostics.Debug.Write(CStr(Trojice(i)) & Space(1))
Next
Výpis bude vypadat takto:
2
Vylosované hodnoty: 0 8 5
Další dvě podobné metody se jmenují WriteLineIf a WriteIf a umožňují podmínit výpisy informací
nějakými kritérii.
VB6. Tyto metody pojmenovaného prostoru System.Diagnoastics nahrazují dříve
používanou metodu Print globálního objektu Debug (a metodu Assert nahrazují metody
Assert a Fail).

Labels:

Wednesday, April 18, 2007

Námět na procvičování.

Výše uvedené způsoby losování číslic jsem použil hlavně proto, že se na poměrně
jednoduché úloze dalo upozornit na množství rozdílů mezi VB6 a VB.NET. Vyzkoušejte si nějaký modernější
způsob. Například, pojnenovaný prostor System poskytuje generátor pseudo náhodných čísel
prostřednictvím třídy Random. Definujete-li si proměnnou Dim náhčíslo As New Random(), můžete pak
snadno generovat pseudonáhodná čísla metodou Next. (Jedna z jejích variant umožňuje specifikovat interval,
z něhož chcete čísla získávat). Třída zahrnuje i jiné zajímavé metody, například možnost naplnit pole bajtů
náhodnými čísly (metoda NextBytes).

Labels:

Monday, April 16, 2007

VB6.

Také při práci s poli (arrays), ostatně jako skoro všude jinde, došlo k několika velmi
podstatným změnám. Pole se číslují zásadně od nuly, z čehož mj. plyne, že je nadbytečný příkaz
Option Base, proto se nepodporuje.
Horní mez v deklaraci pole určuje výchozí počet prvků pole (v našem výpisu konkrétně 3), nikoli
počet prvků plus jedna, jako tomu bylo dříve! Horní mez je tedy počet prvků mínus 1
a tuto hodnotu vrátí vestavěná funkce UBound.
Deklarace pole pevné délky s explicitní dolní a horní mezí, jako například
Dim Trojice(0 To 3) As Integer
se už nepodporuje. Připomínám, že dolní mez všech polí musí být ve VB.NET nula. Prvky
pole však můžete inicializovat výchozími hodnotami. Například:
Dim Trojice() As Integer = {9, 8, 7}
Vícerozměrné pole můžete deklarovat pomocí pozičních závorek. Například trojrozměrné pole
celých čísel příkazem:
Dim Kvádr(,,) As Integer
Několik „drobných“ rozdílů je také spojeno s příkazem ReDim, který se používá
k předimenzování dynamického pole. Lze už měnit velikost kteréhokoli rozměru, počet rozměrů
však musí zůstat stejný.
Tedy, zatímco ve VB6 všechno následující projde:
Dim K() As Integer ' V deklarační sekci
' V proceduře pak:
ReDim K(5)
MsgBox (UBound(K)) '6
ReDim K(-1 To 7)
MsgBox (UBound(K) - LBound(K) + 1) '9
ReDim K(4, 5)
MsgBox (UBound(K)) '4
ve VB.NET tomu tak není. Chování ve VB.NET ilustrují následující ukázky:
Dim Kvádr(,,) As Integer ' V deklarační sekci
' V proceduře pak:
ReDim kvádr(5, 7, 9)
ReDim kvádr(10, 10) ' změna počtu rozměrů nejde
Dim krychle() As Integer ' V deklarační sekci
' V proceduře pak:
ReDim krychle(5)
ReDim krychle(5, 5)
Poslední příkaz neprojde, protože počet rozměrů nejde měnit. VB.NET vám oznámí, že
„Cannot change the Rank in a ReDim“).
Poslední připomínka. Ve VB6 jste mohli i úvodní deklaraci pole zařídit příkazem ReDim. Ve
VB.NET se to už nepovoluje.

Labels:

Wednesday, April 11, 2007

Alternativní způsob losování čísel

Jako téměř všechny úlohy, i losování můžete řešit mnoha způsoby. Například, místo losování jednotlivých
číslic můžete rovnou vylosovat jediné číslo od 0 do 999, a pak ho rozdělit na jednotlivé číslice. Můžete
k tomu využít vestavěnou funkci Format, která umožňuje převést pomocí bohaté palety masek hodnotu uvedenou
jako první parametr na řetězec pomocí formátovacího řetězce uvedeného jako druhý parametr:
Dim Trojice As String
Trojice = Format(VygenerovatPrirozeneCislo(0, 999), "000")
Poznámka. Pro účely formátování se ve Visual Basic.NET připravují speciální ovládací prvky jako jsou
FormatNumber či FormatDateTime, jejichž popis jsem při psaní brožury neměl k dispozici, takže je v aplikaci
nepoužívám a držím se klasického způsobu formátování.
Chcete-li mít jednotlivé číslice (znaky jako prvky pole), dá se to udělat také najednou, součinností funkcí
Format a Split:
Dim Trojice() As String
Trojice = Split(Format(VygenerovatPrirozeneCislo(0, 999), "0 0 0"))
Nabízí se samozřejmě další varianta, uložit vygenerované číslice do celočíselného pole. Tuto variantu
uvádím především proto, abych upozornil na rozdíly, které čekají uživatele předchozích verzí Basicu při práci
s poli a dále proto, že si na různém způsobu uložení generovaných výherních čísel (řetězec a celočíselné pole)
ukážeme tvorbu přetížené procedury Vyhral. Trojici číslic lze vygenerovat a uložit samozřejmě také takto:
Dim i, Trojice(3) As Integer
For i = 0 To 2
Trojice(i) = CInt(VygenerovatPrirozeneCislo())
Next

Labels:

Tuesday, April 10, 2007

Volitelné parametry procedury

Protože dejme tomu předpokládáte, že většinou budete v daném projektu losovat číslice, (tj. hodnoty 0
až 9), můžete si metodu zobecnit tak, že z původních povinných parametrů uděláte volitelné. Dělá se to tak,
že před parametry (musí to být poslední parametry vpravo) přidáte klíčové slovo Optional a uvedete výchozí
hodnoty. Funkce pak bude vypadat takto:
Public Function VygenerovatPrirozeneCislo _
(Optional ByVal DolniMez As Integer = 0, _
Optional ByVal HorniMez As Integer = 9) As String
VygenerovatPrirozeneCislo = _
CStr(Int((HorniMez - DolniMez + 1) * Rnd + DolniMez))
End Function
Volání se v našem případě zjednoduší na tvar:
lblCislo1.Text = VygenerovatPrirozeneCislo()
VB6. Dříve bylo uvádění výchozích hodnot nepovinné. Nepředání některého z volitelných parametrů
se testovalo funkcí IsMissing. Protože jsou nyní výchozí hodnoty povinné, je tato
funkce přebytečná a nepodporuje se.

Labels:

Saturday, April 07, 2007

Konstanty a datové typy ve Visual Basicu

V proceduře uvedené výše jsme použili číselnou konstantu jedna (1). Vzhledem k množství potřebných
konverzí se někdy hodí, vynutit přímo při zápisu konstanty její datový typ. Dělá se to tak, že se za literál zapíše
počáteční písmeno, které identifikuje datový typ. Například 1R znamená, že literál 1 bude datového typu
Double. Písmena pro jednotlivé číselné typy jsou: C=Char, D=Decimal, F=Single, I = Integer, L = Long,
R=Double, S = Short. Dají se také používat tzv. sufixy typů Visual Basicu (%, &, @, !, # a $).
V naší proceduře jsme se dotkli pojmu datový typ. Datový typ určuje, jaký druh dat může daná konstanta,
proměnná, pole, vlastnost, parametr procedury či návratová hodnota funkce obsahovat. Neuvedete-li explicitně
datový typ, použije se výchozí datový typ Object. V této brožuře se budete převážně setkávat s tzv. přirozenými
datovými typy Visual Basicu: Boolean, Byte, Char, Date, Decimal, Double, Integer, Long,
Object, Short a String.
Ve Visual Basic.NET odpovídají tyto typy strukturám či třídám pojmenovaného prostoru System. Datové
typy mají proto členy, k nimž se dá přistupovat podobně, jako přistupujete k vlastnostem a metodám objektů.
Například, datový typ Date je reprezentován strukturou System.DateTime a její vlastnost DaysInMonth
určuje, kolik dní je v zadaném měsíci zadaného roku.
VB6. Několik velmi závažných změn se ve VB.NET týká právě datových typů. Především už
neexistuje datový typ Variant (místo něho je Object) a funkce VarType, nepodporují se řetězce
pevné délky a nepodporují se také uživatelské datové typy (konstrukce Type…End Type,
místo ní se používá zobecněná konstrukce Structure…End Structure).
Nepodporují se také příkazy Deftyp. Datum se nyní ukládá na 8 bajtů (dříve 4) a změnám se
nevyhnuly ani číselné datové typy. Místo Integer je nyní Short, místo Long je Integer,
kromě toho se dá používat i datový typ System.SByte (8 bitů se znaménkem)

Labels:

Tuesday, April 03, 2007

Konstrukce

Konstrukce lze vnořovat a pomocí klíčových slov ElseIf docílit více kolejí. Jedná-li se o více než dvě
větve a podmínka je u všech větví stejná, používejte konstrukci Select Case (viz testování, zda uživatel
vyhrál pomocí vlastní přetížené funkce Vyhral, kterou budeme probírat později). Mod vrací zbytek po dělení
levého operandu pravým.
VB6. Logických hodnot True a False se dotýká „nepatrná“ drobnost, z jejíhož přehlédnutí
by mohla některé programátory VB6 pěkně bolet hlava. Jestliže jste ve svých programech
místo hodnoty True používali číselné vyjádření, vezměte prosím na vědomí, že hodnotě True
nyní odpovídá číselná hodnota 1, nikoli –1!

Labels:

Monday, April 02, 2007

Vytvoření vlastní metody pro vylosování čísla

Chcete-li napsat proceduru, která vylosuje náhodné celé číslo ze zvoleného intervalu, najdete patřičný výraz
v nápovědě k funkci Rnd. Vyjdete-li z něho a z informací uvedených v předchozím oddílu, můžete přidat
do kódu formuláře tuto funkční proceduru:
Public Function VygenerovatPrirozeneCislo _
(ByVal DolniMez As Integer, ByVal HorniMez As Integer) As String
VygenerovatPrirozeneCislo = _
CStr(Int((HorniMez - DolniMez + 1) * Rnd + DolniMez))
End Function
Funkční procedury jsou druhým základním typem procedur ve Visual Basicu. Od procedur typu Sub se liší
klíčovým slovem v úvodním a uzavírajícím definičním příkazu, hlavně ale tím, že vracejí hodnotu. Datový
typ návratové hodnoty se udává za seznamem parametrů, návratová hodnota se získá tím, že se v těle funkce
uvede přiřazovací příkaz, kde na levé straně funkce je její název, vpravo výraz určující návratovou hodnotu.
VB6. Připomínám, že nyní se parametry standardně předávají hodnotou (ByVal), nikoli odkazem
(ByRef) a že se standardně také vyžadují definice typů parametrů a návratové hodnoty
(klíčová slova As).
Příkaz pro přiřazení vylosovaného čísla bychom proto mohli napsat takto:
lblCislo1.Text = VygenerovatPrirozeneCislo(0, 9)
Modifikace algoritmu losování
Generování v podobě procedury může mít i jiné výhody. Když tuto proceduru „vhodně“ doplníte, můžete
si automat vylepšit ve svůj prospěch, například snížíte trochu pravděpodobnost, že se vylosují taková čísla,
která jsou výherní (uživatelům o tom samozřejmě neřeknete).
Například, je-li výherní kritérium stanoveno jako „alespoň jedna jednička“ a vy nechcete, aby uživatelé
příliš vyhrávali, můžete například proceduru modifikovat tak, že pokud se vylosuje něco jiného než jednička,
tak to necháte, když se vylosuje jednička, tak v polovině případů budete losovat ještě jednou. Upravená procedura
by mohl mít například tento tvar:
Public Function VygenerovatPrirozeneCislo _
(ByVal DolniMez As Integer, ByVal HorniMez As Integer) As String
Dim strCislo As String
strCislo = CStr(Int((HorniMez - DolniMez + 1) * Rnd + DolniMez))
If (strCislo = "1") And (Int(2 * Rnd) Mod 2 = 0) Then
VygenerovatPrirozeneCislo = _
CStr(Int((HorniMez - DolniMez + 1) * Rnd + DolniMez))
Else
VygenerovatPrirozeneCislo = strCislo
End If
End Function
Základní rozhodovací konstrukcí je ve Visual Basicu If podmínka Then něco udělej End If.
Vyhodnotí-li se podmínka na True, provedou se příkazy těla konstrukce, jinak se neprovede nic
(v železničářské terminologii „výhybka“). Zde je uvedena varianta s frází Else. Jestliže podmínka platí, udělej
to, jinak udělej něco jiného (v železničářské terminologii „rozdvojení na dvě koleje“).

Labels:

Sunday, April 01, 2007

Kupodivu vlnovka nezmizí.

Když na ni umístíte kurzor myši, zobrazí se okénko s touto informací:
Toto okénko patří mezi mnohé pomůcky, které poskytuje editor kódu. (Možnosti jsou soustředěny ve
složce Basic v rámci složky Text Editor dialogového okna Tools > Options.) Okénko nápovědy při psaní kódu,
kterým voláte funkci, je zobrazeno pod příštím výpisem, další ukázky jsou uvedeny v oddílu „Zjištění, zda
uživatel vyhrál“.
Visual Basic byl neblaze proslulý mj. tím, že podporoval nedeklarované proměnné, daly se „zamlčovat“
výchozí objekty a vlastnosti a také byl velmi liberální ohledně provádění implicitních konverzí. Mezi nové
schopnosti programovacího jazyka VB.NET patří velmi důležitý příkaz Option Strict. Je-li v činnosti
(On), povoluje implicitní konverze pouze tehdy, když se jedná o rozšíření datového typu na obecnější (například
Byte na Integer). Tím se automaticky vyloučí možnost, že by se při konverzi - zejména při převodu
číselných typů na řetězce - ztrácela přesnost nebo data jako taková. Option Strict zasáhne také při výskytu
nedeklarované proměnné (protože implikuje Option Explicit) a při příkazech tzv. pozdního vázání objektů.
Dá se tedy říci, že kvůli tomuto příkazu stoupá důležitost explicitního využívání dříve někdy dost přehlížených
konverzních funkcí. Náš konkrétní příkaz spravíte například takto:
lblCislo1.Text = CStr(Int(Rnd * 10))
Když píšete tento příkaz a dostanete se k levé závorce funkce Int, uvidíte jinou zajímavou pomůcku, která
upozorňuje na novou mocnou schopnost Visual Basic.Net, totiž přetěžování (overloading). Přetěžování
procedur umožňuje pod jediným názvem volat několik procedur, které se liší typem předávaných parametrů.
Konkrétně, funkce Int má sedm variant:
Zobrazuje se vždy jen jediný řádek, varianty prohlížíte klepáním na šipkách. Můžete samozřejmě psát
vlastní přetěžované procedury (jedná-li se o funkce, musí být typ návratové hodnoty stejný). Ukážeme si to
později na dvou variantách funkce, která bude zjišťovat, zda uživatel automatu vyhrál.
Losování čísel se pokusíme řešit obecněji. Předně se může stát, že budeme chtít losovat čísla z jiného intervalu
– proto bude žádoucí, když si sestrojíme k tomuto účelu vlastní uživatelsky definovanou funkci. Kromě
toho, abychom naplnili tři popisné objekty, musíme napsat tři téměř stejné příkazy. Dokud jsou tři, je to
celkem jedno. Pokud by bylo čísel třeba 20, už by tento způsob byl poněkud neohrabaný. Proto se pokusíme
přiřazení hodnot (ale i následné operace) řešit pomocí cyklu. První dílčí úlohu vyřešíme hned teď, rozbor
možností cyklování přes nějaké ovládací prvky najdete později v oddílu „Procházení podmnožiny ovládacích
prvků na formuláři“.

Labels:

Vylosování čísel

Dalším krokem v řešení naší úlohy bude vylosovat tři náhodné číslice, každá se objeví v jednom popisném
objektu. Později některé kombinace vylosovaných čísel prohlásíme za výherní čísla. Náhodná čísla se
doposud ve Visual Basicu generovala převážně pomocí spolupráce příkazu Randomize a funkce Rnd, která
vrací náhodné číslo z intervalu 0, 1. Tento způsob použijeme i zde. Nový způsob, který si můžete vyzkoušet,
viz Námět na procvičování na konci oddílu „Alternativní způsob losování čísel“.
Tato etapa řešení se tedy skládá ze dvou kroků:
1. Na místo, kam umisťujeme inicializační kód formuláře (pod řádek TODO ve vygenerovaném kódu
formuláře) přidáme příkaz Randomize.
2. Do událostní procedury Click tlačítka s nápisem Roztočit přidáme kód, jímž přiřadíme do vlastnosti
Text jednotlivých popisných prvků náhodně získanou číslici z intervalu 0 až 9. Hodnotu vrácenou
funkcí Rnd vynásobíme deseti a funkcí Int odřízneme desetinná místa.
VB6. Napíšete-li do kódu příkaz Randomize, zjistíte, že ho vývojové prostředí označí modrou
vlnovkou, což znamená, že je něco v nepořádku. Je to proto, že tento příkaz i funkce Rnd
jsou nyní nahrazeny metodami pojmenovaného prostoru Microsoft.VisualBasic. Compatibility.
VB6, takže příkaz musíte zapsat ve tvaru:
Microsoft.VisualBasic.Compatibility.VB6.Randomize()
To není příliš příjemné, naštěstí se dá kód zkrátit.
3. Přidejte na začátek kódu příkaz Imports pro tento pojmenovaný prostor:
Imports Microsoft.VisualBasic.Compatibility.VB6
Pak budete moci příkaz zkrátit na Randomize()
A také funkci Rnd nebudete muset volat s tak dlouhatánskou kvalifikací.
VB6. K přiřazení hodnoty do popisku dříve stačil například takovýto příkaz:
lblCislo1 = Int(Rnd * 10)
Ve VB.NET to takto napsat nejde, a to dokonce z několika důvodů. Na levé straně tohoto přiřazovacího
příkazu byla vypuštěna tzv. výchozí vlastnost ovládacího prvku, kterou byla dříve
Caption. Výchozí vlastnosti se už ve Visual Basicu nepodporují (kromě těch, které jsou parametrizované
– jimi se v této brožuře zabývat nebudeme), takže je už nemůžete vynechávat.
Mimo jiné se tím přispívá k lepší srozumitelnosti kódu.
Tato věc má další závažný důsledek. Protože nejsou výchozí vlastnosti, není nutné rozlišovat,
zda přiřazujete do vlastnosti (Caption, příkaz Let) nebo zda přiřazujete odkaz na objekt
(příkaz Set). Z toho důvodu se už příkazy Let a Set nepodporují!
Zdá se tedy, že se problém vyřeší jednoduše tím, že se prostě uvede vlastnost explicitně (za předpokladu,
že máte na začátku kódu příkaz Imports pro kompatibilní knihovnu):
lblCislo1.Text = Int(Rnd * 10)

Labels: