6. Seznßmenφ s datov²mi mno╛inami

Zßkladnφ jednotkou pro zp°φstup≥ovßnφ dat v C++ Builderu je rodina objekt∙ datov²ch mno╛in. Na╣e aplikace pou╛φvß datovΘ mno╛iny pro ve╣ker² p°φstup k databßzφm. Obecn∞ objekt datovΘ mno╛iny reprezentuje urΦitou tabulku obsa╛enou v databßzi, nebo reprezentuje dotaz nebo ulo╛enou proceduru, kterΘ zp°φstup≥ujφ databßzi. V╣echny objekty datov²ch mno╛in, kterΘ pou╛φvßme v na╣ich databßzov²ch aplikacφch, jsou odvozeny od TDataSet a tedy od TDataSet d∞dφ datovΘ polo╛ky, vlastnosti, udßlosti a metody. Abychom mohli pou╛φvat libovoln² objekt datovΘ mno╛iny, musφme pochopit sdφlenou funkΦnost poskytnutou TDataSet.
Na nßsledujφcφm obrßzku je uvedena hierarchie v╣ech komponent datov²ch mno╛in.

TDataSet je p°edek v╣ech objekt∙ datov²ch mno╛in, kterΘ m∙╛eme pou╛φvat ve sv²ch aplikacφch. Definuje mno╛inu datov²ch polo╛ek, vlastnostφ, udßlostφ a metod sdφlen²ch v╣emi objekty datov²ch mno╛in. TDataSet je virtußlnφ datovß mno╛ina, co╛ znamenß, ╛e v∞t╣ina jejich vlastnostφ a metod je virtußlnφch nebo Φir²ch. Tyto virtußlnφ metody mohou b²t p°epsßny (a obvykle jsou) ve sv²ch potomcφch, ale v ka╛dΘm z nich mohou b²t implementovßny jinak. ╚irß virtußlnφ metoda je deklarovßna bez aktußlnφ implementace. Deklarace je prototyp, kter² popisuje metodu (a jejφ parametry a nßvratov² typ), kterß musφ b²t implementovßna ve v╣ech potomcφch.
Proto╛e TDataSet obsahuje ΦirΘ virtußlnφ metody, nem∙╛e b²t v na╣ich aplikacφch pou╛ita p°φmo. Musφme vytvß°et instance potomk∙ TDataSet jako je TTable, TQuery, TStoredProc a TClientDataSet a pou╛φt je ve svΘ aplikaci nebo odvodit svou vlastnφ t°φdu datovΘ mno╛iny od TDataSet nebo jeho potomk∙ a zapsat implementaci v╣ech jejich abstraktnφch metod.
TDataSet definuje v╣e, co je spoleΦnΘ pro v╣echny objekty datov²ch mno╛in. Nap°. TDataSet definuje zßkladnφ strukturu v╣ech datov²ch mno╛in: pole komponent TField, kterΘ odpovφdajφ sloupc∙m v jednΘ nebo vφce databßzov²ch tabulkßch a vyhledßvacφ nebo poΦitatelnΘ polo╛ky poskytnutΘ na╣i aplikaci.
V tΘto kapitole se seznßmφme s funkΦnostφ TDataSet, kterou d∞dφ objekty datov²ch mno╛in pou╛φvanΘ v na╣ich aplikacφch. Tuto sdφlenou funkΦnost musφme pochopit, abychom mohli pou╛φvat libovolnΘ objekty datov²ch mno╛in. Je popsßna v t∞chto bodech:

Typy datov²ch mno╛in

K pochopenφ spoleΦnΘ koncepce pro v╣echny objekty datov²ch mno╛in a jako p°φpravu pro v²voj sv²ch vlastnφch p°izp∙soben²ch datov²ch mno╛in, kterΘ pou╛φvajφ BDE, je zapot°ebφ se seznßmit s touto kapitolou.
K v²voji tradiΦnφch dvou vrstvov²ch databßzov²ch aplikacφ typu Klient/server pou╛φvajφcφch BDE se musφme takΘ seznßmit s BDE. ┌vod do TBDEDataSet a TDBDataSet a seznßmenφ s BDE bude uvedeno pozd∞ji. V tΘto kapitole jsou popsßny sdφlenΘ slu╛by nejΦast∞ji pou╛φvan²ch komponent datov²ch mno╛in TQuery, TStoredProc a TTable.
S n∞kter²mi verzemi C++ Builderu m∙╛eme vyvφjet vφce vrstvovΘ databßzovΘ aplikace pou╛φvajφcφ distribuovanΘ datovΘ mno╛iny. S pracφ klientsk²ch datov²ch mno╛in ve vφce vrstvov²ch aplikacφch se seznßmφme pozd∞ji.

Otevφrßnφ a uzavφrßnφ datov²ch mno╛in

Abychom mohli Φφst nebo zapisovat data tabulky (nebo dotazu), aplikace musφ nejprve otev°φt datovou mno╛inu. Datovou mno╛inu lze otev°φt dv∞mi zp∙soby. Nastavφme vlastnost Active datovΘ mno╛iny na true a to p°i nßvrhu v Inspektoru objekt∙ nebo k≤dem za b∞hu. Nap°.
CustTable->Active = true;
Druhou mno╛nostφ je volßnφ metody Open pro datovou mno╛inu za b∞hu:
CustQuery->Open();
Obdobn∞, datovou mno╛inu m∙╛eme takΘ uzav°φt dv∞mi zp∙soby. Vlastnost Active datovΘ mno╛iny nastavφme na false a to p°i nßvrhu v Inspektoru objekt∙ nebo k≤dem za b∞hu. Nap°.
CustQuery->Active = false;
Druhou mo╛nostφ je volßnφ metody Close pro datovou mno╛inu za b∞hu:
CustTable->Close();
Datovou mno╛inu musφme uzav°φt abychom mohli zm∞nit jistΘ jejφ vlastnosti (nap°. TableName komponenty TTable). Za b∞hu m∙╛eme takΘ chtφt uzav°φt datovou mno╛inu z jist²ch d∙vod∙ specifick²ch pro na╣i aplikaci.

Zji╣╗ovßnφ a nastavovßnφ stavu datovΘ mno╛iny

Stav nebo re╛im datovΘ mno╛iny urΦuje co lze provßd∞t s jejφmi daty. Nap°. kdy╛ datovß mno╛ina je uzav°ena, pak jejφ stav je dsInactive, co╛ znamenß, ╛e nenφ mo╛no nic provßd∞t s jejφmi daty. Za b∞hu, m∙╛eme testovat vlastnost datovΘ mno╛iny State (je urΦenß pouze pro Φtenφ) k zji╣t∞nφ jejφho souΦasnΘho stavu. Nßsledujφcφ tabulka uvßdφ mo╛nΘ hodnoty vlastnosti State a co tyto stavy znamenajφ:
 
Hodnota V²znam
dsInactive Uzav°enß datovß mno╛ina. Jejφ data jsou nedostupnß.
dsBrowse Otev°enß datovß mno╛ina. Jejφ data m∙╛eme prohlφ╛et, ale ne m∞nit. Je to implicitnφ stav otev°enΘ datovΘ mno╛iny.
dsEdit Otev°enß datovß mno╛ina. SouΦasn² °ßdek m∙╛e b²t modifikovßn.
dsInsert Otev°enß datovß mno╛ina. Je vklßdßn nebo p°idßvßn nov² °ßdek.
dsSetKey Pouze pro TTable nebo TClientDataSet. Otev°enß datovß mno╛ina. Umo╛≥uje nastavovat hodnoty rozsahu a klφΦe pou╛itΘ v operacφch rozsahu a GotoKey.
dsCalcFields Otev°enß datovß mno╛ina. Indikuje, ╛e mno╛ina je pod °φzenφm udßlosti OnCalcFields. Zabra≥uje zm∞nßm polo╛ek, kterΘ nejsou poΦitatelnΘ.
dsCurValue Pouze pro internφ pou╛itφ.
dsNewValue Pouze pro internφ pou╛itφ.
dsOldValue Pouze pro internφ pou╛itφ.
dsFilter Otev°enß datovß mno╛ina. Indikuje, ╛e mno╛ina je °φzena operacφ filtru. Filtrovanß mno╛ina dat m∙╛e b²t prohlφ╛ena a ╛ßdnß data nemohou b²t zm∞n∞na.

Kdy╛ aplikace otev°e datovou mno╛inu, pak je implicitn∞ uvedena do stavu dsBrowse. Stav datovΘ mno╛iny se m∞nφ podle toho jak aplikace zpracovßvß data. Otev°enou datovou mno╛inu p°evedeme z jednoho stavu do jinΘho, k≤dem na╣φ aplikace nebo vestav∞n²m chovßnφm datov²ch komponent. Pro p°evedenφ datovΘ mno╛iny do stavu dsEdit, dsBrowse, dsInsert nebo dsSetKey volßme metodu odpovφdajφcφ jmΘnu stavu. Nap°. nßsledujφcφ k≤d uvßdφ CustTable do stavu dsInsert, akceptuje vstup u╛ivatele jako nov² zßznam a zapisuje nov² zßznam do databßze:
CustTable->Insert(); // uvßdφ datovou mno╛inu do stavu dsInsert
AddressPromptDialog->ShowModal();
if (AddressPromptDialog->ModalResult == mrOK)
  CustTable->Post(); // p°i ·sp∞chu p°echod do stavu dsBrowse
else
  CustTable->Cancel(); // p°echod do stavu dsBrowse
