D°φve ne╛ se zaΦneme zab²vat datov²mi zdroji, podφvßme
se obecn∞ na jedno a dvouvrstvovΘ databßzovΘ aplikace. Jedno a dvou vrstvovΘ
aplikace obsahujφ logiku, kterß manipuluje s databßzov²mi informacemi,
ve stejnΘ aplikaci jako je u╛ivatelskΘ rozhranφ. Nebo╗ logika manipulace
dat nenφ izolovßna ve specißlnφ vrstv∞, jsou tyto typy aplikacφ vyhovujφcφ
pouze pokud dal╣φ aplikace nesdφlejφ stejnΘ databßzovΘ informace. Kdy╛
dal╣φ aplikace sdφlejφ databßzovΘ informace, pak tyto typy aplikacφ jsou
vyhovujφcφ pouze pro jednoduchΘ databßze. M∙╛eme takΘ zaΦφt jedno nebo
dvouvrstvov²mi aplikacemi, i kdy╛ mßme v ·myslu pro na╣i aplikaci pou╛φt
model vφcevrstvovΘ aplikace. Umo╛nφ nßm vytvo°it u╛ivatelskΘ rozhranφ a
logiku manipulace dat pozd∞ji p°esuneme na aplikaΦnφ server. Je tedy vhodnΘ
izolovat logiku manipulace dat tak, aby ji bylo mo╛no snadno p°esunout.
Aplikace zalo╛enΘ na BDE
Proto╛e komponenty datovΘho p°φstupu (a BDE) provßd∞jφ Φtenφ,
zßpis a prochßzenφ dat stejn∞ v jedno i dvouvrstvov²ch aplikacφch, nebudeme
tyto typy aplikacφ zde nadßle rozli╣ovat. Kdy╛ vyvφjφme aplikaci zalo╛enou
na BDE, pak do na╣φ aplikace musφme vlo╛it BDE. I kdy╛ to zv∞t╣uje velikost
a komplikuje ╣φ°enφ aplikace, BDE m∙╛e b²t sdφleno s ostatnφmi aplikacemi
zalo╛en²mi na BDE a nabφzφ mnoho v²hod. Aplikace zalo╛enΘ na BDE umo╛≥ujφ
pou╛φvat volßnφ API knihovny BDE. I kdy╛ nechceme pou╛φvat API BDE, pak
zßpisem aplikacφ zalo╛en²ch na BDE, zφskßme podporu, kterß jinak nenφ dostupnß.
Jednß se o (tyto body budou popsßny ve 12. kapitole):
-
P°ipojovßnφ k databßzi
-
Pou╛φvßnφ transakcφ
-
Odklßdßnφ aktualizacφ
-
Vytvß°enφ a restrukturalizovßnφ databßzov²ch tabulek
Architektura zalo╛enß na BDE
Jedno a dvouvrstvovΘ aplikace zalo╛enΘ na BDE obsahujφ:
-
U╛ivatelskΘ rozhranφ obsahujφcφ datovΘ ovladaΦe.
-
Jednu nebo vφce datov²ch mno╛in, kterΘ reprezentujφ informace
z databßzov²ch tabulek.
-
Komponentu datovΘho zdroje pro ka╛dou datovou mno╛inu pro
p°ipojovßnφ datov²ch ovladaΦ∙ k datov²m mno╛inßm.
-
Nepovinn∞, jednu nebo vφce komponent databßze k °φzenφ transakcφ
v jedno i dvouvrstvov²ch aplikacφch a ke sprßv∞ p°ipojenφ k databßzi
ve dvouvrstvov²ch aplikacφch.
-
Nepovinn∞, jednu nebo vφce komponent sezenφ k izolovßnφ operacφ
datovΘho p°φstupu, jako je databßzovΘ p°ipojenφ a ke sprßv∞ skupiny databßzφ.
VzßjemnΘ vztahy mezi t∞mito prvky jsou uvedeny na nßsledujφcφm
obrßzku:
Dal╣φ informace jsou uvedeny v t∞chto bodech:
Seznßmenφ
s databßzemi a datov²mi mno╛inami
Databßze obsahujφ informace ulo╛enΘ v tabulkßch. Mohou takΘ
obsahovat tabulky informacφ o tom, co je obsa╛eno v databßzi, objekty jako
jsou indexy, kterΘ jsou pou╛φvßny tabulkami a objekty SQL jako jsou ulo╛enΘ
procedury.
Strßnka Data Access Palety komponent obsahuje
r∙znΘ komponenty datov²ch mno╛in, kterΘ reprezentujφ tabulky obsa╛enΘ v
databßzi nebo logickΘ tabulky vytvo°enΘ z dat ulo╛en²ch v t∞chto databßzov²ch
tabulkßch. Komponentu datovΘ mno╛iny musφme vlo╛it do svΘ aplikace, abychom
mohli pracovat s databßzov²mi informacemi.
Ka╛dß komponenta na strßnce Data Access podporujφcφ
BDE mß vlastnost DatabaseName, kterß specifikuje databßzi obsahujφcφ
tabulku nebo tabulky, kterΘ dr╛φ informace v tΘto datovΘ mno╛in∞. Kdy╛
nastavujeme na╣φ aplikaci, pak musφme pou╛φt tuto vlastnost ke specifikaci
databßze d°φve ne╛ m∙╛eme spojit datovou mno╛inu se specifick²mi informacemi
obsa╛en²mi v tΘto databßzi. Jakou hodnotu specifikujeme zßvisφ na tom zda:
-
Databßze mß p°ezdφvku BDE. P°ezdφvku BDE m∙╛eme specifikovat
jako hodnotu DatabaseName. P°ezdφvka BDE reprezentuje databßzi a
konfiguraΦnφ informace pro tuto databßzi. KonfiguraΦnφ informace p°i°azenΘ
k p°ezdφvce se li╣φ podle typu databßze (Oracle, Sybase, Interbase, Paradox,
dBASE apod.). K vytvß°enφ a sprßv∞ p°ezdφvek BDE pou╛φvßme Administrßtor
BDE nebo Pr∙zkumnφk SQL.
-
Jednß se o databßzi Paradox nebo dBASE. Pokud pou╛φvßme tyto
databßze, pak DatabaseName m∙╛e specifikovat adresß°, kde databßzovΘ
tabulky jsou umφst∞ny.
-
Pou╛φvßme explicitn∞ komponentu databßze. Komponenta databßze
(TDatabase)
reprezentuje v na╣i aplikaci databßzi. Pokud nep°idßme komponentu databßze
explicitn∞, je jedna vytvß°ena automaticky a to na zßklad∞ vlastnosti DatabaseName.
Pokud explicitn∞ pou╛ijeme komponentu databßze, pak DatabaseName
je hodnota vlastnosti DatabaseName komponenty databßze.
Pou╛φvßnφ sezenφ
Sezenφ izolujφ operace datovΘho p°φstupu jako je p°ipojenφ
k databßzi a sprßva skupin databßzφ. V╣echno pou╛itφ BDE probφhß v kontextu
sezenφ. Sezenφ m∙╛eme pou╛φt ke specifikaci konfiguraΦnφch informacφ aplikovan²ch
na v╣echny databßze v sezenφ. To umo╛≥uje zm∞nit chovßnφ specifikovanΘ
administrßtorem BDE. Sezenφ m∙╛eme pou╛φt k:
-
Sprßv∞ p°ezdφvek BDE. M∙╛eme vytvß°et novΘ p°ezdφvky,
ru╣it p°ezdφvky a modifikovat existujφcφ p°ezdφvky. Implicitn∞, zm∞ny ovliv≥ujφ
pouze sezenφ, ale zm∞ny m∙╛eme zapsat do konfiguraΦnφho souboru BDE a tak
je ud∞lat trval²mi.
-
╪φzenφ uzav°enφ databßzov²ch p°ipojenφ ve dvouvrstvov²ch
aplikacφch. Udr╛ovßnφ otev°en²ch databßzov²ch p°ipojenφ kdy╛ ╛ßdnß
datovß mno╛ina v databßzi nenφ aktivnφ, chrßnφ zdroje, kterΘ by mohli b²t
uvoln∞ny, ale zvy╣uje rychlost a sni╛uje sφ╗ov² provoz. K dr╛enφ otev°en²ch
databßzov²ch p°ipojenφ kdy╛ nejsou aktivnφ datovΘ mno╛iny, nastavφme
vlastnost KeepConnections na true (implicitn∞).
-
Sprßv∞ p°φstupu k tabulkßm Paradoxu nebo dBASE chrßn∞n²ch
heslem v jednovrstvov²ch aplikacφch. Pro datovΘ mno╛iny, kterΘ p°istupujφ
k tabulkßm Paradoxu a dBASE chrßn∞n²m heslem, pou╛ijeme komponenty sezenφ
k p°edßnφ hesla p°i jejich otev°enφ. Implicitnφ chovßnφ m∙╛eme p°epsat
a p°edßvat heslo programov∞. Pokud zam²╣lφme p°ejφt od jednovrstvovΘ aplikace
na dvou nebo vφcevrstvovou aplikaci, pak m∙╛eme vytvo°it spoleΦnΘ u╛ivatelskΘ
rozhranφ pro zφskßnφ informacφ autorizace u╛ivatele, kter² se nezm∞nφ i
kdy╛ p°ejdeme na pou╛φvßnφ vzdßlen²ch databßzov²ch server∙ vy╛adujφcφch
p°ihla╣ovßnφ k serveru a ne k tabulce.
-
Specifikaci umφst∞nφ specißlnφch adresß°∙ Paradoxu.
Databßze Paradoxu, kterΘ jsou sdφleny na sφti, pou╛φvajφ sφ╗ov² adresß°
obsahujφcφ doΦasnΘ soubory s informacemi o uzamΦen²ch tabulkßch a zßznamech.
Databßze Paradoxu takΘ pou╛φvajφ privßtnφ adresß° pro uklßdßnφ doΦasn²ch
soubor∙ typu v²sledku dotazu.
Pokud na╣e aplikace m∙╛e p°istupovat ke stejnΘ databßzi soub∞╛n∞,
pak musφme pou╛φt vφce sezenφ k izolaci t∞chto pou╛φvßnφ databßze. Aplikace
riskuje soub∞╛n² p°φstup, kdy╛ spou╣tφ soub∞╛nΘ dotazy nebo kdy╛ pou╛φvß
vφce vlßken. Pokud nepot°ebujeme pou╛φvat vφce sezenφ, pak je mo╛no pou╛φvat
implicitnφ sezenφ.
P°ipojovßnφ k databßzi
BDE obsahuje ovladaΦe pro p°ipojenφ k r∙zn²m databßzφm. Verze
Standard C++ Builderu obsahuje pouze ovladaΦe pro lokßlnφ databßze: Paradox,
dBASE, FoxPro a Access. U verze Profesional, zφskßme takΘ adaptΘr ODBC,
kter² umo╛≥uje pou╛φvat ovladaΦe ODBC. Tφm zφskßme p°φstup k databßzφm
vyu╛φvajφcφm ODBC. Ostatnφ verze takΘ obsahujφ ovladaΦe pro vzdßlenΘ databßzovΘ
servery. OvladaΦe instalovanΘ s SQL Links pou╛ijeme ke komunikaci se vzdßlen²mi
databßzov²mi servery jako je Interbase, Oracle, Sybase, Informix, Microsoft
SQL server a DB2.
Poznßmka: Jedin²m rozdφlem mezi jednovrstvov²mi
a dvouvrstvov²mi aplikacemi zalo╛en²mi na BDE je to, zda pou╛φvajφ lokßlnφ
nebo vzdßlenΘ databßzovΘ servery.
Pou╛φvßnφ datov²ch
zdroj∙
Komponenta TDataSource je nevizußlnφ databßzovß komponenta,
kterß pracuje jako propojenφ mezi datovou mno╛inou a datov²mi komponentami
na formulß°i. Ka╛dß datovß mno╛ina musφ mφt odpovφdajφcφ komponentu datovΘho
zdroje. Komponenta datovΘho zdroje spojuje vizußlnφ datovΘ ovladaΦe na
formulß°i s datovou mno╛inou. Vizußlnφ databßzovΘ ovladaΦe zφskßvajφ data
z a zasφlajφ data do komponenty datovΘho zdroje. Komponenta datovΘho zdroje
p°enß╣φ data z datovΘ mno╛iny k vizußlnφm ovladaΦ∙m a z vizußlnφch ovladaΦ∙
zp∞t do datovΘ mno╛iny. Ka╛d² datov² ovladaΦ musφ b²t p°i°azen ke komponent∞
datovΘho zdroje, aby mohl zobrazovat a manipulovat s daty.
Poznßmka: M∙╛eme takΘ pou╛φt komponentu datovΘho
zdroje ke spojenφ datov²ch mno╛in do vzßjemnΘm vztahu master - detail.
Komponenty datovΘho zdroje umis╗ujeme do datovΘho modulu
nebo na formulß° a to stejn∞ jako umis╗ujeme jinΘ komponenty databßzovΘho
p°φstupu. Musφme pou╛φt alespo≥ jednu komponentu datovΘho zdroje pro ka╛dou
komponentu datovΘ mno╛iny v datovΘm modulu nebo na formulß°i.
S datov²mi zdroji se seznßmφme v t∞chto bodech:
Pou╛φvßnφ vlastnostφ TDataSource
TDataSource mß pouze n∞kolik zve°ej≥ovan²ch vlastnostφ.
Nßsledujφ informace o pou╛φvßnφ t∞chto vlastnostφ. Jsou popsßny v t∞chto
bodech:
Nastavovßnφ vlastnosti DataSet
Vlastnost DataSet urΦuje datovou mno╛inu, ze kterΘ
komponenta datovΘho zdroje zφskßvß svß data. B∞hem nßvrhu m∙╛eme vybrat
datovou mno╛inu v rozbalovacφm seznamu v Inspektoru objekt∙. Za b∞hu aplikace
m∙╛eme p°epφnat datovΘ mno╛iny pro komponentu datovΘho zdroje podle pot°eby.
Nap°. nßsledujφcφ k≤d p°epφnß datovΘ mno╛iny pro komponentu datovΘho zdroje
CustSource
mezi Customers a Orders:
if (CustSource->DataSet == Customers)
CustSource->DataSet = Orders;
else
CustSource->DataSet = Customers;
M∙╛eme takΘ nastavit vlastnost DataSet na datovou
mno╛inu z jinΘho formulß°e k synchronizaci datov²ch ovladaΦ∙ na dvou formulß°φch.
Nap°.
void __fastcall TForm2::FormCreate(TObject
*Sender)
{
DataSource1->DataSet = Form1->Table1;
}
Nastavovßnφ vlastnosti Name
Name umo╛≥uje specifikovat smysluplnΘ jmΘno pro komponentu
datovΘho zdroje, kterΘ se musφ li╣it od v╣ech jmen ostatnφch datov²ch zdroj∙
v na╣φ aplikaci. JmΘno komponenty datovΘho zdroje je zobrazovßno pod ikonou
komponenty v datovΘm modulu. Je vhodnΘ aby toto jmΘno indikovalo p°i°azenou
datovou mno╛inu. Nap°. p°edpoklßdejme, ╛e mßme datovou mno╛inu nazvanou
Customers
a ╛e je spojena s komponentou datovΘho zdroje nastavenφm vlastnosti komponenty
datovΘho zdroje DataSet na Customers. Vlastnost Name
u komponenty datovΘho zdroje pak nastavφme nap°. na CustomersSource.
Nastavovßnφ vlastnosti Enabled
Vlastnost Enabled urΦuje zda komponenta datovΘho zdroje
je p°ipojena ke svΘ datovΘ mno╛in∞. Kdy╛ Enabled je true,
pak datov² zdroj je p°ipojen k datovΘ mno╛in∞. Datov² zdroj m∙╛eme doΦasn∞
odpojit od svΘho datovΘho spoje nastavenφm Enabled na false.
Kdy╛ Enabled je false, pak v╣echny datovΘ ovladaΦe p°ipojenΘ
ke komponent∞ datovΘho zdroje jsou prßzdnΘ a neaktivnφ, dokud Enabled
op∞t nenastavφme na true. Je ale doporuΦovßno °φdit p°φstup k datovΘ
mno╛in∞ prost°ednictvφm metod DisableControls a EnableControls
datovΘ mno╛iny, nebo╗ ovliv≥ujφ v╣echny p°ipojenΘ datovΘ zdroje.
Nastavovßnφ vlastnosti AutoEdit
Vlastnost AutoEdit datovΘho zdroje urΦuje, zda datovß
mno╛ina p°ipojenß k datovΘmu zdroji automaticky p°echßzφ do stavu dsEdit,
kdy╛ u╛ivatel zaΦne zapisovat do datovΘho ovladaΦe spojenΘho s datovou
mno╛inou. Pokud
AutoEdit je true (implicitn∞), pak datovß
mno╛ina automaticky p°ejde do stavu
dsEdit, kdy╛ u╛ivatel zapisuje
do p°ipojenΘho datovΘho ovladaΦe. Jinak, datovß mno╛ina p°echßzφ do stavu
dsEdit
pouze kdy╛ aplikace explicitn∞ volß metodu Edit.
Pou╛φvßnφ udßlostφ datovΘho
zdroje
Datov² zdroj mß t°i udßlosti:
Pou╛φvßnφ udßlosti
OnDataChange
Udßlost OnDataChange nastßvß, kdy╛ kurzor je p°esunut
na jin² zßznam. Kdy╛ aplikace volß Next, Prior, Insert
nebo n∞kterou jinou metodu, kterß m∞nφ pozici kurzoru, pak je generovßna
udßlost
OnDataChange. Tato udßlost je u╛iteΦnß, kdy╛ aplikace manußln∞
synchronizuje komponenty.
Pou╛φvßnφ udßlosti
OnUpdateData
Udßlost OnUpdateData nastane, kdy╛ data v souΦasnΘm
zßznamu majφ b²t aktualizovßna. Nap°. udßlost OnUpdateData nastane,
kdy╛ je volßna metoda Post, ale d°φve ne╛ jsou data skuteΦn∞ zapsßna
do databßze. Tato udßlost je u╛iteΦnß, kdy╛ aplikace pou╛φvß standardnφ
(nedatabßzovΘ) ovladaΦe a pot°ebuje je synchronizovat s datovou mno╛inou.
Pou╛φvßnφ
udßlosti OnStateChange
Udßlost OnStateChange nastßvß, kdy╛ stav datovΘ mno╛iny
datovΘho zdroje se zm∞nφ. Stav datovΘ mno╛iny je zaznamenßn ve vlastnosti
State
datovΘ mno╛iny. OnStateChange je u╛iteΦnß pro provßd∞nφ akcφ souvisejφcφch
se zm∞nou stavu datovΘho zdroje.
Nap°. v pr∙b∞hu normßlnφho databßzovΘho sezenφ se stav
datovΘ mno╛iny m∞nφ Φasto. K zachycenφ t∞chto zm∞n, m∙╛eme zapsat obsluhu
udßlosti OnStateChange, kterß zobrazφ aktußlnφ stav datovΘ mno╛iny
v komponent∞ Label na formulß°i. Nßsledujφcφ k≤d ukazuje jak to
provΘst:
void __fastcall TForm1::DataSource1StateChange(TObject
*Sender)
{
AnsiString S;
switch (CustTable->State)
{
case dsInactive: S = "Inactive";
break;
case dsBrowse: S = "Browse";
break;
case dsEdit: S = "Edit";
break;
case dsInsert: S = "Insert";
break;
case dsSetKey: S = "SetKey";
break;
}
CustTableStateLabel->Caption = S;
}
Podobn∞ OnStateChange m∙╛e b²t pou╛ito k povolenφ
nebo zakßzßnφ tlaΦφtek nebo prvk∙ nabφdek na zßklad∞ souΦasnΘho stavu.
void __fastcall TForm1::DataSource1StateChange(TObject
*Sender)
{
CustTableEditBtn->Enabled = (CustTable->State
== dsBrowse);
CustTableCancelBtn->Enabled = (CustTable->State
== dsInsert ||
CustTable->State == dsEdit ||
CustTable->State == dsSetKey);
...
}
-
Nynφ zahßjφme v²voj databßzovΘ aplikace pro fiktivnφ firmu Global Dive
Supply. Jeliko╛ nß╣ projekt se bude sklßdat z n∞kolika formulß°∙ vytvo°φme
si nejprve prßzdn² standardnφ formulß° pro tuto firmu (bude tvo°it zßklad
v╣ech formulß°∙ aplikace). Takto vytvo°en² formulß° m∙╛eme vlo╛it do zßsobnφku
objekt∙.
Uzav°eme v╣echny soubory (volbou File | Close All) a zvolφme
File
| New Form. Tφm vytvo°φme nov² prßzdn² formulß°, kter² nenφ zapojen
do ╛ßdnΘho projektu. Vlastnost
Name u tohoto formulß°e zm∞nφme na
Base
a hodnotu vlastnosti
Caption vyprßzdnφme. Titulnφ °ßdek formulß°e
nynφ obsahuje prßzdn² °ßdek.
Na formulß° zaΦneme p°idßvat komponenty. K hornφmu okraji formulß°e
vlo╛φme Panel (pro jmΘno na╣φ firmy) a dal╣φ panel vlo╛φme ke spodnφmu
okraji formulß°e (pro °φdφcφ tlaΦφtka). V²╣ka obou panel∙ bude asi 40 bod∙.
U hornφho panelu zru╣φme hodnotu vlastnosti Caption a vlastnost
Align
nastavφme na alTop. Do hornφho panelu umφstφme komponentu
Label
a nastavφme jejφ vlastnosti: vlastnost Align na alLeft,
Caption
na Global Dive Supply a vlastnost Font na pφsmo Arial,
tuΦnou kurzφvu, velikost 16 a barvu Purple.
U spodnφho panelu zru╣φme hodnotu vlastnosti Caption, vlastnost
Align
zm∞nφme na alBottom a vlastnosti BevelInner a BevelOuter
nastavφme na bvNone. Na spodnφ panel vpravo p°idßme tlaΦφtko pro
uzavφrßnφ formulß°e. Zm∞nφme jeho Caption na Exit a vytvo°φme
jeho obsluhu stisknutφ, kterß bude tvo°ena p°φkazem
Close();
Tφm je vytvo°en zßklad pro formulß° na╣φ fiktivnφ firmy a mohli bychom
jej umφstit do Zßsobnφku objekt∙. Zde na uΦebn∞ se nßm to ale nepoda°φ
(mßme zakßzßn zßpis). Formulß° tedy ulo╛φme n∞kolikrßt pod r∙zn²m jmΘnem
(do adresß°e, kter² jsme si vytvo°ili pro tuto aplikaci). JmΘno BaseMod
pou╛ijeme pro formulß° pou╛it² jako ╣ablonu, jmΘno HomeMod pro °φdφcφ
formulß° aplikace a jmΘno CustMod pro formulß° zßkaznφk∙.
-
K vytvo°enφ novΘho prßzdnΘho projektu zvolφme File | New Application.
Jeliko╛ v╣echny svΘ formulß°e budeme odvozovat od na╣eho formulß°e (╣ablony),
musφme odstranit implicitnφ formulß° vytvo°en² C++ Builderem pro nov² projekt.
Pomocφ sprßvce projektu zru╣φme Form1. Jsme dotßzßni, zda soubor
ulo╛it; odpovφme No.
Prvnφ formulß°, kter² v na╣em projektu vytvo°φme, bude °φdφcφ formulß°
aplikace. Ve Sprßvci projektu p°ejdeme na Projektov² uzel, v jeho mφstnφ
nabφdce zvolφme Add a k projektu p°idßme nß╣ ji╛ ulo╛en² formulß°
HomeMod.
U tohoto formulß°e zm∞nφme vlastnost Name na Home a vlastnost
Caption
na Global Dive Supply Central Control.
Na lev² okraj spodnφho panelu p°idßme tlaΦφtko, zm∞nφme jeho vlastnost
Caption
na Customers a vytvo°φme obsluhu jeho stisku, kterß bude tvo°ena
p°φkazem:
Cust->Show();
Cust bude jmΘno formulß°e, kter² bude pou╛it k zobrazenφ informacφ
o zßkaznφcφch. Kdy╛ u╛ivatel stiskne toto tlaΦφtko ve spu╣t∞nΘ aplikaci,
pak p°edchozφ k≤d zp∙sobφ zobrazenφ uvedenΘho formulß°e. Vedle tlaΦφtka
Customers
vlo╛φme dal╣φ tlaΦφtko a zm∞nφme jeho vlastnost Caption na Terms.
Pro toto tlaΦφtko zapφ╣eme takΘ obsluhu jeho stisku:
Term->Show();
Term bude jmΘno formulß°e, kter² pou╛ijeme k zobrazenφ informacφ
o placenφ objednßvek. Kdy╛ u╛ivatel stiskne toto tlaΦφtko, pak tento k≤d
zp∙sobφ zobrazenφ uvedenΘho formulß°e. TlaΦφtko Exit nechßme beze
zm∞ny a formulß° ulo╛φme.
-
Datov² modul je typ formulß°e, kter² obsahuje p°ipojenφ na externφ databßzi
a pracuje jako jednoduch² centrßlnφ zdroj pro v╣echny ostatnφ formulß°e
aplikace. Zvolφme File | New, p°ejdeme na strßnku Data Modules,
nastavφme voliΦ Inherit, vybereme objekt Customer Data a
stiskneme tlaΦφtko OK. U vytvo°enΘho datovΘho modulu zm∞nφme vlastnost
Name
na Data, u tabulek Customers a Orders zm∞nφme vlastnost
Active
na true a modul ulo╛φme pod jmΘnem
DataMod. K DatovΘmu modulu
se za chvφli vrßtφme.
-
Nynφ p°idßme formulß° CustMod, kter² se zobrazφ po stisku tlaΦφtka
Customers.
Ve Sprßvci projektu v mφstnφ nabφdce projektovΘho uzlu zvolφme Add
a vybereme tento d°φve ulo╛en² formulß°. Vlastnost Name zm∞nφme
na Cust a Caption na Customer Contacts. My╣φ p°esuneme
tento formulß° nepatrn∞ dol∙ a vpravo (aby byl vid∞t hornφ okraj formulß°e
Home).
K formulß°i p°ipojφme nß╣ Datov² modul. Vybereme nov² formulß°, zvolφme
File
| Include Unit Hdr, vybereme DataMod a stiskneme
OK.
Nynφ formulß° CustMod mß p°φstup ke v╣em informacφm obsa╛en²m v
DatovΘm modulu.
Na formulß° na jeho hornφ panel blφzko jeho pravΘho okraje vlo╛φme
komponentu Edit. Zm∞nφme jejφ vlastnost Name na FilterText,
zru╣φme hodnotu vlastnosti Text a nastavφme Width na 80.
Vlevo od tΘto komponenty vlo╛φme znaΦku. Zm∞nφme jejφ Name na FilterToggle,
Caption
na Filter? a Alignment na taLeftJustify.
Na formulß° dßle p°idßme komponentu TDBGrid. Zm∞nφme jejφ vlastnost
Align
na alClient. Jeliko╛ nß╣ formulß° pou╛φvß datov² modul
DataMod,
m∙╛eme nastavit vlastnost DataSource komponenty
TDBGrid na
Data->CustomerSource.
Dßle je nutno urΦit, kterΘ ·daje budeme zobrazovat. Klikneme prav²m tlaΦφtkem
na TDBGrid a z jeho mφstnφ nabφdky zvolφme
Columns Editor.
V zobrazenΘm dialogovΘm okn∞ stiskneme tlaΦφtko
Add All Fields a
zru╣φme v╣echny sloupce mimo: Company, State,
Phone,
FAX
a Contact. Polo╛ku Contact p°esuneme p°ed Phone a
okno uzav°eme. Nynφ m∙╛eme pomocφ my╣i nastavit ╣φ°ku jednotliv²ch sloupc∙
(p°eta╛enφm rozd∞lovacφch Φar v hlaviΦce tabulky).
Zapφ╣eme takΘ obsluhy udßlostφ. Obsluha OnChange editaΦnφho
ovladaΦe je tvo°ena p°φkazy:
FilterToggle->Checked = true;
Data->Customers->Filtered = true;
a obsluha udßlosti kliknutφ na znaΦce je tvo°ena p°φkazem:
Data->Customers->Filtered = FilterToggle->Checked;
Zobrazφme nß╣ Datov² modul DataMod, vybereme tabulku Customers
a vytvo°φme jejφ obsluhu udßlosti OnFilterRecord. Bude tvo°ena p°φkazem:
Accept = (CustomersState->Value == Cust->FilterText->Text);
Tφm je formulß° CustMod hotov a m∙╛eme jej ulo╛it. Datov² modul
se ale nynφ odkazuje na znaΦku formulß°e CustMod. Musφme tedy k
DatovΘmu modulu p°idat hlaviΦkov² soubor CustMod (p°i vybranΘm DatovΘm
modulu, zvolφme File | Include Unit Hdr, vybereme CustMod
a stiskneme OK).
-
Na╣e aplikace pot°ebuje je╣t∞ jeden formulß°. Mφsto vytvo°enφ novΘho formulß°e,
kter² zd∞dφ vlastnosti od BaseMod, nß╣ nov² formulß° m∙╛eme odvodit
i od n∞kterΘho formulß°e ve stejnΘm projektu. Zvolφme File | New,
p°ejdeme na strßnku Project1 (pokud jsme projekt nep°ejmenovali)
a nastavφme voliΦ Inherit. Nynφ vidφme v Zßsobnφku objekt∙ v╣echny
formulß°e pou╛itΘ v na╣em projektu. Vybereme Cust, stiskneme OK
a op∞t my╣φ posuneme nov² formulß° nepatrn∞ dol∙ a doprava. U tohoto novΘho
formulß°e zm∞nφme Name na Term a Caption na Display
Orders By Terms. K formulß°i op∞t p°idßme hlaviΦkov² soubor na╣eho
DatovΘho modulu. Formulß° ulo╛φme pod jmΘnem TermMod.
V╣echny komponenty, a╛ na TDBGrid m∙╛eme nechat beze zm∞ny.
Vybereme
TDBGrid a nastavφme vlastnost DataSource na Data->OrderSource.
Z mφstnφ nabφdky TDBGrid zvolφme Columns Editor. Z polo╛ek
tabulky nechßme zobrazovat pouze: OrderNo, CustNo,
CustCompany,
SaleDate,
Terms
a PaymentMetod. Po°adφ prvnφch t°φ zm∞nφme takto: CustNo,
CustCompany
a OrderNo. U polo╛ek
OrderNo a CustNo zmen╣φme ╣φ°ku
sloupce.
Musφme je╣t∞ zm∞nit k≤d obsluh udßlostφ OnClick editaΦnφ komponenty
a znaΦky formulß°e (zd∞d∞n² k≤d je nutno zru╣it) a p°idat obsluhu udßlosti
OnFilterRecord
pro tabulku Orders. Pro editaΦnφ komponentu pou╛ijeme k≤d:
FilterToggle->Checked = true;
Data->Orders->Filtered = true;
ZnaΦka bude mφt k≤d:
Data->Orders->Filtered = FilterToggle->Checked;
V DatovΘm modulu vybereme tabulku Orders a zapφ╣eme jejφ obsluhu
udßlosti OnFilterRecord. Bude ji tvo°it p°φkaz:
Accept = (OrdersTerms->Value == Term->FilterText->Text);
Tφm je v²voj na╣φ aplikace hotov. Do °φdφcφho formulß°e je nutno je╣t∞
vlo╛it hlaviΦkovΘ soubory obou dal╣φch formulß°∙ a ulo╛it v╣echny soubory.
Aplikaci m∙╛eme vyzkou╣et.
-
Podφvßme se je╣t∞ na jednu podobnou aplikaci. ⌐ablona formulß°e, kterou
v tΘto aplikaci budeme pou╛φvat, je zobrazena na nßsledujφcφm obrßzku.
ZaΦn∞te v²voj novΘ aplikace a vytvo°φme nßsledujφcφ formulß°. V hornφ
Φßsti je panel a na n∞m je pou╛ita komponenta TImage (okolo obrßzku
je umφst∞na komponenta TBevel) a vedle dv∞ a dv∞ komponenty TLabel
(nad sebou). BφlΘ okraje pφsmen jsou tvo°eny tφm, ╛e bφl² text je p°ekryt
stejn²m Φern²m textem, kter² je o jeden bod posunut nahoru. Vlastnost Name
formulß°e zm∞nφme na GDSStdForm a ulo╛φme jej do souboru GDSStd.cpp.
-
Ve v²voji aplikace budeme pokraΦovat tφm, ╛e na nov² formulß°, odvozen²
od p°edchozφho, p°idßme komponenty datovΘho p°φstupu a n∞kolik dal╣φch
ovladaΦ∙ (viz nßsledujφcφ obrßzek). Zvolφme File | New, p°ejdeme
na strßnku
Project1, nastavφme voliΦ Inherit, vybereme GDSStdForm
a stiskneme
OK.
K formulß°i p°idßme nßsledujφcφ soukromΘ polo╛ky (dv∞ datovΘ slo╛ky
pro ulo╛enφ parametru filtrovacφho kritΘria ve tvaru reßlnΘho Φφsla nebo
datumu a dv∞ metody) :
double FLastAmount;
TDateTime FLastDate;
double __fastcall CalcAmountDue(void);
void __fastcall ConvertFilterCriteria(void);
Implementace metod je:
double __fastcall TStdDataForm::CalcAmountDue(void)
{
return OrdersItemsTotal->Value * (1.0
+ OrdersTaxRate->Value
/ 100) + OrdersFreight->Value
- OrdersAmountPaid->Value;
}
/* P°evßdφ text filtrovacφho kritΘria na
datum nebo reßlnΘ Φφslo. Tato
hodnota bude pou╛ita v obsluze
OnFilterRecord
mφsto p°φmΘho pou╛itφ
filtrovacφho kritΘria a °et∞zec
tedy nenφ nutno p°evßd∞t v╛dy p°i
vzniku tΘto udßlosti. */
void __fastcall TStdDataForm::ConvertFilterCriteria(void)
{
if (FilterCriteria->Text != "")
{
switch (FilterOnRadioGroup->ItemIndex)
{
case 0:
FLastDate = StrToDate(FilterCriteria->Text);
break;
case 1:
FLastAmount = StrToFloat(FilterCriteria->Text);
break;
}
}
if (Orders->Filtered) Orders->Refresh();
}
Jedna z komponent TTable mß nastaveny vlastnosti: Name
na Orders, DatabaseName na BCDEMOS, TableName
na Orders.db a Active na true. Druhß komponenta TTable
mß vlastnost Name nastavenu na Cust, vlastnost DatabaseName
na BCDEMOS, TableName na Customers.db a Active
na true. U komponenty datovΘho zdroje je Name nastaveno na
OrdersSource
a vlastnost DataSet na Orders.
Prvnφ komponenta TTable (Orders) bude pou╛φvat poΦitatelnΘ
polo╛ky. V mφstnφ nabφdce tΘto komponenty zvolφme Fields editor.
Tφm zobrazφme Editor polo╛ek. Seznam Editoru polo╛ek je zatφm prßzdn².
V mφstnφ nabφdce Editoru zvolφme Add Fields a v zobrazenΘm okn∞
jsou uvedeny v╣echny polo╛ky datovΘ mno╛iny Orders. V╣echny vybereme
a stiskneme OK. Tφm jsme do seznamu Editoru polo╛ek p°idali v╣echny
polo╛ky tabulky. Vytvo°φme je╣t∞ jednu vyhledßvacφ a dv∞ poΦitatelnΘ polo╛ky.
V mφstnφ nabφdce Editoru polo╛ek zvolφme New Field a v zobrazenΘm
dialogovΘm okn∞ zapφ╣eme do Φßsti Name jmΘno CustName, v
kombinovanΘm ovladaΦi Type vybereme String, do Size
zadßme 20 a nastavφme voliΦ Lookup. Dßle Dataset nastavφme
na Cust, Key Fields na CustNo, Lookup Keys
na CustNo, ResultField na Company a stiskneme OK.
Tφm je definovßna vyhledßvacφ polo╛ka.
Podobn∞ vytvo°φme poΦitatelnΘ polo╛ky. V mφstnφ nabφdce Editoru polo╛ek
zvolφme New Field a v zobrazenΘm dialogovΘm okn∞ do Φßsti Name
zapφ╣eme hodnotu TaxAmount, v kombinovanΘm ovladaΦi
Type
vybereme Currency, nastavφme voliΦ Calculated a stiskneme
OK.
Pro p°idßnφ druhΘ polo╛ky zvolφme op∞t New Field, do Φßsti Name
zadßme AmountDue, Type a Calculated nastavφme stejn∞
jako u p°edchozφ polo╛ky a stiskneme OK. Tφm mßme poΦitatelnΘ polo╛ky
definovßny. P∙vodnφ i p°idanΘ polo╛ky jsou nynφ popsßny polo╛kov²mi komponentami.
Jeliko╛ pozd∞ji v m°φ╛ce budeme chtφt zobrazovat pouze polo╛ky OrderNo,
CustNo,
vyhledßvacφ a ob∞ poΦitatelnΘ polo╛ky, je nutno, aby pouze u t∞chto p∞ti
polo╛kov²ch komponent byla nastavena vlastnost Visible na true
(ostatnφ polo╛kovΘ komponenty ji musφ mφt nastavenu na false).
Je nutno je╣t∞ definovat obsluhu udßlosti
OnCalcFields prvnφ
komponenty TTable. Obsluhu tvo°φ p°φkazy:
OrdersTaxAmount->Value=OrdersItemsTotal->Value*(OrdersTaxRate->Value/100);
OrdersAmountDue->Value=CalcAmountDue();
U tΘto komponenty je nutno je╣t∞ vytvo°it obsluhu udßlosti OnFilterRecord.
Tato obsluha se bude ale m∞nit. Budou se zde st°φdat nßsledujφcφ dv∞ obsluhy
(p∙vodn∞ je udßlosti p°i°azena prvnφ z nich):
void __fastcall TStdDataForm::OrdersFilterOnAmount(TDataSet
* DataSet,
bool & Accept)
{
Accept = (CalcAmountDue() >= FLastAmount);
}
void __fastcall TStdDataForm::OrdersFilterOnDate(TDataSet
* DataSet,
bool & Accept)
{
Accept = (OrdersSaleDate->Value >=
FLastDate);
}
Dal╣φ ovladaΦe, kterΘ byly p°idßny, jsou umφst∞ny na komponent∞ panelu.
P°idßme tedy komponentu panelu a nastavφme u n∞j vlastnost Name na
StdCtrlPanel,
vlastnost Align nastavφme na alTop a vlastnost Height
na 72.
Podle p°edchozφho obrßzku vlo╛te na panel dal╣φ komponenty. Vlevo je
umφst∞na komponenta TRadioGroup, uprost°ed TGroupBox (obsahuje
komponenty TLabel a TEdit) a vpravo TCheckBox a dv∞
tlaΦφtka. Na komponenty se budeme odkazovat v k≤du a zm∞nφme jejich vlastnosti
Name
takto: u TRadioGroup na FilterOnRadioGroup, u
TLabel
na FilterOnLabel, u TEdit na FilterCriteria, u znaΦky
na FilterCheckBox, u levΘho tlaΦφtka na NextBtn a u pravΘho
tlaΦφtka na PriorBtn.
Pro formulß° musφme vytvo°it obsluhu udßlosti OnCreate. Je tvo°ena
p°φkazy:
FLastDate = EncodeDate(1995, 1, 1);
FLastAmount = 1000;
FilterOnRadioGroup->ItemIndex = 0;
N∞kterΘ komponenty majφ takΘ p°i°azeny obsluhy udßlostφ. Obsluha kliknutφ
na skupin∞ voliΦ∙ je tvo°ena p°φkazy:
FilterOnLabel->Caption =
FilterOnRadioGroup->Items->Strings[FilterOnRadioGroup->ItemIndex];
switch (FilterOnRadioGroup->ItemIndex)
{
case 0:
Orders->OnFilterRecord
= OrdersFilterOnDate;
FilterCriteria->Text =
AnsiString(FLastDate);
break;
case 1:
Orders->OnFilterRecord
= OrdersFilterOnAmount;
FilterCriteria->Text =
AnsiString(FLastAmount);
break;
}
ActiveControl = FilterCriteria;
if (Orders->Filtered)
Orders->Refresh();
Obsluhu OnExit editaΦnφho ovladaΦe tvo°φ p°φkaz:
ConvertFilterCriteria();
a obsluhu OnKeyPress p°φkazy:
if (Key == 0x13)
{
ConvertFilterCriteria();
Key = 0x00;
}
Obsluha kliknutφ na znaΦce je tvo°ena:
ConvertFilterCriteria();
Orders->Filtered = FilterCheckBox->Checked;
NextBtn->Enabled = ! FilterCheckBox->Checked;
PriorBtn->Enabled = ! FilterCheckBox->Checked;
Zb²vajφ je╣t∞ obsluhy stisku obou tlaΦφtek. Obsluha prvnφho je tvo°ena
p°φkazy:
ConvertFilterCriteria();
Orders->FindNext();
a obsluha druhΘho:
ConvertFilterCriteria();
Orders->FindPrior();
Tφm je formulß° hotov. Bude op∞t tvo°it ╣ablonu od kterΘ budeme odvozovat
formulß°e skuteΦn∞ pou╛φvanΘ aplikacφ. Vlastnost Name formulß°e
zm∞nφme na StdDataForm a formulß° ulo╛φme do souboru GdsData.
-
Nynφ se ji╛ budeme zab²vat hlavnφm formulß°em aplikace. Odvodφme jej od
prßv∞ vytvo°enΘho formulß°e (StdDataForm). Zvolφme File | New,
p°ejdeme na strßnku Project1, nastavφme voliΦ Inherit, vybereme
StdDataForm
a stiskneme OK.
Vlastnost Name vytvo°enΘho formulß°e zm∞nφme na GridViewForm,
na zb²vajφcφ plochu formulß°e p°idßme komponentu TDBGrid a nastavφme
u nφ: Align na alClient, DataSource na OrdersSource
a vytvo°φme pro nφ obsluhu dvojitΘho kliknutφ tvo°enou p°φkazem:
RecViewForm->Show();
Tφm je hlavnφ formulß° aplikace hotov. Zvolφme Project | Options
a zru╣φme vytvß°enφ na╣ich p∙vodnφch dvou formulß°∙ (╣ablon) a z poslednφho
formulß°e vytvo°φme hlavnφ formulß° aplikace. Ulo╛φme jej pod jmΘnem GridForm.
-
Dal╣φm formulß°em, kter² na╣e aplikace bude je╣t∞ po╛adovat, je formulß°
zobrazen² na nßsledujφcφm obrßzku.
Tento formulß° je op∞t odvozen od na╣i druhΘ ╣ablony. Zb²vajφcφ plochu
formulß°e zaplnφme panelem a na n∞j umφstφme komponenty podle p°edchozφho
obrßzku. Tento formulß° ji╛ neobsahuje ╛ßdn² k≤d a je zobrazovßn dvojit²m
kliknutφm na m°φ╛ce v p°edchozφm formulß°i (v tomto formulß°i jsou podrobnΘ
informace o vybranΘm zßkaznφkovi). Vlastnost Name formulß°e zm∞nφme
na RecViewForm a formulß° ulo╛φme do souboru RecForm. Podle
p°edchozφho obrßzku se pokuste dokonΦit v²voj aplikace sami.
![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/4/PreviousArrow.gif) ![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/4/NextArrow.gif) ![](/file/23411/Chip_2002-05_cd1.bin/chplus/cpp/4/WayUpArrow.gif) |
7. Prßce s datov²mi zdroji
|