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.
   |
7. Práce s datovými zdroji
|