Tento p°φklad takΘ ukazuje, ╛e stav datovΘ mno╛iny se automaticky zm∞nφ na dsBrowse, kdy╛ metoda Post ·sp∞╣n∞ zapφ╣e zßznam do databßze (p°i chyb∞ Post se stav datovΘ mno╛iny nem∞nφ) nebo kdy╛ je volßna metoda Cancel.
N∞kterΘ stavy nemohou b²t nastavovßny p°φmo. Nap°. k uvedenφ datovΘ mno╛iny do stavu dsInactive, nastavφme jejφ vlastnost Active na false nebo volßme metodu Close datovΘ mno╛iny. Nßsledujφcφ p°φkazy jsou ekvivalentnφ:
CustTable->Active = false;
CustTable->Close();
Zb²vajφcφ stavy (dsCalcField, dsCurValue, dsNewValue, dsOldValue a dsFilter) nemohou b²t nastavovßny na╣φ aplikacφ. Do t∞chto stav∙ datovß mno╛ina p°ejde automaticky, kdy╛ je to nutnΘ. Nap°. stav dsCalcField je nastaven, kdy╛ je generovßna udßlost OnCalcField. Kdy╛ udßlost OnCalcField skonΦφ, pak datovß mno╛ina se vrßtφ do p°edchozφho stavu.
Poznßmka: Kdy╛ se zm∞nφ stav datovΘ mno╛iny, pak je generovßna udßlost OnStateChange pro v╣echny komponenty datov²ch zdroj∙ p°i°azen²ch k datovΘ mno╛in∞.
V nßsledujφcφch bodech je provedeno seznßmenφ s t∞mito stavy, jak a kdy jsou stavy nastaveny, jakΘ jsou vztahy mezi jednotliv²mi stavy a kde najdeme pot°ebnΘ informace. Jsou zde uvedeny tyto body:

Deaktivovßnφ datovΘ mno╛iny
Datovß mno╛ina je neaktivnφ, kdy╛ je uzav°ena. Nem∙╛eme p°istupovat k zßznam∙m v uzav°enΘ datovΘ mno╛in∞. P°i nßvrhu, datovß mno╛ina je uzav°ena, dokud nenastavφme jejφ vlastnost Active na true. Za b∞hu je datovß mno╛ina uzav°ena dokud ji aplikace neotev°e volßnφm metody Open nebo nastavenφm vlastnosti Active na true. Kdy╛ otev°eme neaktivnφ datovou mno╛inu, pak jejφ stav se automaticky zm∞nφ na dsBrowse.
K ud∞lßnφ datovΘ mno╛iny neaktivnφ volßme jejφ metodu Close. M∙╛eme zapsat obsluhy udßlostφ OnBeforeClose a OnAfterClose, kterΘ reagujφ na metodu Close pro datovou mno╛inu. Nap°. pokud datovß mno╛ina je ve stavu dsEdit nebo dsInsert a aplikace volß Close, pak se aplikace m∙╛e dotßzat u╛ivatele, zda zm∞ny zapsat nebo zru╣it a to p°ed uzav°enφm datovΘ mno╛iny (v obsluze udßlosti OnBeforeClose):
void __fastcall TForm1::VerifyBeforeClose(TDataSet *DataSet)
{
  if (DataSet->State == dsEdit || DataSet->State == dsInsert)
  {
    TMsgDlgButtons btns;
    btns << mbYes << mbNo;
    if (MessageDlg("Post changes before closing?",mtConfirmation,btns,0)==mrYes)
      DataSet->Post();
    else
      DataSet->Cancel();
  }
}
Prohlφ╛enφ datovΘ mno╛iny
Kdy╛ aplikace otev°e datovou mno╛inu, pak datovß mno╛ina automaticky p°ejde do stavu dsBrowse. Tento stav umo╛≥uje prohlφ╛et zßznamy v datovΘ mno╛in∞, ale neumo╛≥uje jejich editaci nebo vklßdßnφ nov²ch zßznam∙. Ze stavu dsBrowse m∙╛eme p°ejφt do v╣ech ostatnφch stav∙. Nap°. volßnφm metody Insert nebo Append pro datovou mno╛inu zm∞nφme jejφ stav z dsBrowse na dsInsert (pokud to ostatnφ vlastnosti datovΘ mno╛iny umo╛≥ujφ). Volßnφ SetKey uvßdφ datovou mno╛inu do stavu dsSetKey.
Dv∞ metody p°i°azenΘ ke v╣em datov²m mno╛inßm, mohou vrßtit datovou mno╛inu do stavu dsBrowse. Cancel ukonΦuje souΦasnou editaΦnφ, vklßdacφ nebo vyhledßvacφ ·lohu a v╛dy vracφ datovou mno╛inu do stavu dsBrowse. Post se pokusφ zapsat zm∞ny do databßze a v p°φpad∞ ·sp∞chu takΘ vracφ datovou mno╛inu do stavu dsBrowse. P°i ne·sp∞chu se souΦasn² stav datovΘ mno╛iny nem∞nφ.
Umo╛n∞nφ editace datovΘ mno╛iny
Datovß mno╛ina musφ b²t ve stavu dsEdit, aby aplikace mohla modifikovat jejφ zßznamy. V na╣em k≤du m∙╛eme pou╛φt metodu Edit k uvedenφ datovΘ mno╛iny do stavu dsEdit, pokud vlastnost CanModify (urΦenß pouze pro Φtenφ) datovΘ mno╛iny je true. Vlastnost CanModify je true, pokud k databßzi spojenΘ s datovou mno╛inou mßme Φtecφ a zßpisovß privilegia.
N∞kterΘ datovΘ ovladaΦe na formulß°i v na╣i aplikaci mohou automaticky uvΘst datovou mno╛inu do stavu dsEdit, pokud: D∙le╛itΘ: Pro komponentu TTable, pokud vlastnost ReadOnly je true, pak CanModify je false, co╛ zabra≥uje editaci zßznam∙. Podobn∞ pro komponentu TQuery, pokud vlastnost RequestLive je false, pak CanModify je false.
Poznßmka: I kdy╛ datovß mno╛ina je ve stavu dsEdit, pak pro SQL databßze, editace zßznam∙ nemusφ b²t ·sp∞╣nß, pokud u╛ivatel na╣φ aplikace nemß pot°ebnß p°φstupovß privilegia.
Datovou mno╛inu m∙╛eme vrßtit ze stavu dsEdit do stavu dsBrowse v k≤du volßnφm metod Cancel, Post nebo Delete. Cancel zru╣φ editaci souΦasnΘ polo╛ky nebo zßznamu. Post se pokusφ zapsat modifikovan² zßznam do datovΘ mno╛iny a v p°φpad∞ ·sp∞chu vracφ datovou mno╛inu do stavu dsBrowse (p°i ne·sp∞chu se stav nem∞nφ). Delete se pokusφ odstranit souΦasn² zßznam z datovΘ mno╛iny a v p°φpad∞ ·sp∞chu vracφ datovou mno╛inu do stavu dsBrowse (v p°φpad∞ ne·sp∞chu datovß mno╛ina z∙stßvß ve stavu dsEdit).
DatovΘ ovladaΦe pro kterΘ editace je povolena, automaticky volajφ Post, kdy╛ u╛ivatel provede libovolnou akci, kterß m∞nφ souΦasn² zßznam (p°esun na jin² zßznam) nebo kterß zp∙sobφ, ╛e ovladaΦ ztrßcφ zaost°enφ (p°esun na jin² ovladaΦ na formulß°i).
Umo╛n∞nφ vklßdßnφ nov²ch zßznam∙
Datovß mno╛ina musφ b²t ve stavu dsInsert, aby aplikace mohla k nφ p°idat nov² zßznam. V na╣em k≤du m∙╛eme pou╛φt metodu Insert nebo Append k uvedenφ datovΘ mno╛iny do stavu dsInsert, pokud vlastnost urΦenß pouze pro Φtenφ CanModify datovΘ mno╛iny je false. Pro stav dsInsert platφ v╣e, co je v²╣e uvedeno pro stav dsEdit.
Umo╛n∞nφ prohledßvßnφ datov²ch mno╛in
Libovolnou datovou mno╛inu m∙╛eme prohledßvat pomocφ metod Locate a Lookup. Komponenty TTable poskytujφ dal╣φ metody (GotoKey a FindKey), kterß umo╛≥ujφ vyhledßvat zßznamy na zßklad∞ indexu tabulky. Pro pou╛itφ t∞chto metod pro komponentu tabulky, komponenta musφ b²t ve stavu dsSetKey. Stav dsSetKey je aplikovateln² pouze na komponenty TTable. Datovou mno╛inu uvedeme do stavu dsSetKey za b∞hu volßnφm metody SetKey. Metody GotoKey, GotoNearest, FindKey a FindNearest ukonΦujφcφ souΦasnΘ hledßnφ vracejφ datovou mno╛inu do stavu dsBrowse po dokonΦenφ vyhledßvßnφ.
M∙╛eme zobrazit a editovat podmno╛inu dat pro libovolnou datovou mno╛inu pomocφ filtr∙. Komponenta TTable takΘ podporuje dal╣φ zp∙sob p°φstupu k podmno╛in∞ zßznam∙, nazvan² rozsah. K vytvo°enφ a aplikovßnφ rozsahu na tabulku, tabulka musφ b²t ve stavu dsSetKey.
PoΦitatelnΘ polo╛ky
C++ Builder uvßdφ datovou mno╛inu do re╛imu dsCalcFields, kdy╛ aplikace volß obsluhu udßlosti OnCalcFields datovΘ mno╛iny. Tento stav zabra≥uje modifikacφm nebo p°idßvßnφ zßznam∙ do datovΘ mno╛iny, mimo modifikace poΦitateln²ch polo╛ek modifikovan²ch obsluhou. V╣echny ostatnφ modifikace jsou zakßzßny, proto╛e OnCalcFields pou╛φvß hodnoty ostatnφch polo╛ek k odvozenφ hodnot poΦitateln²ch polo╛ek. Zm∞ny na t∞chto ostatnφch polo╛kßch by mohli znehodnotit hodnoty p°i°azenΘ poΦitateln²m polo╛kßm. Kdy╛ obsluha OnCalcFields skonΦφ, pak datovß mno╛ina se vrßtφ do stavu dsBrowse.
Filtrovßnφ zßznam∙
Kdy╛ aplikace volß obsluhu udßlosti OnFilterRecord datovΘ mno╛iny, pak C++ Builder uvßdφ datovou mno╛inu do stavu dsFilter. Tento stav zabra≥uje modifikacφm nebo p°idßvßnφ zßznam∙ do datovΘ mno╛iny b∞hem procesu filtrovßnφ a tedy filtr nem∙╛e b²t znehodnocen. Po dokonΦenφ obsluhy OnFilterRecord, se datovß mno╛ina vracφ do stavu dsBrowse.
Aktualizovßnφ zßznam∙
Kdy╛ provßdφme operace odlo╛en²ch aktualizacφ, pak C++ Builder m∙╛e uvΘst datovou mno╛inu doΦasn∞ do stavu dsNewValue, dsOldValue nebo dsCurValue. Tyto stavy indikujφ, ╛e odpovφdajφcφ vlastnosti polo╛kov²ch komponent (NewValue, OldValue a CurValue) mohou b²t zp°φstupn∞ny a to obvykle v obsluze udßlosti OnUpdateError. Na╣e aplikace nem∙╛e vid∞t nebo nastavovat tyto stavy.

Prochßzenφ datov²mi mno╛inami

Ka╛dß aktivnφ datovß mno╛ina mß kurzor (ukazatel na souΦasn² °ßdek v datovΘ mno╛in∞). SouΦasn² °ßdek v datovΘ mno╛in∞ je ten, jeho╛ hodnoty mohou b²t zpracovßny metodami editace, vklßdßnφ a ru╣enφ a ten jeho╛ hodnoty polo╛ek jsou prßv∞ zobrazeny v jednotliv²ch polo╛kov²ch datov²ch ovladaΦφch na formulß°i, jako je nap°. TDBEdit, TDBLabel nebo TDBMemo.
SouΦasn² °ßdek m∙╛eme zm∞nit p°esunem kurzoru k ukazovßnφ na jin² °ßdek. Nßsledujφcφ tabulka uvßdφ metody, kterΘ m∙╛eme pou╛φt v k≤du aplikace k p°esunu na jin² zßznam:
 
Metoda Popis
First P°esouvß kurzor k ukazovßnφ na prvnφ °ßdek v datovΘ mno╛in∞.
Last P°esouvß kurzor k ukazovßnφ na poslednφ °ßdek v datovΘ mno╛in∞.
Next P°esouvß kurzor k ukazovßnφ na nßsledujφcφ °ßdek v datovΘ mno╛in∞.
Prior P°esouvß kurzor k ukazovßnφ na p°edchozφ °ßdek v datovΘ mno╛in∞.
MoveBy P°esouvß kurzor o specifikovan² poΦet °ßdk∙ dop°edu nebo zp∞t v datovΘ mno╛in∞.

Vizußlnφ datov² ovladaΦ TDBNavigator zaobaluje tyto metody jako tlaΦφtka, kterß u╛ivatel m∙╛e stisknout k pohybu po zßznamech za b∞hu aplikace.
Mimo t∞chto metod, dal╣φ tabulka popisuje dv∞ logickΘ vlastnosti datovΘ mno╛iny, kterΘ poskytujφ u╛iteΦnΘ informace p°i prochßzenφ zßznamy datovΘ mno╛iny:
 
Vlastnost Popis
Bof true pokud kurzor je na prvnφm °ßdku v datovΘ mno╛in∞; false v opaΦnΘm p°φpad∞
Eof true pokud kurzor je na poslednφm °ßdku v datovΘ mno╛in∞; false v opaΦnΘm p°φpad∞

V tΘto Φßsti jsou uvedeny je╣t∞ tyto body:

Pou╛φvßnφ metod First a Last
Metoda First p°esouvß kurzor na prvnφ °ßdek v datovΘ mno╛in∞ a nastavuje vlastnost Bof na true. Pokud kurzor je ji╛ na prvnφm °ßdku datovΘ mno╛iny, pak First nic ned∞lß. Nap°. nßsledujφcφ k≤d p°esouvß kurzor na prvnφ zßznam v CustTable:
CustTable->First();
Metoda Last p°esouvß kurzor na poslednφ °ßdek v datovΘ mno╛in∞ a nastavuje vlastnost Eof na true. Pokud kurzor je ji╛ na poslednφm °ßdku datovΘ mno╛iny, pak Last nic ned∞lß. Nap°. nßsledujφcφ k≤d p°esouvß kurzor na poslednφ zßznam v CustTable:
CustTable->Last();
Poznßmka: I kdy╛ mohou b²t r∙znΘ d∙vody pro p°echod na prvnφ nebo poslednφ °ßdek v datovΘ mno╛in∞ bez intervence u╛ivatele, m∙╛eme povolit u╛ivateli p°echod ze zßznamu na zßznam pomocφ komponenty TDBNavigator. Tato komponenta obsahuje tlaΦφtka, kterß umo╛≥ujφ u╛ivateli p°esun na prvnφ nebo poslednφ °ßdek aktivnφ datovΘ mno╛iny. Udßlost OnClick t∞chto tlaΦφtek volß metody First nebo Last datovΘ mno╛iny.
Pou╛φvßnφ metod Next a Prior
Metoda Next p°esouvß kurzor dop°edu o jeden °ßdek v datovΘ mno╛in∞ a nastavuje Bof na false, pokud datovß mno╛ina nenφ prßzdnß. Pokud kurzor je ji╛ na poslednφm °ßdku datovΘ mno╛iny, pak volßnφ Next nic ned∞lß. Nap°. nßsledujφcφ k≤d p°esouvß kurzor na nßsledujφcφ zßznam v CustTable:
CustTable->Next();
Metoda Prior p°esouvß kurzor zp∞t o jeden °ßdek v datovΘ mno╛in∞ a nastavuje Eof na false, pokud datovß mno╛ina nenφ prßzdnß. Pokud kurzor je ji╛ na prvnφm °ßdku datovΘ mno╛iny, pak volßnφ Prior nic ned∞lß. Nap°. nßsledujφcφ k≤d p°esouvß kurzor na p°edchßzejφcφ zßznam v CustTable:
CustTable->Prior();
Po╛φvßnφ metody MoveBy
MoveBy umo╛≥uje specifikovat o kolik °ßdk∙ dop°edu nebo dozadu p°esunout kurzor v datovΘ mno╛in∞. P°esun je relativnφ k souΦasnΘmu zßznamu v dob∞, kdy MoveBy je volßno. MoveBy takΘ nastavuje vlastnosti Bof a Eof datovΘ mno╛iny podle skuteΦnΘho stavu. Tato metoda p°ebφrß celoΦφseln² parametr urΦujφcφ o kolik °ßdk∙ se p°esouvßme. Kladnß Φφsla indikujφ sm∞r dop°edu a zßpornß p°esun zp∞t.
MoveBy vracφ poΦet °ßdk∙ o kter² byl proveden p°esun. Pokud se pokusφme provΘst p°esun o vφce °ßdk∙ ne╛ kolik jich je k zaΦßtku nebo konci datovΘ mno╛iny, pak poΦet °ßdk∙ vrßcen² MoveBy se li╣φ od poΦtu °ßdk∙ po╛adovanΘho p°esunu. P°esun konΦφ p°i dosa╛enφ prvnφho nebo poslednφho °ßdku v datovΘ mno╛in∞. Nßsledujφcφ k≤d p°esouvß kurzor o dva zßznamy zp∞t v CustTable:
CustTable->MoveBy(-2);
Poznßmka: Pokud pou╛φvßme MoveBy ve svΘ aplikaci a pracujeme ve vφceu╛ivatelskΘm databßzovΘm prost°edφ, nesmφme zapomenout, ╛e databßze se m∞nφ. Zßznam, kter² byl o p∞t zßznam∙ zp∞t m∙╛e b²t nynφ o Φty°i, ╣est nebo neznßm² poΦet zßznam∙ zp∞t, proto╛e n∞kolik u╛ivatel∙ m∙╛e souΦasn∞ p°istupovat k databßzi a m∞nit jejφ data.
Pou╛φvßnφ vlastnostφ Eof a Bof
B∞hovΘ vlastnosti (urΦenΘ pouze pro Φtenφ) Eof (End of file) a Bof (Begin of file) jsou u╛iteΦnΘ pro prochßzenφ datovou mno╛inou, obzvlß╣t∞ kdy╛ chceme prochßzet v╣emi zßznamy v datovΘ mno╛in∞.
Kdy╛ Eof je true, pak kurzor je na poslednφm °ßdku v datovΘ mno╛in∞. Eof je true, pokud aplikace otev°e prßzdnou datovou mno╛inu, volß metodu Last datovΘ mno╛iny, volß metodu Next datovΘ mno╛iny a metoda je ne·sp∞╣nß nebo╗ kurzor je na poslednφm °ßdku datovΘ mno╛iny nebo volß SetRange na prßzdn² rozsah nebo datovou mno╛inu. Eof je v ostatnφch p°φpadech nastaveno na false.
Eof je Φasto testovßno v podmφnkßch cykl∙ k °φzenφ procesu iterace v╣emi zßznamy v databßzi. Pokud otev°eme datovou mno╛inu obsahujφcφ zßznamy (nebo volßme First), pak Eof je false. K prochßzenφ zßznamy datovΘ mno╛iny vytvo°φme cyklus, kter² je ukonΦen, kdy╛ Eof je true. Uvnit° cyklu volßme Next pro ka╛d² zßznam v datovΘ mno╛in∞. Eof je false dokud Next nep°ejde na poslednφ zßznam. Nßsledujφcφ p°φklad k≤du ukazuje jeden zp∙sob prochßzenφ zßznamy datovΘ mno╛iny nazvanΘ CustTable:
CustTable->DisableControls();
try
{
  CustTable->First();     // p°echod na prvnφ zßznam
  while (!CustTable->Eof) // cyklus dokud Eof nenφ true
  (
    // Zpracovßnφ ka╛dΘho zßznamu
    ...
    CustTable->Next();
    // kdy╛ jsme na poslednφm zßznamu, pak Eof je true; jinak je false
  }
}
__finally
{
  CustTable->EnableControls();
}
Tip: Tento p°φklad takΘ ukazuje jak zakßzat a povolit vizußlnφ datovΘ ovladaΦe spojenΘ s datovou mno╛inou. Pokud vizußlnφ datovΘ ovladaΦe b∞hem prochßzenφ datovou mno╛inou zakß╛eme, pak proces iterace je urychlen, nebo╗ C++ Builder nemusφ aktualizovat obsah t∞chto ovladaΦ∙ p°i zm∞n∞ aktußlnφho zßznamu. Po dokonΦenφ iterace, ovladaΦe op∞t povolφme, aby obsahovaly hodnoty pro nov² souΦasn² °ßdek. Pov╣imn∞te si, ╛e povolenφ ovladaΦ∙ je vlo╛eno do klauzule __finally p°φkazu try ... __finally. Tφm zajistφme, ╛e i kdy╛ v²jimka ukonΦφ cyklus p°edΦasn∞, ovladaΦe nez∙stanou zakßzanΘ.
Bof je true, kdy╛ kurzor je na prvnφm °ßdku datovΘ mno╛iny. Bof je nastaveno na true, kdy╛ aplikace otev°e datovou mno╛inu, volß metodu First datovΘ mno╛iny, volß metodu Prior datovΘ mno╛iny kdy╛ kurzor je na jejφm prvnφm °ßdku nebo volß SetRange na prßzdn² rozsah nebo datovou mno╛inu. V ostatnφch p°φpadech je Bof nastaveno na false.
Podobn∞ jako Eof i Bof m∙╛e b²t pou╛ito v podmφnkßch cykl∙ p°i °φzenφ iteraΦnφho zpracovßnφ zßznam∙ v datovΘ mno╛in∞. Ukazuje to nßsledujφcφ k≤d:
CustTable->DisableControls(); // urychlenφ zpracovßnφ
try
{
  while (!CustTable->Bof)     // cyklus dokud Bof je true
  (
    // zpracovßnφ ka╛dΘho zßznamu
    ...
    CustTable->Prior();
  }
}
catch (...)
{
  CustTable->EnableControls();
  throw;
}
CustTable->EnableControls();
OznaΦovßnφ a nßvrat na zßznamy
Mimo p°esunu ze zßznamu na zßznam v datovΘ mno╛in∞, je Φasto takΘ u╛iteΦnΘ oznaΦit jistΘ mφsto v datovΘ mno╛in∞, abychom se na n∞ mohli rychle vrßtit, kdy╛ je pot°eba. TDataSet a jeho potomci implementujφ slu╛bu zßlo╛ek, kterß umo╛≥uje oznaΦit zßznamy a pozd∞ji se na n∞ vracet. Slu╛ba zßlo╛ek se sklßdß z vlastnosti Bookmark a p∞ti metod pro prßci se zßlo╛kami.
Vlastnost Bookmark indikuje, kterß zßlo╛ka z mnoha zßlo╛ek v na╣i aplikaci je aktußlnφ. Bookmark je °et∞zec, kter² identifikuje aktußlnφ zßlo╛ku. Kdykoliv m∙╛eme p°edat dal╣φ zßlo╛ku, kterß se stßvß aktußlnφ zßlo╛kou.
TDataSet implementuje virtußlnφ metody zßlo╛ek. I kdy╛ tyto metody zaji╣╗ujφ, ╛e libovoln² objekt odvozen² od TDataSet vracφ p°i volßnφ metody zßlo╛ky hodnotu, vrßcenß hodnota je implicitnφ a neurΦuje souΦasnΘ mφsto. Potomci TDataSet, jako je TBDEDataSet, reimplementujφ metody zßlo╛ek k nßvratu rozumn²ch hodnot podle nßsledujφcφho seznamu: Pro vytvo°enφ zßlo╛ky v na╣i aplikaci musφme deklarovat prom∞nnou typu TBookmark, pak volat GetBookmark k alokovßnφ mφsta pro prom∞nnou a nastavenφ jejφ hodnoty na jistΘ mφsto v datovΘ mno╛in∞. Prom∞nnß TBookmark je ukazatel (void *).
P°ed volßnφm GotoBookmark k p°esunu na specifikovan² zßznam, m∙╛eme volat BookmarkValid k urΦenφ zda zßlo╛ka ukazuje na zßznam. BookmarkValid vracφ true, pokud specifikovanß zßlo╛ka na zßznam ukazuje. V TDataSet, BookmarkValid v╛dy vracφ false (indikace, ╛e zßlo╛ka nenφ p°φpustnß). Potomci TDataSet metodu reimplementujφ k poskytnutφ smysluplnΘ nßvratovΘ hodnoty.
M∙╛eme takΘ volat CompareBookmarks k zji╣t∞nφ zda se chceme p°esunout na jinou (ne souΦasnou) zßlo╛ku. TDataSet::CompareBookmarks v╛dy vracφ 0 (indikace, ╛e zßlo╛ky jsou identickΘ). Potomci TDataSet tuto metodu reimplementujφ k nßvratu smysluplnΘ hodnoty.
Kdy╛ zßlo╛ku p°edßme GotoBookmark, pak kurzor datovΘ mno╛iny je p°esunut na mφsto specifikovanΘ v zßlo╛ce. TDataSet::GotoBookmark je Φirß abstraktnφ metoda. Potomci TDataSet ji smyslupln∞ reimplementujφ.
FreeBookmark uvol≥uje pam∞╗ alokovanou pro specifikovanou zßlo╛ku, kdy╛ ji╛ nenφ zapot°ebφ. FreeBookmark m∙╛eme takΘ volat p°ed op∞tovn²m pou╛itφm existujφcφ zßlo╛ky.
Nßsledujφcφ k≤d ukazuje jedno z mo╛n²ch pou╛itφ zßlo╛ky:
void DoSomething (const TTable *Tbl)
{
  TBookmark Bookmark=Tbl->GetBookmark();//Alokovßnφ pam∞ti a p°i°azenφ hodnoty
  Tbl->DisableControls(); // Vypnutφ zobrazovßnφ hodnot v datov²ch ovladaΦφch
  try
  {
    Tbl->First(); // P°echod na prvnφ zßznam v tabulce
    while (!Tbl->Eof) // Prochßzenφ v╣emi zßznamy tabulky
    {
      // Na╣e zpracovßnφ zßznam∙
      ...
      Tbl->Next();
    }
  }
  __finally
  {
    Tbl->GotoBookmark(Bookmark);
    Tbl->EnableControls(); // Zapnutφ zobrazovßnφ hodnot v datov²ch ovladaΦφch
    Tbl->FreeBookmark(Bookmark); // Dealokace pam∞ti pro zßlo╛ku
    throw;
  }
}
P°ed prochßzenφm zßznamy jsou ovladaΦe zakßzßny. Pokud v pr∙b∞hu prochßzenφ zßznamy vznikne chyba, pak klauzule __finally zajistφ, ╛e ovladaΦe jsou povoleny a zßlo╛ka uvoln∞na a to i p°i p°edΦasnΘm ukonΦenφ cyklu.

Prohledßvßnφ datovΘ mno╛iny

V libovolnΘ datovΘ mno╛in∞ m∙╛eme hledat urΦit² zßznam pomocφ obecn²ch prohledßvacφch metod Locate a Lookup. Tyto metody umo╛≥ujφ hledßnφ v libovolnΘm typu sloupce v libovolnΘ datovΘ mno╛in∞. Budou popsßny v t∞chto bodech:
Pou╛φvßnφ Locate
Locate p°esouvß kurzor na prvnφ °ßdek odpovφdajφcφ specifikovan²m vyhledßvacφm kritΘriφm. V nejjednodu╣╣φm tvaru, p°edßme Locate jmΘno prohledßvanΘho sloupce, hledanou hodnotu a p°φznaky voleb urΦujφcφ zda p°i hledßnφ rozli╣ovat velikost pφsmen nebo zda pou╛φvat ΦßsteΦnΘ vyhledßvßnφ. Nap°. nßsledujφcφ k≤d p°esouvß kurzor na prvnφ °ßdek, kde hodnota ve sloupci Company je Professional Divers, Ltd.:
TLocateOptions SearchOptions;
SearchOptions.Clear();
SearchOptions << loPartialKey;
bool LocateSuccess=CustTable->Locate("Company","Professional Divers, Ltd.",
                                     SearchOptions);
Jestli╛e Locate nalezne vyhovujφcφ zßznam, pak tento zßznam se stane souΦasn²m a Locate vracφ true. Nenφ-li vyhovujφcφ zßznam nalezen, pak Locate vracφ false a souΦasn² zßznam se nem∞nφ.
Locate m∙╛eme pou╛φt i pro hledßnφ ve vφce sloupcφch a m∙╛eme specifikovat vφce hodnot pro hledßnφ. HledanΘ hodnoty jsou variantami (datov² typ umo╛≥ujφcφ pou╛φvßnφ libovolnΘho datovΘho typu), co╛ umo╛≥uje specifikovat ve vyhledßvacφch kritΘriφch r∙znΘ datovΘ typy. P°i specifikaci vφce sloupc∙ ve vyhledßvacφm °et∞zci, odd∞lujeme jednotlivΘ prvky v °et∞zci st°ednφky. Proto╛e vyhledßvanΘ hodnoty jsou variantami, pak p°i p°edßvßnφ vφce hodnot musφme jako parametr p°edat pole typu variant (nap°. hodnoty vrßcenΘ metodou Lookup) nebo musφme vytvo°it pole variant pomocφ funkce VarArrayOf.
Nßsledujφcφ k≤d ukazuje hledßnφ ve vφce sloupcφch pomocφ vφce vyhledßvan²ch hodnot a pou╛itφ vyhledßvßnφ typu ΦßsteΦnΘho klφΦe:
TLocateOptions Opts;
Opts.Clear();
Opts << loPartialKey;
Variant locvalues[2];
locvalues[0] = Variant("Sight Diver");
locvalues[1] = Variant("P");
CustTable->Locate("Company;Contact", VarArrayOf(locvalues, 1), Opts);
Locate pou╛φvß nejrychlej╣φ mo╛nou metodu k lokalizaci hledanΘho zßznamu. Pokud prohledßvan² sloupec je indexovßn a index je kompatibilnφ s nßmi urΦenou volbou hledßnφ, pak Locate pou╛ije index.
Pou╛φvßnφ Lookup
Lookup hledß prvnφ °ßdek, kter² vyhovuje specifikovan²m vyhledßvacφm kritΘriφm. P°i nalezenφ °ßdku, jsou provedena p°epoΦφtßnφ v╣ech poΦitateln²ch polo╛ek a vyhledßvacφch polo╛ek p°i°azen²ch k datovΘ mno╛in∞ a potom metoda vrßtφ jednu nebo vφce polo╛ek z nalezenΘho °ßdku. Lookup nep°esouvß kurzor na nalezen² °ßdek, pouze z n∞j vracφ hodnoty.
V nejjednodu╣╣φ form∞, p°edßme Lookup jmΘno prohledßvanΘho sloupce, hledanou hodnotu a vracenou polo╛ku nebo polo╛ky. Nap°. nßsledujφcφ k≤d hledß prvnφ °ßdek v CustTable, kde ve sloupci Company je hodnota Professional Divers, Ltd. a vracφ jmΘno podniku, kontaktnφ osobu a telefonnφ Φφslo:
Variant LookupResults = CustTable->Lookup("Company",
        "Professional Divers, Ltd", "Company;Contact;Phone");
Lookup vracφ hodnoty specifikovan²ch polo╛ek z prvnφho vyhovujφcφho zßznamu. Hodnoty jsou vraceny jako varianty. Jestli╛e je po╛adovßno vracenφ vφce hodnot, pak Lookup vracφ pole typu Variant. Pokud ╛ßdn² zßznam nevyhovuje, pak Lookup vracφ prßzdnou variantu. Vφce informacφ o polφch variant naleznete v nßpov∞d∞.
Lookup takΘ umo╛≥uje hledßnφ ve vφce sloupcφch a specifikovat vφce hodnot pro hledßnφ. Ve specifikaci °et∞zc∙ obsahujφcφch vφce sloupc∙ nebo v²sledkov²ch polo╛ek, odd∞lujeme jednotlivΘ polo╛ky st°ednφky. Proto╛e hledanΘ hodnoty jsou variantami, pak p°i p°edßvßnφ vφce hodnot, musφme p°edat jako parametr pole typu Variant (nap°. vrßcenΘ hodnoty z metody Lookup) nebo musφme vytvo°it pole variant pomocφ funkce VarArrayOf. Nßsledujφcφ k≤d ukazuje hledßnφ ve vφce sloupcφch:
Variant LookupResults;
Variant locvalues[2];
Variant v;
locvalues[0] = Variant("Sight Diver");
locvalues[1] = Variant("Kato Paphos");
LookupResults = CustTable->Lookup("Company;City", VarArrayOf(locvalues, 1),
                "Company;Addr1;Addr2;State;Zip");
// v²sledek vlo╛φme do globßlnφho seznamu °et∞zc∙ (vytvo°enΘho n∞kde jinde)
pFieldValues->Clear();
for (int i = 0; i < 5; i++) // Lookup po╛adoval 5 polo╛ek
{
  v = LookupResults.GetElement(i);
  if (v.IsNull())
    pFieldValues->Add("");
  else
    pFieldValues->Add(v);
}
Lookup pou╛φvß nejrychlej╣φ mo╛nou metodu k nalezenφ vyhovujφcφho zßznamu. Jestli╛e prohledßvanΘ sloupce jsou indexovßny, pak Lookup index pou╛ije.

Zobrazovßnφ a editace podmno╛iny dat pomocφ filtr∙

Aplikaci Φasto zajφmß pouze podmno╛ina zßznam∙ v datovΘ mno╛in∞. Nap°. nßs mohou zajφmat pouze zßznamy obsahujφcφ jistou mno╛inu hodnot polo╛ek. V t∞chto p°φpadech m∙╛eme pou╛φt filtry k omezenφ p°φstupu aplikace k podmno╛in∞ v╣ech zßznam∙ v datovΘ mno╛in∞.
Filtr specifikuje podmφnku, kterou zßznam musφ spl≥ovat, aby byl zobrazen. Podmφnka filtru m∙╛e b²t zadßna ve vlastnosti Filter datovΘ mno╛iny nebo zak≤dovßna v jejφ obsluze udßlosti OnFilteredRecord. Podmφnky filtru jsou zalo╛eny na hodnotßch v n∞kolika specifikovan²ch polo╛kßch v datovΘ mno╛in∞ a to bez ohledu na to, zda tyto polo╛ky jsou indexovßny. Nap°. k zobrazenφ pouze t∞ch zßznam∙, kterΘ se t²kajφ Kalifornie, m∙╛eme pou╛φt filtr, kde budeme ve sloupci State po╛adovat hodnotu "CA".
Poznßmka: Filtry jsou aplikovßny na v╣echny zßznamy zφskanΘ z datovΘ mno╛iny. Kdy╛ chceme filtrovat velkΘ mno╛stvφ dat, pak je v²hodn∞j╣φ pou╛φt k omezenφ zφskan²ch zßznam∙ dotaz nebo nastavit rozsah pro indexovanou tabulku.
V tΘto sekci jsou uvedeny nßsledujφcφ body:
Povolenφ a zakazovßnφ filtrovßnφ
Povolovßnφ filtrovßnφ datovΘ mno╛iny je t°φkrokov² proces:
  1. Vytvo°φme filtr.
  2. Nastavφme volby filtru pro testovßnφ zalo╛enΘm na °et∞zcφch (je-li pot°eba).
  3. Nastavφme vlastnost Filtered na true.
Kdy╛ je filtrovßnφ povoleno, pak aplikace zφskßvß pouze ty zßznamy, kterΘ spl≥ujφ filtrovacφ kriteria. Filtrovßnφ je v╛dy doΦasn² proces. M∙╛eme jej vypnout nastavenφm vlastnosti Filtered na false.

Vytvo°enφ filtru
Jsou dva zp∙soby vytvß°enφ filtr∙ pro datovou mno╛inu:

Specifikujeme podmφnku ve vlastnosti Filter
Hlavnφ v²hodou vytvß°enφ filtr∙ pomocφ vlastnosti Filter je to, ╛e na╣e aplikace m∙╛e vytvß°et, m∞nit a aplikovat filtr dynamicky (nap°. v zßvislosti na vstupu u╛ivatele). Hlavnφ nev²hodou je to, ╛e filtrovacφ podmφnka musφ b²t vyjßd°ena jako jednoduch² textov² °et∞zec, nem∙╛e pou╛φvat konstrukce v∞tvenφ a cykl∙ a nem∙╛e testovat nebo porovnßvat svΘ hodnoty s hodnotami, kterΘ nejsou v datovΘ mno╛in∞.
V²hodou udßlosti OnFilterRecord je to, ╛e filtr m∙╛e b²t slo╛it² a prom∞nn², m∙╛e b²t vytvo°en vφce °ßdky k≤du pou╛φvajφcφ v∞tvenφ a cykly a m∙╛e testovat hodnoty datovΘ mno╛iny s hodnotami mimo datovou mno╛inu (nap°. textem v editaΦnφm ovladaΦi). Nev²hodou je to, ╛e filtr je vytvo°en b∞hem nßvrhu a nem∙╛e b²t modifikovßn v zßvislosti na vstupu u╛ivatele. M∙╛eme ale vytvo°it n∞kolik obsluh udßlostφ a p°epφnat se mezi nimi.
K vytvo°enφ filtru pomocφ vlastnosti Filter, nastavφme hodnotu tΘto vlastnosti na °et∞zec obsahujφcφ filtrovacφ podmφnku. Nap°. nßsledujφcφ p°φkaz vytvß°φ filtr, kter² testuje polo╛ku State datovΘ mno╛iny na hodnotu pro stßt Kalifornie:
Dataset1->Filter = "State = 'CA'";
M∙╛eme takΘ dodat hodnotu pro Filter na zßklad∞ textu zadanΘho v ovladaΦi. Nap°. nßsledujφcφ p°φkaz p°i°azuje vlastnosti Filter text z editaΦnφho ovladaΦe:
Dataset1->Filter = Edit1->Text;
╪et∞zec m∙╛eme takΘ vytvo°it z pevnΘho textu a dat zadan²ch u╛ivatelem v ovladaΦi:
Dataset1->Filter = AnsiString("State = '") + Edit1->Text + "'";
Po specifikaci hodnoty pro Filter, aplikujeme filtr na datovou mno╛inu nastavenφm vlastnosti Filtered na true. M∙╛eme porovnßvat hodnoty polo╛ek s konstantami a pou╛φvat nßsledujφcφ operßtory: < > >= <= = <> AND NOT OR. Pomocφ kombinace t∞chto operßtor∙, m∙╛eme vytvß°et slo╛it∞j╣φ filtry. Nap°. nßsledujφcφ podmφnka pou╛φvß operßtor AND:
(Custno > 1400) AND (Custno < 1500);
Poznßmka: P°i zapnutΘm filtrovßnφ, editace zßznam∙ m∙╛e zp∙sobit, ╛e zßznam p°estßvß spl≥ovat podmφnku filtru. Tento zßznam tedy ji╛ nenφ dßle zφskßvßn z datovΘ mno╛iny. Pokud toto nastane, pak souΦasn²m zßznamem se stane dal╣φ zßznam spl≥ujφcφ podmφnku filtru.

Zßpis obsluhy udßlosti OnFilterRecord
Filtr pro datovou mno╛inu m∙╛e b²t takΘ obsluha udßlosti OnFilterRecord generovanß pro ka╛d² zßznam zφskan² z datovΘ mno╛iny. Jßdrem ka╛dΘ obsluhy filtru je test, kter² urΦuje zda zßznam bude za°azen mezi ty, kterΘ jsou viditelnΘ aplikacφ.
K indikaci, zda zßznam spl≥uje podmφnku filtru, na╣e obsluha filtru musφ nastavit parametr Accept na true k akceptovßnφ zßznamu, nebo na false k odmφtnutφ zßznamu. Nap°. nßsledujφcφ filtr propou╣tφ pouze ty zßznamy, kde polo╛ka State mß hodnotu "CA".
void __fastcall TForm1::Table1FilterRecord(TDataSet *DataSet; bool &Accept)
{
  Accept = DataSet->FieldByName["State"]->AsString == "CA";
}
Kdy╛ filtrovßnφ je povoleno, pak udßlost OnFilterRecord je generovßna pro ka╛d² zφskan² zßznam. Obsluha udßlosti testuje ka╛d² zßznam a pouze ty, kterΘ spl≥ujφ podmφnku filtru jsou propou╣t∞ny. Proto╛e udßlost OnFilterRecord je generovßna pro ka╛d² zßznam v datovΘ mno╛in∞, musφme se sna╛it, aby k≤d obsluhy byl co nejkrat╣φ aby nebyla snφ╛ena v²konnost aplikace.
M∙╛eme k≤dovat n∞kolik obsluh udßlostφ filtr∙ a p°epφnat se mezi nimi za b∞hu. K p°epnutφ na jinou obsluhu udßlosti za b∞hu, p°i°adφme novou obsluhu udßlosti vlastnosti OnFilterRecord datovΘ mno╛iny. Nap°. nßsledujφcφ p°φkaz p°epne OnFilterRecord na obsluhu udßlosti nazvanou NewYorkFilter:
DataSet1->OnFilterRecord = NewYorkFilter;
Refresh;

Nastavovßnφ voleb filtru
Vlastnost FilterOptions umo╛≥uje specifikovat zda se bude provßd∞t ·plnΘ porovnßvßnφ °et∞zc∙ a zda se bude rozli╣ovat p°i porovnßvßnφ velikost pφsmen. FilterOptions je mno╛ina, kterß m∙╛e b²t prßzdnß (implicitn∞) nebo m∙╛e obsahovat jednu nebo ob∞ z nßsledujφcφch hodnot:
 
Hodnota V²znam
foCaseInsensitive  P°i porovnßvßnφ °et∞zc∙ je ignorovßna velikost pφsmen.
foPartialCompare  ╚ßsteΦnΘ porovnßvßnφ °et∞zc∙ (°et∞zec konΦφcφ hv∞zdiΦkou).

Nap°. nßsledujφcφ p°φkaz nastavuje filtr, kter² ignoruje velikost pφsmen p°i porovnßvßnφ hodnot v polo╛ce State:
TFilterOptions FilterOptions;
FilterOptions.Clear();
FilterOptions << foCaseInsensitive;
Table1->FilterOptions = FilterOptions;
Table1->Filter = "State = 'CA'";

Prochßzenφ zßznamy ve filtrovanΘ datovΘ mno╛in∞
Jsou Φty°i metody datov²ch mno╛in, kterΘ umo╛≥ujφ prochßzet zßznamy ve filtrovanΘ datovΘ mno╛in∞. Tyto metody jsou popsßny v nßsledujφcφ tabulce.
 
Metoda ╚innost
FindFirst P°esun na prvnφ zßznam v datovΘ mno╛in∞, kter² spl≥uje zadanß filtrovacφ kritΘria. Hledßnφ v╛dy zaΦφnß prvnφm zßznamem v nefiltrovanΘ datovΘ mno╛in∞.
FindLast P°esun na poslednφ zßznam v datovΘ mno╛in∞, kter² spl≥uje zadanß filtrovacφ kritΘria.
FindNext P°esun na nßsledujφcφ zßznam v datovΘ mno╛in∞, kter² spl≥uje zadanß filtrovacφ kritΘria.
FindPrior P°esun na p°edchozφ zßznam v datovΘ mno╛in∞, kter² spl≥uje zadanß filtrovacφ kritΘria.

Nap°. nßsledujφcφ p°φkaz nalezne prvnφ vyhovujφcφ zßznam v datovΘ mno╛in∞:
DataSet1->FindFirst();
Pokud mßme nastavenu vlastnost Filter nebo vytvo°enou obsluhu udßlosti OnFilterRecord pro na╣i datovou mno╛inu, pak tyto metody p°emφstφ kurzor na specifikovan² zßznam a to bez ohledu na to, zda filtrovßnφ je povoleno. Kdy╛ volßme tyto metody a filtrovßnφ nenφ povoleno, pak filtrovßnφ je doΦasn∞ povoleno, kurzor umφst∞n na odpovφdajφcφ zßznam a filtrovßnφ je zakßzßno.
Poznßmka: Jestli╛e vlastnost Filter nenφ nastavena a nenφ vytvo°ena obsluha udßlosti OnFilterRecord, pak tyto metody pracujφ stejn∞ jako metody First, Last, Next a Prior.
V╣echny tyto metody umφstφ kurzor na vyhovujφcφ zßznam (pokud existuje) a vracejφ true. Pokud vyhovujφcφ zßznam neexistuje, pak pozice kurzoru se nem∞nφ a metoda vracφ false. Nap°. pokud kurzor je na poslednφm vyhovujφcφm zßznamu v datovΘ mno╛in∞ a volßme FindNext, pak metoda vracφ false a souΦasn² zßznam se nem∞nφ.

Modifikovßnφ dat

M∙╛eme pou╛φvat nßsledujφcφ metody datovΘ mno╛iny pro vklßdßnφ, aktualizaci a ru╣enφ dat:
 
Metoda Popis
Edit Uvßdφ datovou mno╛inu do stavu dsEdit, pokud ji╛ nenφ ve stavu dsEdit nebo dsInsert.
Append Zapisuje nezapsanß data, p°esouvß kurzor na konec datovΘ mno╛iny a p°evßdφ datovou mno╛inu do stavu dsInsert.
Insert Zapisuje nezapsanß data a p°evßdφ datovou mno╛inu do stavu dsInsert.
Post Pokusφ se zapsat nov² nebo zm∞n∞n² zßznam do databßze. V p°φpad∞ ·sp∞chu vracφ datovou mno╛inu do stavu dsBrowse, jinak se stav nem∞nφ.
Cancel UkonΦuje souΦasnou operaci a vracφ datovou mno╛inu do stavu dsBrowse.
Delete Ru╣φ souΦasn² zßznam a p°evßdφ datovou mno╛inu do stavu dsBrowse.

Tyto metody jsou podrobn∞ji popsßny v nßsledujφcφch bodech:

Editace zßznam∙
Aby aplikace mohla modifikovat zßznamy, musφ b²t datovß mno╛ina ve stavu dsEdit. V na╣em k≤du m∙╛eme pou╛φt metodu Edit k uvedenφ datovΘ mno╛iny do stavu dsEdit, pokud vlastnost CanModify datovΘ mno╛iny je true. CanModify je true, pokud k tabulce spojenΘ s datovou mno╛inou mßme Φtecφ a zßpisovß privilegia. Jak jsme se ji╛ dozv∞d∞li, datovß mno╛ina p°i spln∞nφ jist²ch podmφnek m∙╛e do stavu dsEdit p°ejφt automaticky.
Po uvedenφ datovΘ mno╛iny do stavu dsEdit u╛ivatel m∙╛e modifikovat hodnoty polo╛ek souΦasnΘho zßznamu, kterΘ jsou zobrazeny v datov²ch ovladaΦφch na formulß°i. DatovΘ ovladaΦe pro kterΘ je automaticky povolenß editace, volajφ Post, kdy╛ u╛ivatel provede n∞jakou akci m∞nφcφ souΦasn² zßznam (p°esun na jin² zßznam). Pokud nß╣ formulß° obsahuje navigaΦnφ komponentu, pak u╛ivatel m∙╛e zru╣it provedenΘ zm∞ny stisknutφm tlaΦφtka Cancel navigßtora. Tφm p°ejde datovß mno╛ina do stavu dsBrowse.
V k≤du musφme zapsat nebo zru╣it provedenΘ zm∞ny volßnφm p°φslu╣n²ch metod. Zm∞ny zapisujeme volßnφm Post a ru╣φme je volßnφm Cancel. Edit a Post jsou Φasto pou╛φvßny spoleΦn∞. Nap°.
Table1->Edit();
Table1->FieldValues["CustNo"] = 1234;
Table1->Post();
V p°edchozφm p°φklad∞, prvnφ °ßdek k≤du uvßdφ datovou mno╛inu do stavu dsEdit. Dal╣φ °ßdek k≤du p°i°azuje Φφslo 1234 polo╛ce CustNo souΦasnΘho zßznamu. Poslednφ °ßdek zapisuje (ode╣le) modifikovan² zßznam do databßze.
Poznßmka: Pokud vlastnost CachedUpdates datovΘ mno╛iny je true, pak odesφlanΘ modifikace jsou zapsßny do doΦasnΘ vyrovnßvacφ pam∞ti. K jejich zßpisu do databßze volßme metodu ApplyUpdates datovΘ mno╛iny.
P°idßvßnφ nov²ch zßznam∙
D°φve ne╛ aplikace m∙╛e k datovΘ mno╛in∞ p°idat dal╣φ zßznam, musφme ji uvΘst do stavu dsInsert. Pro uvedenφ datovΘ mno╛iny do stavu dsInsert volßme v k≤du metodu Insert nebo Append, pokud vlastnost CanModify datovΘ mno╛iny je nastavena na true. CanModify je true, pokud k databßzi spojenΘ s datovou mno╛inou mßme Φtecφ a zßpisovß privilegia. Datovß mno╛ina p°i spln∞nφ urΦit²ch podmφnek m∙╛e b²t do stavu dsInsert p°evedena automaticky.
Po uvedenφ datovΘ mno╛iny do stavu dsInsert, u╛ivatel nebo aplikace m∙╛e zadßvat hodnoty do polo╛ek novΘho zßznamu. Mimo mφsta ulo╛enφ nenφ rozdφl mezi metodami Insert a Append. Insert pou╛φvßme pro vlo╛enφ novΘho °ßdku p°ed souΦasn² zßznam a Append pro vlo╛enφ novΘho °ßdku za poslednφ zßznam datovΘ mno╛iny.
DatovΘ ovladaΦe, pro kterΘ je povoleno vklßdßnφ, automaticky volajφ Post, kdy╛ u╛ivatel provede n∞jakou akci, kterß m∞nφ souΦasn² zßznam (p°esun na jin² zßznam). Jinak musφme volat Post ve svΘm k≤du. Post zapisuje nov² zßznam do databßze nebo p°i CachedUpdates nastaven²m na true, do doΦasnΘ vyrovnßvacφ pam∞ti (pro zßpis do databßze je nutno je╣t∞ volat ApplyUpdates).
Insert otevφrß nov² prßzdn² zßznam p°ed souΦasn²m zßznamem a tento prßzdn² zßznam se stßvß souΦasn²m zßznamem a tedy hodnoty polo╛ek tohoto zßznamu mohou b²t zadßvßny u╛ivatelem nebo k≤dem na╣φ aplikace.
Kdy╛ aplikace volß Post (nebo ApplyUpdates p°i povolen²ch odlo╛en²ch aktualizacφch), nov∞ vklßdan² zßznam je zapsßn do databßze jednφm z t∞chto zp∙sob∙: Append otevφrß nov² prßzdn² zßznam na konci datovΘ mno╛iny. Jinak je Φinnost stejnß jako p°i Insert (p°i zßpisu do neindexovanΘ tabulky je zßznam vlo╛en na konec datovΘ mno╛iny).
Ru╣enφ zßznam∙
Aby aplikace mohla zru╣it zßznam, musφ b²t datovß mno╛ina aktivnφ. Delete ru╣φ aktivnφ zßznam v datovΘ mno╛in∞ a p°evßdφ ji do stavu dsBrowse. Zßznam, kter² nßsleduje za zru╣en²m zßznamem se stßvß souΦasn²m zßznamem. Pokud jsou povoleny odlo╛enΘ aktualizace, pak zru╣en² zßznam je pouze odstran∞n z doΦasnΘ vyrovnßvacφ pam∞ti, dokud nevolßme ApplyUpdates.
Pokud na svΘm formulß°i pou╛φvßme navigaΦnφ komponentu, pak u╛ivatel m∙╛e zru╣it souΦasn² zßznam stisknutφm tlaΦφtka Delete navigßtora. V k≤du musφme explicitn∞ volat k odstran∞nφ souΦasnΘho zßznamu metodu Delete.
Odesφlßnφ dat do databßze
Metoda Post centralizuje v aplikacφch C++ Builderu interakce s databßzovou tabulkou. Post zapisuje zm∞ny souΦasnΘho zßznamu do databßze, ale chovßnφ se li╣φ v zßvislosti na stavu datovΘ mno╛iny: Odeslßnφ m∙╛e b²t provßd∞no explicitn∞ nebo implicitn∞ jako Φßst jinΘ procedury. Kdy╛ aplikace p°esouvß souΦasn² zßznam, pak Post je volßno implicitn∞. Volßnφ metod First, Next, Prior a Last provßdφ Post, pokud datovß mno╛ina je ve stavu dsEdit nebo dsInsert. Metody Append a Insert takΘ implicitn∞ odesφlajφ v╣echna nevy°φzenß data.
Poznßmka: Metoda Close nevolß Post implicitn∞. Pou╛ijeme obsluhu udßlosti BeforeClose k odeslßnφ v╣ech nevy°φzen²ch aktualizacφ.
Zru╣enφ zm∞n
Aplikace m∙╛e zru╣it zm∞ny provedenΘ na souΦasnΘm zßznamu, pokud je╣t∞ nebyly zapsßny pomocφ Post. Nap°. pokud datovß mno╛ina je ve stavu dsEdit a u╛ivatel zm∞nil data jednΘ nebo vφce polo╛ek, pak aplikace se m∙╛e vrßtit k p∙vodnφm hodnotßm zßznamu volßnφm metody Cancel datovΘ mno╛iny. Volßnφ Cancel v╛dy vracφ datovou mno╛inu do stavu dsBrowse. Pokud na formulß°i mßme umφst∞nu navigaΦnφ komponentu, pak m∙╛eme pro zru╣enφ zm∞n p°ipojenΘ datovΘ mno╛iny stisknout tlaΦφtko Cancel tΘto komponenty.
Modifikace cel²ch zßznam∙
V╣echny datovΘ ovladaΦe na formulß°i mimo m°φ╛ky a navigaΦnφ komponenty poskytujφ p°φstup k jednotliv²m polo╛kßm v zßznamu. V k≤du ale m∙╛eme pou╛φvat nßsledujφcφ metody, kterΘ pracujφ s cel²mi zßznamy a to za p°edpokladu, ╛e struktura databßzov²ch tabulek p°ipojenΘ datovΘ mno╛iny je stabilnφ a nem∞nφ se.
 
Metoda Popis
AppendRecord([pole hodnot])  P°edßvß zßznam se specifikovan²mi hodnotami sloupc∙ na konec tabulky. Provßdφ implicitn∞ Post.
InsertRecord([pole hodnot])  Vklßdß specifikovanΘ hodnoty jako zßznam p°ed souΦasnou pozici kurzoru tabulky. Provßdφ implicitn∞ Post.
SetFields([pole hodnot])  Nastavuje hodnoty specifikovan²ch polo╛ek (odpovφdß p°i°azenφ hodnot do TFields). Aplikace musφ provΘst explicitn∞ Post.

Tyto metody p°ebφrajφ pole hodnot TVarRec jako parametr, kde ka╛dß hodnota odpovφdß sloupci v p°ipojenΘ datovΘ mno╛in∞. K vypln∞nφ t∞chto polφ pou╛ijeme makro ARRAYOFCONST. Hodnoty mohou b²t konstanty, prom∞nnΘ nebo NULL. Pokud poΦet hodnot v parametru je men╣φ ne╛ poΦet sloupc∙ v datovΘ mno╛in∞, pak zb²vajφcφm sloupc∙m je p°i°azeno NULL.
Pro neindexovanΘ datovΘ mno╛iny, AppendRecord p°idßvß zßznam na konec datovΘ mno╛iny a InsertRecord vklßdß zßznam p°ed souΦasn² zßznam. Pro indexovanΘ tabulky, ob∞ metody umis╗ujφ zßznam do tabulky na zßklad∞ indexu. V obou p°φpadech metody p°emφstφ kurzor na vlo╛en² zßznam.
SetFields p°i°azuje hodnoty specifikovanΘ v poli parametr∙ do polo╛ek v datovΘ mno╛in∞. Pro pou╛itφ SetFields, aplikace musφ nejprve volat Edit k uvedenφ datovΘ mno╛iny do stavu dsEdit. Aplikovßnφ zm∞n na souΦasn² zßznam pak provedeme Post.
Jestli╛e pou╛ijeme SetFields k modifikaci n∞kter²ch, ale ne v╣ech polo╛ek v existujφcφm zßznamu, pak m∙╛eme p°edat hodnotu NULL pro polo╛ky, kterΘ nechceme m∞nit. Pokud nep°edßme dostatek hodnot pro v╣echny polo╛ky v zßznamu, pak SetFields p°i°adφ hodnoty NULL pro zb²vajφcφ polo╛ky (tyto NULL p°epφ╣φ existujφcφ hodnoty v t∞chto polo╛kßch).
Nap°. p°edpoklßdejme, ╛e v databßzi je tabulka COUNTRY se sloupci Name, Capital, Continent, Area a Population. Pokud komponenta TTable nazvanß CountryTable je spojenß s touto tabulkou, pak nßsledujφcφ p°φkaz vlo╛φ zßznam do tabulky COUNTRY:
CountryTable->InsertRecord(ARRAYOFCONST(("Japan", "Tokyo", "Asia")));
Tento p°φkaz neobsahuje hodnoty pro sloupce Area a Population a jsou tedy do nich vlo╛eny hodnoty NULL. Tabulka je indexovßna podle sloupce Name a p°φkaz tedy vlo╛φ zßznam na mφsto na zßklad∞ abecednφho umφst∞nφ "Japan". K aktualizaci zßznamu, aplikace m∙╛e pou╛φt tento k≤d:
TLocateOptions SearchOptions;
SearchOptions.Clear();
SearchOptions << loCaseInsensitive;
if (CountryTable->Locate("Name", "Japan", SearchOptions))
{
  CountryTable->Edit();
  CountryTable->SetFields(ARRAYOFCONST(
     ((void *)NULL, (void *)NULL, (void *)NULL, 344567, 164700000)));
  CountryTable->Post();
}
Tento k≤d p°i°azuje hodnoty polo╛ek Area a Population a potom je odesφlß do databßze. T°i ukazatelΘ na NULL dr╛φ mφsto pro prvnφ t°i sloupce k zabrßn∞nφ zm∞n∞ jejφho obsahu (musφme provΘst p°etypovßnφ na void *).
Varovßnφ: Pokud pou╛ijeme NULL bez p°etypovßnφ, pak polo╛ku nastavφme na prßzdnou hodnotu.

Pou╛φvßnφ udßlostφ datov²ch mno╛in

DatovΘ mno╛iny majφ n∞kolik udßlostφ, kterΘ umo╛≥ujφ aplikaci provßd∞t kontroly, v²poΦty souΦt∙ a dal╣φ ·lohy. Tyto udßlosti jsou uvedeny v nßsledujφcφ tabulce:
 
Udßlost Popis
BeforeOpen, AfterOpen Je generovßna p°ed/po otev°enφ datovΘ mno╛iny.
BeforeClose, AfterClose Je generovßna p°ed/po uzav°enφ datovΘ mno╛iny.
BeforeInsert, AfterInsert Je generovßna p°ed/po uvedenφ datovΘ mno╛iny do stavu dsInsert.
BeforeEdit, AfterEdit Je generovßna p°ed/po uvedenφ datovΘ mno╛iny do stavu dsEdit.
BeforePost, AfterPost Je generovßna p°ed/po odeslßnφ zm∞n.
BeforeCancel, AfterCancel Je generovßna p°ed/po zru╣enφ proveden²ch zm∞n.
BeforeDelete, AfterDelete Je generovßna p°ed/po zru╣enφ zßznamu.
OnNewRecord Je generovßna p°i vytvo°enφ novΘho zßznamu; pou╛φvß se k nastavenφ implicitnφch hodnot.
OnCalcFields Je generovßna, kdy╛ poΦitatelnΘ polo╛ky jsou poΦφtßny.

Pro zru╣enφ provßd∞nφ metod, jako je nap°. Open nebo Insert, volßme funkci Abort v n∞kterΘ metod∞ Before... (BeforeOpen, BeforeInsert apod.). Nap°. nßsledujφcφ k≤d vy╛aduje potvrzenφ u╛ivatele p°ed zru╣enφm zßznamu.
void __fastcall TForm1::TableBeforeDelete (TDataSet *Dataset)
{
  if (MessageBox(0, "Delete This Record?", "CONFIRM", MB_YESNO) != IDYES)
   Abort();
}

Pou╛itφ OnCalcFields
Udßlost OnCalcFields je pou╛φvßna k nastavovßnφ hodnot poΦitateln²ch polo╛ek. Vlastnost AutoCalcFields urΦuje zda je generovßna udßlost OnCalcFields. Jestli╛e hodnota tΘto vlastnosti je true, pak OnCalcFields je generovßna kdy╛: OnCalcFields je v╛dy generovßna p°i zm∞n∞ hodnoty n∞kterΘ nepoΦitatelnΘ polo╛ky a to bez ohledu na nastavenφ AutoCalcFields.
Varovßnφ: Jeliko╛ OnCalcFields je volßna velmi Φasto, je vhodnΘ, aby obsluha tΘto udßlosti byla krßtkß. Pokud AutoCalcFields je true, pak OnCalcFields by nem∞la provßd∞t akce modifikujφcφ datovou mno╛inu nebo╗ to m∙╛e vΘst k rekurzi (pokud OnCalcFields volß Post, pak je generovßna OnCalcFields). Kdy╛ AutoCalcFields je false, pak OnCalcFields je generovßna pouze p°i volßnφ Post.
P°i provßd∞nφ OnCalcFields je datovß mno╛ina ve stavu dsCalcFields a nemohou b²t tedy m∞n∞ny hodnoty jin²ch ne╛ poΦitateln²ch polo╛ek. Po dokonΦenφ OnCalcFields se datovß mno╛ina vrßtφ do stavu dsBrowse.

  1. Dal╣φ aplikace, kterou vytvo°φme, bude zobrazovat informace o na╣ich podmo°sk²ch p°ßtelφch a umo╛nφ uklßdat tyto informace do textovΘho souboru. Aplikace bude pou╛φvat ji╛ vytvo°en² databßzov² soubor BIOLIFE.DB. Ukß╛eme si v nφ pou╛itφ komponent TDBGrid, TDBText, TDBImage, TDataSource, TTable a TDBMemo, prochßzenφ daty pomocφ m°φ╛ky, extrakci dat z datovΘho ovladaΦe a zßpis do textovΘho souboru.

  2. ZaΦneme v²voj novΘ aplikace. Na formulß° umφstφme komponentu panel, jejφ╛ v²╣ku nastavφme asi 72 bob∙ a zarovnßme ji se spodnφm okrajem formulß°e (Align nastavφme na alBottom). Na formulß° p°idßme dal╣φ panel, kter² tentokrßt bude zabφrat levou polovinu zb²vajφcφ Φßsti formulß°e. Do spodnφ Φßsti tohoto panelu p°idßme komponentu TDBText (pou╛ijeme ΦervenΘ pφsmo, tuΦnΘ a kurzφvou velikosti 14) a na jeho zb²vajφcφ plochu komponentu DBImage. Na zb²vajφcφ plochu formulß°e umφstφme komponentu TDBMemo. Data z databßze budeme zφskßvat komponentou TTable. Umφstφme ji na formulß° a nastavφme u nφ vlastnost DatabaseName na BCDEMOS, vlastnost TableName na BIOLIFE a vlastnost Active na true. Dßle je nutno na formulß° umφstit komponentu TDataSource a nastavφme u nφ vlastnost DataSet na Table1. Na panel umφst∞n² u spodnφho okraje formulß°e na pravΘm okraji nad sebe dv∞ tlaΦφtka BitBtn. Spodnφ bude mφt nastavenu vlastnost Kind na bkClose (bude slou╛it k ukonΦenφ aplikace) a hornφ bude mφt tuto vlastnost nastavenu na bkCustom (bude slou╛it k zßpisu dat z ovladaΦe do souboru; jeho text zm∞nφme na Save a vlo╛φme na n∞j vhodn² obrßzek). Zbytek plochy spodnφho panelu zaplnφme komponentou TDBGrid (jejφ v²sku nastavφme tak, aby mimo hlaviΦky zde byl zobrazen pouze jeden °ßdek).
    Vlastnosti DataSource u komponent TDBGrid, TDBText, TDBImage a TDBMemo nastavφme na DataSource1 a vlastnosti DataField u TDBText na Common_Name, u TDBImage na Graphic a u TDBMemo na Notes. Nynφ ji╛ aplikaci m∙╛eme p°elo╛it a spustit. Rolovßnφm m°φ╛ky prochßzφme zßznamy tabulky. M°φ╛ka obsahuje zbyteΦnΘ sloupce. Pozd∞ji si ukß╛eme jak je nezobrazovat a jak umo╛nit definovat zp∙sob zobrazenφ.
  3. Zatφm jsme se nezab²vali uklßdßnφm dat z ovladaΦe do souboru. Na formulß° umφstφme komponentu TSaveDialog a nastavφme u nφ vlastnosti DefaultExt na .txt, FileName na Fish.txt a Filter na Textov² soubor (*.txt). Obsluha stisknutφ tlaΦφtka Save bude tvo°ena p°φkazy:

  4. FILE *outfile;
    char buff[100];
    sprintf(buff, "Save Info For: %s", DBText1->Field->AsString.c_str());
    SaveDialog1->Title = buff;
    if (SaveDialog1->Execute()){
      outfile = fopen(SaveDialog1->FileName.c_str(), "wt");
      if (outfile) {
        fprintf(outfile, "Facts on the %s\n\n",
                (LPSTR)DBText1->Field->AsString.c_str());
        for (int i=0; i < DBGrid1->FieldCount; i++)
          fprintf(outfile, "%s: %s\n",
                  (LPSTR)DBGrid1->Fields[i]->FieldName.c_str(),
                  (LPSTR)DBGrid1->Fields[i]->AsString.c_str());
        fprintf(outfile, "\n%s\n", (LPSTR)DBMemo1->Text.c_str());
      }
      fclose(outfile);
    }
    Tato obsluha zapφ╣e do textovΘho souboru informace o souΦasnΘ ryb∞. Podφvejte se, jak se tyto informace zφskßvajφ a zapisujφ. Tφm je v²voj aplikace ukonΦen. Dal╣φ p°φklady budou uvedeny v nßsledujφcφ kapitole.
6. Seznßmenφ s datov²mi mno╛inami