19. Vytvß°enφ a pou╛φvßnφ klientskΘ datovΘ mno╛iny

TClientDataSet je komponenta datovΘ mno╛iny urΦenß pro prßci bez podpory BDE. Mφsto BDE je pou╛φvßna DBCLIENT.DLL, kterß je mnohem men╣φ a jednodu╣╣φ pro instalaci a konfiguraci. Komponenty databßze s klientsk²mi datov²mi mno╛inami nepou╛φvßme, proto╛e nemajφ databßzovΘ p°ipojenφ.
KlientskΘ datovΘ mno╛iny poskytujφ v╣echen datov² p°φstup, editace, navigace a filtrovßnφ zd∞d∞nΘ od TDataSet. NicmΘn∞ aplikace, kterß pou╛φvß klientskΘ datovΘ mno╛iny, musφ poskytnout mechanismus kter²m klientskß datovß mno╛ina Φte data a zapisuje aktualizace. KlientskΘ datovΘ mno╛iny toto poskytujφ jednou z nßsledujφcφch mo╛nostφ:

Tyto mechanismy mohou b²t kombinovßny v jednΘ aplikaci pou╛φvajφcφ model aktovky. U╛ivatel zφskß pot°ebnß data, ulo╛φ je do souboru a m∙╛e s nimi pracovat samostatn∞. Pozd∞ji klientskß aplikace aplikuje zm∞ny z lokßlnφ kopie dat na aplikaΦnφ server. AplikaΦnφ server je zpracuje a vracφ chyby klientskΘ datovΘ mno╛in∞ pro zpracovßnφ. Toto je popsßno v Podpora aktovkovΘho modelu.
Nßsledujφcφ body poskytujφ vφce informacφ o prßci s klientsk²mi datov²mi mno╛inami:

DatabßzovΘ aplikace ploch²ch soubor∙

DatabßzovΘ aplikace ploch²ch soubor∙ jsou jednovrstvovΘ aplikace, kterΘ pou╛φvajφ TClientDataSet k reprezentaci v╣ech sv²ch datov²ch mno╛in. KlientskΘ datovΘ mno╛iny dr╛φ v╣echna svß data v pam∞ti, co╛ znamenß, ╛e tento typ aplikacφ nenφ vhodn² pro velkΘ datovΘ mno╛iny. DatabßzovΘ aplikace ploch²ch soubor∙ nevy╛adujφ BDE. Mφsto BDE pou╛φvajφ pouze DBCLIENT.DLL. Tento typ aplikacφ tedy sßm nepot°ebuje tolik pam∞ti jako aplikace zalo╛enΘ na BDE. Proto╛e pou╛φvajφ pouze DBCLIENT.DLL, jejich ╣φ°enφ je snaz╣φ, proto╛e nemusφ instalovat, konfigurovat a udr╛ovat BDE.
Proto╛e tyto aplikace nepou╛φvajφ BDE, nejsou urΦeny pro vφce u╛ivatelsk² p°φstup. DatovΘ mno╛iny jsou zcela vyhrazenΘ tΘto aplikaci. Data mohou b²t uklßdßna na disk a pozd∞ji op∞t zavßd∞na, ale nemajφ zabudovanou ochranu chrßnφcφ p°ed p°epsßnφm jin²m u╛ivatelem.
Klientskß datovß mno╛ina (umφst∞nß na strßnce MIDAS Palety komponent) je zßkladem databßzov²ch aplikacφ ploch²ch soubor∙. Poskytuje podporu pro v∞t╣inu databßzov²ch operacφ provßd∞n²ch datov²mi mno╛inami zalo╛en²mi na BDE. Pou╛φvßme stejnΘ komponenty datov²ch ovladaΦ∙ a datov²ch zdroj∙ jako u aplikacφ zalo╛en²ch na BDE. Nem∙╛eme pou╛φt komponentu databßze, proto╛e se nep°ipojujeme k databßzi. TakΘ se nepou╛φvß komponenta sezenφ.
Hlavnφm rozdφlem mezi Databßzov²mi aplikacemi ploch²ch soubor∙ a BDE databßzov²mi aplikacemi je ve vytvß°enφ datov²ch mno╛in a zp∙sobu zavßd∞nφ a uklßdßnφ dat.
M∙╛eme takΘ vytvo°it hybridnφ aplikaci, pracujφcφ jako jednovrstvovß aplikace ploch²ch soubor∙ a po p°ipojenφ k aplikaΦnφmu serveru pracuje jako klientskß Φßst vφcevrstvovΘ databßzovΘ aplikace. Tyto aplikace pou╛φvajφ aktovkov² model.

Vytvß°enφ datov²ch mno╛in

Proto╛e databßzovΘ aplikace ploch²ch soubor∙ nepou╛φvajφ existujφcφ databßze, jsou sami zodpov∞dnΘ za vytvß°enφ datov²ch mno╛in. Po vytvo°enφ datovΘ mno╛iny je mo╛no ji ulo╛it do souboru. P°i Φtenφ pak nenφ nutno op∞tovn∞ vytvß°et tabulky, data jsou pouze zavedena ze souboru, kde byla ulo╛ena. Indexy ale nejsou uklßdßny s tabulkou, je nutno je v╛dy p°i zavedenφ tabulky vytvo°it.
Kdy╛ zaΦφnßme s Databßzovou aplikacφ ploch²ch soubor∙, pak musφme nejprve vytvo°it a ulo╛it prßzdnΘ soubory pro na╣e datovΘ mno╛iny p°ed zahßjenφm zßpisu samotnΘ aplikace. Tφmto zp∙sobem nemusφme definovat metadata pro na╣e klientskΘ datovΘ mno╛iny ve v²slednΘ aplikaci.
Jak vytvo°φme na╣e klientskΘ datovΘ mno╛iny zßvisφ na tom, zda vytvß°φme novou datovou mno╛inu nebo p°evßdφme existujφcφ BDE aplikaci.
Vytvß°enφ novΘ datovΘ mno╛iny pou╛φvajφcφ trvalΘ polo╛ky
Nßsledujφcφ kroky popisujφ vytvß°enφ novΘ klientskΘ datovΘ mno╛iny pomocφ Editoru polo╛ek:
  1. Ze strßnky MIDAS Palety komponent, p°idßme komponentu TClientDataSet k na╣i aplikaci.
  2. V mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Fields Editor. V mφstnφ nabφdce Editoru polo╛ek zvolφme New Field a popφ╣eme zßkladnφ vlastnosti definice polo╛ky. Po vytvo°enφ polo╛ky m∙╛eme tyto vlastnosti m∞nit v Inspektoru objekt∙. PokraΦujeme v p°idßvßnφ polo╛ek dokud nemßme popsßnu celou klientskou datovou mno╛inu.
  3. V mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Create DataSet. Tφm vytvo°φme prßzdnou klientskou datovou mno╛inu z trval²ch polo╛ek p°idan²ch v Editoru polo╛ek.
  4. V mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Save To File Tento p°φkaz nenφ dostupn², dokud klientskß datovß mno╛ina neobsahuje data.
  5. V dialogovΘm okn∞ uklßdßnφ soubor∙ zvolφme jmΘno souboru a ulo╛φme kopii plochΘho souboru na╣φ klientskΘ datovΘ mno╛iny.
Poznßmka: M∙╛eme takΘ vytvo°it klientskou datovou mno╛inu za b∞hu pomocφ trval²ch polo╛ek, kterΘ jsou ulo╛eny s klientskou datovou mno╛inou. Pouze volßme metodu CreateDataSet.
Vytvß°enφ datov²ch mno╛in pomocφ definicφ polo╛ek a index∙
Vytvß°enφ klientskΘ datovΘ mno╛iny pomocφ definic polo╛ek a index∙ se podobß pou╛itφ komponenty TTable k vytvo°enφ databßzovΘ tabulky. Nespecifikujeme zde vlastnosti DatabeseName, TableName a TableType, proto╛e pro klientskΘ datovΘ mno╛iny jsou zbyteΦnΘ. NicmΘn∞ jako u TTable pou╛ijeme vlastnost FieldDefs pro specifikaci polo╛ek na╣φ tabulky a vlastnost IndexDefs pro specifikaci index∙. Po dokonΦenφ specifikace tabulky p°i nßvrhu zvolφme v mφstnφ nabφdce klientskΘ datovΘ mno╛iny Create DataSet nebo za b∞hu aplikace volßme metodu CreateDataSet.
Kdy╛ pro na╣φ klientskou aplikaci definujeme indexy, pak dv∞ vlastnosti definice indexu aplikujφ unikßtnost na klientskou datovou mno╛inu. Jednß se o TIndexDef::DescFields a TIndexDef::CaseInsFields.
DescFields definuje indexy, kterΘ °adφ zßznamy podle n∞kter²ch polo╛ek vzestupn∞ a podle jin²ch sestupn∞. Mφsto pou╛φtφ volby ixDescending k urΦenφ sestupnΘho °azenφ podle v╣ech polo╛ek indexu, uvedeme jako hodnotu DescFields pouze ty polo╛ky, kterΘ majφ b²t sestupnΘ. Nap°. kdy╛ definujeme index, kter² °adφ podle Field1, pak podle Field2 a pak podle Field3 a nastavφme DescFields na
Field1;Field3
pak v²sledkem je, ╛e °azenφ podle Field2 je vzestupnΘ a podle Field1 a Field3 je sestupnΘ.
CaseInsFields umo╛≥uje definovat indexy umo╛≥ujφcφ u n∞kter²ch polo╛ek indexu rozli╣ovat velikost pφsmen a u jin²ch ne. Mφsto pou╛itφ volby isCaseInsensitive k nerozli╣ovßnφ velikosti pφsmen u v╣ech polo╛ek uvedeme ve vlastnosti CaseInsFields seznam pouze t∞ch polo╛ek u nich╛ velikost nechceme rozli╣ovat. Jednß se op∞t o seznam jmen polo╛ek odd∞lovan² st°ednφky.
Definice polo╛ek a index∙ m∙╛eme b∞hem nßvrhu vytvo°it pomocφ Editoru. Pouze zvolφme p°φslu╣nou vlastnost v Inspektoru objekt∙ (FieldDefs nebo IndexDefs) a dvojit²m kliknutφm Editor zobrazφme. Editor pou╛ijeme k p°idßvßnφ, ru╣enφ a zm∞nßm definice. Vybereme definici v Editoru a jejφ vlastnosti m∙╛eme editovat v Inspektoru objekt∙.
M∙╛eme takΘ specifikovat definice index∙ a polo╛ek k≤dem za b∞hu. Nap°. nßsledujφcφ k≤d vytvß°φ a aktivuje klientskou datovou mno╛inu v obsluze udßlosti OnCreate formulß°e:
void __fastcallTForm1::FormCreate(TObject *Sender)
{
  TFieldDef *pDef = ClientDataSet1->FieldDefs->AddFieldDef();
  pDef->DataType = ftInteger;
  pDef->Name = "Field1";
  pDef = ClientDataSet1->FieldDefs->AddFieldDef();
  pDef->DataType = ftString;
  pDef->Size = 10;
  pDef->Name = "Field2";
  TIndexDef *pIndex = ClientDataSet1->IndexDefs->AddIndexDef();
  pIndex->Fields = "Field1";
  pIndex->Name = "IntIndex";
  ClientDataSet1->CreateDataSet();
}
Vytvo°enφ datovΘ mno╛iny na zßklad∞ existujφcφ tabulky
Pokud p°evßdφme existujφcφ BDE aplikaci na jednovrstvovou aplikaci ploch²ch soubor∙, pak m∙╛eme kopφrovat existujφcφ tabulky a potom je ulo╛φme jako tabulky ploch²ch soubor∙ z IDE. Nßsledujφcφ kroky popisujφ, jak to ud∞lat:
  1. Ze strßnky Data Access Palety komponent p°idßme k na╣φ aplikaci komponentu TTable. Nastavφme jejφ vlastnosti DatabaseName a TableName k identifikaci existujφcφ databßzovΘ tabulky. Nastavφme jejφ vlastnost Active na true.
  2. Ze strßnky MIDAS Palety komponent p°idßme k aplikaci komponentu TClientDataSet.
  3. V mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Assign Local Data. V zobrazenΘm dialogovΘm okn∞, zvolφme komponentu tabulky p°idanou v kroku 1 a stiskneme OK.
  4. V mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Save To File. Tento p°φkaz nenφ dostupn² pokud klientskß datovß mno╛ina neobsahuje data.
  5. V dialogu uklßdßnφ souboru zvolφme jmΘno souboru a ulo╛φme kopii plochΘho souboru z na╣φ databßzovΘ aplikace.

Zavßd∞nφ a uklßdßnφ dat

V databßzov²ch aplikacφch ploch²ch soubor∙, v╣echny modifikace na tabulkßch existujφ pouze v denφku zm∞n v pam∞ti. Tento denφk je udr╛ovßn odd∞len∞ od samotn²ch dat i kdy╛ je pln∞ transparentnφ k objekt∙m, kterΘ pou╛φvajφ klientskou datovou mno╛inu. Tj. ovladaΦe prochßzejφcφ klientskou datovou mno╛inou nebo zobrazujφcφ jejφ data vidφ pohled na data vΦetn∞ proveden²ch zm∞n. Pokud zm∞ny nechceme zru╣it, pak zm∞ny m∙╛eme slouΦit s daty volßnφm metody MergeChangeLog klientskΘ datovΘ mno╛iny.
Po slouΦenφ zm∞n s daty klientskΘ datovΘ mno╛iny, tato data stßle existujφ pouze v pam∞ti. Zm∞ny tedy nejsou trvalΘ a ztratφme je kdy╛ uzav°eme klientskou datovou mno╛inu a op∞t ji v na╣i aplikaci otev°eme, nebo kdy╛ ukonΦφme prßci na╣φ aplikace. Aby data se stala trval²mi, musφme je zapsat na disk. Zm∞ny na disk zapφ╣eme metodou SaveToFile. Tato metoda p°ebφrß jeden parametr, a to jmΘno vytvß°enΘho (nebo p°episovanΘho) souboru obsahujφcφho tabulku.
Kdy╛ chceme p°eΦφst tabulku d°φve zapsanou pomocφ metody SaveToFile, pak pou╛ijeme metodu LoadFromFile. LoadFromFile p°ebφrß takΘ jeden parametr a to jmΘno souboru obsahujφcφho tabulku.
Kdy╛ ulo╛φme klientskou datovou mno╛inu, pak metadata popisujφcφ strukturu zßznam∙ je ulo╛ena spoleΦn∞ s datovou mno╛inou, ale bez popisu index∙. Z tohoto d∙vodu musφme p°idat k≤d kter² op∞tovn∞ vytvo°φ indexy po zavedenφ dat ze souboru.
Pokud v╛dy zavßdφme a uklßdßme stejn² soubor, pak m∙╛eme pou╛φt vlastnost FileName mφsto metod LoadFromFile a SaveToFile. Kdy╛ vlastnost FileName je nastavena na p°φpustnΘ jmΘno souboru, pak data jsou automaticky zavßd∞na ze souboru, kdy╛ klientskou datovou mno╛inu otev°eme a uklßdßna do souboru, kdy╛ klientskß datovß mno╛ina je uzav°ena.

Podpora aktovkovΘho modelu

Jednovrstvov² model m∙╛e b²t kombinovßn s vφce vrstvov²m modelem k vytvo°enφ aplikace aktovkovΘho modelu.
Poznßmka: Aktovkov² model se n∞kdy naz²vß rozpojiteln² model nebo model pro mobilnφ v²poΦty.
Kdy╛ pracujeme v sφti, pak aplikace aktovkovΘho modelu vypadß jako vφce vrstvov² model: u╛ivatel spustφ klientskou aplikaci na jednom poΦφtaΦi a p°ipojφ se prost°ednictvφm sφt∞ na aplikaΦnφ server na vzdßlenΘm poΦφtaΦi. Klient zφskß data z aplikaΦnφho serveru a zasφlß na n∞j aktualizace. Aktualizace jsou aplikovßny aplikaΦnφm serverem do databßze, kterß je sdφlena s ostatnφmi klienty organizace.
P°edpoklßdejme dßle, ╛e databßze obsahuje data, kterΘ na╣φ prodejnφ reprezentanti mohou pou╛φvat a aktualizovat. V tomto p°φpad∞, by bylo u╛iteΦnΘ, kdyby prodejnφ reprezentanti mohli stßhnout n∞jakß nebo v╣echna data z podnikovΘ databßze a pracovat s nimi na sv²ch p°enosn²ch poΦφtaΦφch mimo podnik a po nßvratu do podniku se p°ipojili k sφti a provedenΘ aktualizace na existujφcφch zßznamech a novΘ zßznamy byly p°eneseny zp∞t do podnikovΘ databßze pro obecnΘ pou╛itφ. Tato mo╛nost pracovat s odpojen²mi daty a pozd∞j╣φ aplikovßnφ zm∞n se naz²vß aktovkov² model.
Pou╛itφm aktovkovΘho modelu m∙╛eme p°evzφt v²hodu mo╛nostφ komponenty klientskΘ datovΘ mno╛iny Φφst a zapisovat data do ploch²ch soubor∙, kterΘ mohou b²t pou╛φvßny spoleΦn∞ s aplikaΦnφm serverem.
K implementaci aktovkovΘho modelu musφme:
  1. Vytvo°it vφce vrstvovou serverovou aplikaci.
  2. Vytvo°it jednovrstvovou databßzovou aplikaci ploch²ch soubor∙ jako na╣φ klientskou aplikaci. P°idat komponentu p°ipojenφ a nastavit vlastnost RemoteServer na╣i klientskΘ datovΘ mno╛iny na specifikaci tΘto komponenty p°ipojenφ. To umo╛nφ dotazovat se aplikaΦnφho serveru vytvo°enΘho v kroku 1.
  3. V klientskΘ aplikaci se pokusφme p°ipojit na aplikaΦnφ server. Pokud p°ipojenφ je ne·sp∞╣nΘ, pak se dotß╛eme u╛ivatele zda pro prßci pou╛φvat lokßlnφ kopii dat.
  4. Do klientskΘ aplikace p°idßme k≤d aplikujφcφ aktualizace na aplikaΦnφ server.

P°echod na vφce vrstvovΘ aplikace

Ve dvouvrstvovΘ aplikaci klient/server, aplikace je klientem dotazujφcφm se p°φmo databßzovΘho serveru. Aplikace mß dv∞ Φßsti: databßzovΘ p°ipojenφ a u╛ivatelskΘ rozhranφ. K p°evedenφ dvouvrstvovΘ aplikace klient/server na vφcevrstvovou aplikaci musφme: Je n∞kolik mo╛nostφ, jak to provΘst, ale nßsledujφcφ sekvence krok∙ zajistφ minimum pot°ebnΘ prßce:
  1. Vytvo°φme nov² projekt pro aplikaΦnφ server, poΦφnaje vzdßlen²m modulem dat.
  2. Duplikujeme Φßst databßzovΘho p°ipojenφ z na╣φ dvouvrstvovΘ aplikace a pro ka╛dou datovou mno╛inu a komponentu poskytovatele, vytvo°φme datovΘ propojenφ mezi aplikaΦnφm serverem a klientem.
  3. Z kopie na╣φ dvouvrstvovΘ aplikace odstranφme jejφ p°φmΘ databßzovΘ p°ipojenφ a p°idßme k nφ pot°ebnou komponentu propojenφ.
  4. Nahradφme v p∙vodnφm projektu ka╛dou datovou mno╛inu BDE klientskou datovou mno╛inou.
  5. Do klientskΘ aplikace p°idßme k≤d aplikujφcφ odlo╛enΘ aktualizace na aplikaΦnφ server.
  6. P°esuneme komponenty datov²ch mno╛in do datovΘho modulu aplikaΦnφho serveru. Nastavφme vlastnost DataSet ka╛dΘho poskytovatele na specifikaci odpovφdajφcφ datovΘ mno╛iny.

Prßce s daty pomocφ klientsk²ch datov²ch mno╛in

Jako u jin²ch datov²ch mno╛in, i klientskou datovou mno╛inu m∙╛eme pou╛φt k p°edßvßnφ dat datov²m ovladaΦ∙m prost°ednictvφm komponenty datovΘho zdroje.
Proto╛e TClientDataSet je potomkem TDataSet, klientskß datovß mno╛ina d∞dφ mnoho vlastnostφ, metod a udßlostφ definovan²ch pro v╣echny komponenty datov²ch mno╛in.
KlientskΘ datovΘ mno╛iny se li╣φ od ostatnφch datov²ch mno╛in v tom, ╛e dr╛φ v╣echna data v pam∞ti. Z tohoto d∙vodu, podpora obecn²ch databßzov²ch funkcφ musφ b²t roz╣φ°ena o dal╣φ mo╛nosti a funkce. N∞kterΘ z t∞chto funkcφ a rozdφl∙ zaveden²ch klientsk²mi datov²mi mno╛inami jsou popsßny v nßsledujφcφch bodech:

Prochßzenφ daty

Pokud aplikace pou╛φvß standardnφ datovΘ ovladaΦe, pak u╛ivatel m∙╛e prochßzet zßznamy klientskΘ datovΘ mno╛iny stejn∞ jako v jin²ch datov²ch mno╛inßch. Zßznamy m∙╛eme takΘ prochßzet programov∞ pomocφ standardnφch metod datov²ch mno╛in jako je First, GotoKey, Last, Next a Prior.
KlientskΘ datovΘ mno╛iny takΘ podporujφ mo╛nosti standardnφch zßlo╛ek pro oznaΦovßnφ a p°echod na specifikovan² zßznam.
Narozdφl od v∞t╣iny datov²ch mno╛in, klientskΘ datovΘ mno╛iny mohou takΘ umis╗ovat kurzor na specifikovan² zßznam v datovΘ mno╛in∞ pomocφ vlastnosti RecNo. Normßln∞ aplikace pou╛φvß RecNo k urΦenφ Φφsla zßznamu souΦasnΘho zßznamu. Klientskß datovß mno╛ina m∙╛e takΘ nastavit RecNo na Φφslo jistΘho zßznamu a ud∞lat tak tento zßznam souΦasn²m.

Omezovßnφ zßznam∙

K omezenφ u╛ivatele na podmno╛inu dostupn²ch dat, aplikace m∙╛e pou╛φt rozsahy a filtry. Kdy╛ aplikujeme rozsah nebo filtr, pak klientskß datovß mno╛ina nezobrazuje v╣echna data z pam∞ti. Jsou zobrazovßna pouze ta data, kterß spl≥ujφ podmφnku rozsahu nebo filtru.
Pro v∞t╣inu datov²ch mno╛in, °et∞zec filtru je rozklßdßn na p°φkazy SQL a ty jsou pak provßd∞ny na databßzovΘm serveru. KlientskΘ datovΘ mno╛iny majφ svoji vlastnφ podporu filtr∙, kterß zahrnuje v∞t╣inu operacφ ostatnφch datov²ch mno╛in. Nap°. kdy╛ pou╛ijeme klientskou datovou mno╛inu, pak v²raz filtru m∙╛e obsahovat °et∞zcovΘ operßtory, kterΘ vracejφ pod°et∞zce, operßtory rozklßdajφcφ ΦasovΘ nebo datumovΘ hodnoty a mnoho dal╣φch. KlientskΘ datovΘ mno╛iny mohou takΘ filtrovat polo╛ky BLOB nebo polo╛ky ADT a polo╛kovß pole.
Kdy╛ aplikujeme rozsah nebo filtr, klientskß datovß mno╛ina stßle uklßdß v╣echny svΘ zßznamy v pam∞ti. Rozsah nebo filtr pouze urΦuje, kterΘ zßznamy jsou dostupnΘ ovladaΦi pro prochßzenφ a zobrazovßnφ dat z klientskΘ datovΘ mno╛iny. Ve vφce vrstvov²ch aplikacφch, m∙╛eme takΘ omezit data ulo╛enß v klientsk²ch datov²ch mno╛inßch na podmno╛inu zßznam∙ p°edßnφm parametru aplikaΦnφmu serveru.

Podpora vzßjemnΘho vztahu Master-detail

Stejn∞ jako tabulky, i klientskΘ datovΘ mno╛iny podporujφ vztah Master-detail. Kdy╛ nastavφme vzßjemn² vztah Master-detail, pak propojφme dv∞ datovΘ mno╛iny tak, ╛e v╣echny zßznamy z jednΘ (detail) v╛dy odpovφdajφ jednomu souΦasnΘmu zßznamu v druhΘ (master).
Dßle m∙╛eme nastavit vzßjemn² vztah Master-detail v klientsk²ch datov²ch mno╛inßch pomocφ vno°en²ch tabulek. M∙╛eme to provΘst jednφm ze dvou zp∙sob∙: Kdy╛ na╣e klientskß datovß mno╛ina obsahuje vno°enou detailnφ datovou mno╛inu, pak TDBGrid poskytuje podporu pro zobrazovßnφ vno°enΘho detailu v zobrazenΘm okn∞. M∙╛eme takΘ zobrazovat a editovat tyto datovΘ mno╛iny v datov²ch ovladaΦφch pomocφ odd∞lenΘ klientskΘ datovΘ mno╛iny pro detailnφ mno╛inu. P°i nßvrhu, vytvo°φme trvalΘ polo╛ky pro polo╛ky v na╣i klientskΘ datovΘ mno╛in∞ vΦetn∞ polo╛ky DataSet pro vno°enou detailnφ mno╛inu.
Nynφ m∙╛eme vytvo°it klientskou datovou mno╛inu k reprezentaci vno°enΘ detailnφ mno╛iny. Nastavφme vlastnost DataSetField tΘto klientskΘ datovΘ mno╛iny na trvalou polo╛ku DataSet v datovΘ mno╛in∞ Master.
Ve vφce vrstvov²ch aplikacφch, pou╛φvßnφ vno°enΘ detailnφ mno╛iny je nutnΘ, pokud chceme aplikovat aktualizace z tabulek Master a Detail na aplikaΦnφ server. V databßzov²ch aplikacφch ploch²ch soubor∙, pou╛itφ vno°enΘ detailnφ mno╛iny umo╛≥uje uklßdat detaily se zßznamy Master do jednoho plochΘho souboru, namφsto zavßd∞nφ dvou samostatn²ch datov²ch mno╛in a op∞tovnΘho vytvß°enφ index∙ pro vytvo°enφ vzßjemnΘho vztahu.
Poznßmka: K pou╛itφ vno°enΘ detailnφ mno╛iny, vlastnost ObjectView klientskΘ datovΘ mno╛iny musφ b²t true.

Omezenφ datov²ch hodnot

KlientskΘ datovΘ mno╛iny poskytujφ podporu pro datovß omezenφ. V╛dy jsou podporovßna p°izp∙sobenß omezenφ. To umo╛≥uje poskytovat vlastnφ, aplikacφ definovanΘ omezenφ hodnot u╛ivatelem odesφlan²ch do klientskΘ datovΘ mno╛iny.
Dßle, pokud pou╛φvßme komponentu poskytovatele pro komunikaci se vzdßlen²m databßzov²m serverem, poskytovatel mß volby p°edßvajφcφ omezenφ serveru klientskΘ datovΘ mno╛in∞.
Ve vφcevrstvov²ch aplikacφch, mohou b²t okam╛iky, kdy pot°ebujeme datovß omezenφ vypnout, a to obzvlß╣t∞ kdy╛ klientskß datovß mno╛ina neobsahuje v╣echny zßznamy z odpovφdajφcφ datovΘ mno╛iny na aplikaΦnφm serveru.

Zp°φstupn∞nφ dat pouze pro Φtenφ

TDataSet zavßdφ vlastnost CanModify, kterou aplikace m∙╛e urΦovat, zda data v datovΘ mno╛in∞ mohou b²t editovßna. Aplikace nem∙╛e vlastnost CanModify zm∞nit, proto╛e pro n∞kterΘ potomky TDataSet, p°ipojenß databßze a ne aplikace, urΦuje zda data mohou b²t modifikovßny.
Proto╛e klientskß datovß mno╛ina reprezentuje data v pam∞ti, na╣e aplikace m∙╛e v╛dy °φdit, zda u╛ivatel m∙╛e editovat tato data. Pro zabrßn∞nφ u╛ivatele v editaci dat, nastavφme vlastnost ReadOnly klientskΘ datovΘ mno╛iny na true. Tφmto nastavenφm takΘ nastavφme vlastnost CanModify na false.
Na rozdφl od ostatnφch typ∙ datov²ch mno╛in, klientskou datovou mno╛inu nemusφme uzav°φt, kdy╛ chceme zm∞nit jeho mo╛nost zßpisu. Aplikace m∙╛e kdykoliv zm∞nit souΦasn² stav mo╛nosti zßpisu nastavenφm vlastnosti ReadOnly.

Editace dat

Klientskß datovß mno╛ina reprezentuje svß data jako paket dat v pam∞ti. Tento paket je hodnota vlastnosti Data klientskΘ datovΘ mno╛iny. Implicitn∞ ale editace nejsou uklßdßny ve vlastnosti Data. Vklßdßnφ, ru╣enφ a modifikace (provedenΘ u╛ivatelem nebo programov∞) jsou uklßdßny v internφm denφku zm∞n, reprezentovan²m vlastnostφ Delta. Denφk zm∞n slou╛φ ke dv∞ma ·Φel∙m: Vlastnost LogChanges povoluje zakßzat zaznamenßvßnφ zm∞n do denφku. Kdy╛ LogChanges je true, pak zm∞ny jsou do denφku zaznamenßvßny. Kdy╛ LogChanges je false, pak zm∞ny jsou p°φmo promφtnuty do vlastnosti Data. M∙╛eme tedy denφk zm∞n zakßzat pro jednovrstvovΘ aplikace, pokud nepot°ebujeme podporu pro ru╣enφ zm∞n.
Editace v denφku zm∞n z∙stßvajφ, pokud nejsou odstran∞ny aplikacφ. Aplikace odstra≥uje editace z denφku p°i: Poznßmka: Uklßdßnφ klientskΘ datovΘ mno╛iny do souboru neodstra≥uje editace z denφku zm∞n. Kdy╛ op∞tovn∞ zavedeme datovou mno╛inu, pak vlastnosti Data a Delta jsou stejnΘ jako kdy╛ data byla ulo╛ena.
Odvolßnφ zm∞n
P°esto╛e p∙vodnφ verze zßznam∙ z∙stßvß ve vlastnosti Data nezm∞n∞na, po opu╣t∞nφ a op∞tovnΘm nßvratu na editovan² zßznam, u╛ivatel vidφ poslednφ zm∞n∞nou verzi zßznamu. Pokud u╛ivatel nebo aplikace edituje zßznam n∞kolikrßt, pak ka╛dß zm∞n∞nß verze zßznamu je ulo╛ena do denφku zm∞n jako samostatnß polo╛ka.
Uklßdßnφ ka╛dΘ zm∞ny umo╛≥uje podporu vφce ·rovnφ operacφ undo k obnovenφ p°edchozφho stavu zßznamu.
K odstran∞nφ poslednφ zm∞ny na zßznamu volßme UndoLastChange. UndoLastChange p°ebφrß logick² parametr FollowChange, kter² indikuje zda kurzor p°esunout na obnoven² zßznam (true) nebo ponechat kurzor na souΦasnΘm zßznamu (false). Pokud je n∞kolik zm∞n na jednom zßznamu, pak ka╛dΘ volßnφ UndoLastChange odstra≥uje poslednφ vrstvu editace. UndoLastChange vracφ logickou hodnotu indikujφcφ ·sp∞ch odstran∞nφ zm∞ny. Vlastnost ChangeCount slou╛φ k urΦenφ zda je je╣t∞ vφce zm∞n ke zru╣enφ. ChangeCount urΦuje poΦet zm∞n ulo╛en²ch do denφku zm∞n.
Mφsto odstra≥ovßnφ jednotliv²ch vrstev zm∞n na jednom zßznamu, m∙╛eme je v╣echny odstranit najednou. K odstran∞nφ v╣ech zm∞n zßznamu, vybereme zßznam a volßme RevertRecord. RevertRecord odstra≥uje v╣echny zm∞ny souΦasnΘho zßznamu z denφku zm∞n.
Kdykoliv v pr∙b∞hu editace m∙╛eme ulo╛it souΦasn² stav denφku zm∞n pomocφ vlastnosti SavePoint. P°eΦtenφm SavePoint navrßtφme oznaΦovaΦ na souΦasnou pozici v denφku zm∞n. Pozd∞ji, pokud chceme zru╣it v╣echny zm∞ny od p°eΦtenΘho bodu ulo╛enφ, pak nastavφme SavePoint na p°edem p°eΦtenou hodnotu. Na╣e aplikace m∙╛e zφskat hodnoty pro vφce bod∙ ulo╛enφ. Pokud se p°esuneme zp∞t v denφku zm∞n na bod ulo╛enφ, pak hodnoty v╣ech nßsledujφcφch bod∙ ulo╛enφ jsou chybnΘ.
V╣echny zm∞ny ulo╛enΘ v denφku zm∞n m∙╛eme zru╣it volßnφm CancelUpdates. CancelUpdates vyprazd≥uje denφk zm∞n, Φφm╛ efektivn∞ zru╣φme v╣echny editace v╣ech zßznam∙. P°i volßnφ CancelUpdates musφme b²t opatrnφ. Po volßnφ CancelUpdates nelze obnovit ╛ßdnou zm∞nu z denφku.
Ulo╛enφ zm∞n
KlientskΘ datovΘ mno╛iny pou╛φvajφ r∙znΘ mechanismy pro p°evzetφ zm∞n z denφku zm∞n, v zßvislosti na tom, zda jsou pou╛ity v samostatnΘ aplikaci nebo reprezentujφ data se vzdßlenΘho aplikaΦnφho serveru. Bez ohledu na pou╛it² mechanismus, denφk zm∞n je automaticky vyprßzdn∞n po p°evzetφ v╣ech zm∞n.
SamostatnΘ aplikace mohou jednodu╣e sluΦovat zm∞ny do lokßlnφ vyrovnßvacφ pam∞ti reprezentovanΘ vlastnostφ Data. Nenφ nutno se zab²vat °e╣enφm konflikt∙ se zm∞nami proveden²mi jin²mi u╛ivateli. Pro slouΦenφ denφku zm∞n do vlastnosti Data volßme metodu MergeChangeLog.
Metodu MergeChangeLog nem∙╛eme pou╛φt ve vφce vrstvov²ch aplikacφch. AplikaΦnφ server pot°ebuje informace z denφku zm∞n aby mohl rozpustit aktualizovanΘ zßznamy v datech ulo╛en²ch v databßzi. Volßme ApplyUpdates, kterß zasφlß zm∞ny na aplikaΦnφ server a aktualizuje vlastnost Data pouze tehdy, kdy╛ modifikace byly ·sp∞╣n∞ odeslßny do databßze.

╪azenφ a indexovßnφ

Pou╛φvßnφ index∙ poskytuje n∞kolik v²hod na╣im aplikacφm: Pokud klientskß datovß mno╛ina je pou╛ita ve vφce vrstvovΘ aplikaci, pak zd∞dφ implicitnφ index a °adφcφ po°adφ od dat zφskan²ch z aplikaΦnφho serveru. Implicitnφ index se naz²vß DEFAULT_ORDER. Toto po°adφ m∙╛eme pou╛φt, ale nem∙╛eme zm∞nit nebo zru╣it index.
Mimo implicitnφho indexu, klientskß datovß mno╛ina udr╛uje sekundßrnφ index, nazvan² CHANGEINDEX, na zm∞n∞n²ch zßznamech ulo╛en²ch v denφku zm∞n (vlastnost Delta). CHANGEINDEX °adφ v╣echny zßznamy v klientskΘ datovΘ mno╛in∞ jak budou zobrazeny, pokud zm∞ny specifikovanΘ v Delta budou aplikovßny. CHANGEINDEX je zalo╛en na po°adφ zd∞d∞nΘm od DEFAULT_ORDER. CHANGEINDEX nelze takΘ zm∞nit nebo zru╣it.
M∙╛eme pou╛φvat ostatnφ existujφcφ indexy pro datovou mno╛inu a m∙╛eme vytvß°et svΘ vlastnφ indexy. V nßsledujφcφch bodech je popsßno jak vytvß°et a pou╛φvat indexy v klientsk²ch datov²ch mno╛inßch:
P°idßvßnφ nov²ch index∙
K vytvo°enφ novΘho indexu pro klientskou datovou mno╛inu volßme AddIndex. AddIndex umo╛≥uje specifikovat vlastnosti indexu vΦetn∞: Tip: Indexovat a °adit m∙╛eme v klientsk²ch datov²ch mno╛inßch, i na internφch poΦitateln²ch polo╛kßch.
Vytvo°enΘ indexy jsou °azeny ve vzestupnΘm abecednφm po°adφ zßvisejφcφm na nßrodnostnφm nastavenφ poΦφtaΦe. V parametru voleb indexu m∙╛eme p°idat ixDescending k nastavenφ volby p°episujφcφ implicitnφ nastavenφ.
Poznßmka: Kdy╛ vytvß°φme indexy ve stejnΘ dob∞ jako klientskß datovß mno╛ina, pak m∙╛eme vytvo°it indexy, kterΘ °adφ ve vzestupnΘm po°adφ na n∞kter²ch polo╛kßch a sestupnΘ °azenφ na jin²ch.
╪azenφ °et∞zcov²ch polo╛ek v indexech implicitn∞ rozli╣uje velikost pφsmen. V parametru voleb indexu m∙╛eme p°idat ixCaseInsensitive k ignorovßnφ velikosti pφsmen p°i °azenφ.
Poznßmka: Kdy╛ vytvß°φme indexy ve stejnΘ dob∞ jako klientskß datovß mno╛ina, pak m∙╛eme vytvß°et indexy, kterΘ v n∞kter²ch polo╛kßch rozli╣ujφ velikost pφsmen a v jin²ch ne.
Varovßnφ: Indexy p°idanΘ pomocφ AddIndex nejsou uklßdßny p°i uklßdßnφ klientskΘ datovΘ mno╛iny do souboru.
Ru╣enφ a p°epφnßnφ index∙
K odstran∞nφ nßmi vytvo°en²ch index∙ pro klientskou datovou mno╛inu, volßme DeleteIndex a specifikujeme jmΘno odstra≥ovanΘho indexu. Indexy DEFAULT_ORDER a CHANGEINDEX nelze odstranit.
K pou╛itφ r∙zn²ch index∙ s klientskou datovou mno╛inou, kdy╛ je dostupn²ch vφce index∙, pou╛ijeme vlastnost IndexName k v²b∞ru pou╛φvanΘho indexu. B∞hem nßvrhu, m∙╛eme vybφrat z dostupn²ch index∙ v rozbalovacφm seznamu vlastnosti IndexName v Inspektoru objekt∙.
Pou╛φvßnφ index∙ k seskupovßnφ dat
Kdy╛ v na╣φ klientskΘ datovΘ mno╛in∞ pou╛ijeme index, urΦφme tφm automaticky °adφcφ po°adφ zßznam∙. Se°azenΘ zßznamy obvykle obsahujφ duplicitnφ hodnoty na polo╛kßch tvo°φcφch index. Nap°. p°edpoklßdejme nßsledujφcφ Φßst tabulky objednßvek, kterß je indexovßna na polo╛kßch SalesRep a Customer:
 
SalesRep Customer OrderNo Amount
1 1 5 100
1 1 2 50
1 2 3 200
1 2 6 75
2 1 1 10
2 3 4 200

Vidφme, ╛e hodnoty ve sloupci SalesRep se opakujφ. V zßznamech pro SalesRep Φφsla 1, se opakujφ hodnoty ve sloupci Customer. Tedy data lze seskupit podle SalesRep a ve skupin∞ SalesRep je m∙╛eme seskupit podle Customer. Ka╛dΘ seskupovßnφ mß p°i°azenou ·rove≥. V na╣em p°φpad∞, skupina SalesRep mß ·rove≥ 1 (proto╛e nenφ vno°ena do ╛ßdnΘ jinΘ skupiny) a skupina Customer mß ·rove≥ 2 (proto╛e je vno°ena ve skupin∞ ·rovn∞ 1). ┌rove≥ seskupovßnφ odpovφdß po°adφ polo╛ek v indexu. Kdy╛ vytvß°φme index, pak m∙╛eme specifikovat podporovanΘ ·rovn∞ seskupovßnφ (a╛ do poΦtu polo╛ek v indexu).
KlientskΘ datovΘ mno╛iny umo╛≥ujφ urΦit, kde souΦasn² zßznam se v danΘ seskupovacφ ·rovni nachßzφ. To umo╛≥uje na╣φ aplikaci zobrazovat zßznamy r∙zn∞, a to podle toho, zda se jednß o prvnφ zßznam skupiny, prost°ednφ zßznam skupiny nebo poslednφ zßznam skupiny. Nap°. m∙╛eme chtφt zobrazovat opakujφcφ se hodnoty pouze v prvnφm zßznamu skupiny. Pokud to provedeme pro p°edchozφ tabulku, pak zφskßme:
 
SalesRep Customer OrderNo Amount
1 1 5 100
2 50
2 3 200
6 75
2 1 1 10
3 4 200

K urΦenφ, kde ve skupin∞ se nachßzφ souΦasn² zßznam, pou╛φvßme metodu GetGroupState. GetGroupState p°ebφrß celΘ Φφslo urΦujφcφ ·rove≥ seskupovßnφ a vracφ hodnotu indikujφcφ, kde se ve skupin∞ nachßzφ souΦasn² zßznam.

Indexovßnφ za b∞hu
Mφsto vytvß°enφ index∙, kterΘ se stanou Φßstφ klientskΘ datovΘ mno╛iny, m∙╛eme vytvß°et doΦasnΘ indexy za b∞hu specifikacφ polo╛ek pou╛it²ch pro indexovßnφ ve vlastnosti IndexFieldNames. JmΘna polo╛ek odd∞lujeme st°ednφky. Po°adφ jmen polo╛ek v seznamu je v²znamnΘ.
Poznßmka: P°i tomto zp∙sobu indexovßnφ nelze urΦit sestupnΘ °azenφ a nerozli╣ovßnφ velikosti pφsmen. TakΘ zde nenφ podpora pro seskupovßnφ.

Reprezentace poΦitateln²ch hodnot

Jako v jin²ch datov²ch mno╛inßch i v klientsk²ch datov²ch mno╛inßch lze pou╛φvat poΦitatelnΘ polo╛ky. Jsou to polo╛ky jejich╛ hodnoty jsou poΦφtßny dynamicky, obvykle na zßklad∞ hodnot ostatnφch polo╛ek ve stejnΘm zßznamu. KlientskΘ datovΘ mno╛iny umo╛≥ujφ optimalizaci poΦitateln²ch polo╛ek pou╛itφm internφch poΦitateln²ch polo╛ek.
M∙╛eme takΘ °φci klientsk²m datov²m mno╛inßm, aby vytvß°ely poΦitatelnΘ hodnoty, kterΘ sumarizujφ data z n∞kolika zßznam∙ pomocφ udr╛ovan²ch agregßt∙.
Pou╛φvßnφ internφch poΦitateln²ch polo╛ek v klientsk²ch datov²ch mno╛inßch
V ostatnφch datov²ch mno╛inßch, na╣e aplikace musφ vypoΦφtat hodnoty poΦitateln²ch polo╛ek poka╛dΘ, kdy╛ se zm∞nφ zßznam nebo u╛ivatel edituje n∞jakou polo╛ku v souΦasnΘm zßznamu. Provßdφ to obsluha udßlosti OnCalcFields.
I kdy╛ toto je mo╛no stßle pou╛φvat, klientskΘ datovΘ mno╛iny minimalizujφ poΦet p°epoΦφtßvan²ch poΦitateln²ch polo╛ek uklßdßnφm vypoΦφtan²ch hodnot do klientskΘ datovΘ mno╛iny. I kdy╛ tyto hodnoty jsou uklßdßny s klientskou datovou mno╛inou, je stßle zapot°ebφ p°epoΦφtßvat hodnoty, kdy╛ u╛ivatel edituje souΦasn² zßznam, ale aplikace ji╛ nepot°ebuje provßd∞t p°epoΦφtßvßnφ p°i zm∞n∞ souΦasnΘho zßznamu. K ulo╛enφ vypoΦφtan²ch hodnot do dat klientskΘ datovΘ mno╛iny, pou╛φvßme mφsto poΦitateln²ch polo╛ek internφ poΦitatelnΘ polo╛ky.
Internφ poΦitatelnΘ polo╛ky, stejn∞ jako poΦitatelnΘ polo╛ky, jsou vypoΦφtßvßny v obsluze udßlosti OnCalcFields. M∙╛eme ale optimalizovat obsluhu udßlosti testovßnφm vlastnosti State na╣φ klientskΘ datovΘ mno╛iny. Kdy╛ stav je dsInternalCalc, pak internφ poΦitatelnΘ polo╛ky musφme p°epoΦφtat. P°i stavu dsCalcFields musφme p°epoΦφtat normßlnφ poΦitatelnΘ polo╛ky.
K pou╛φvßnφ internφch poΦitateln²ch polo╛ek, musφme definovat polo╛ky jako intern∞ poΦitatelnΘ d°φve ne╛ vytvo°φme klientskou datovou mno╛inu. Pokud vytvß°φme klientskou datovou mno╛inu pou╛φvajφcφ trvalΘ polo╛ky, definujeme polo╛ky jako intern∞ poΦitatelnΘ v²b∞rem InternalCalc v Editoru polo╛ek. Kdy╛ vytvß°φme klientskou datovou mno╛inu pomocφ definic polo╛ek, pak nastavφme vlastnost InternalCalcField odpovφdajφcφ definice polo╛ky na true.
Poznßmka: Ostatnφ typy datov²ch mno╛in pou╛φvajφ internφ poΦitatelnΘ polo╛ky. NicmΘn∞ s ostatnφmi datov²mi mno╛inami, tyto hodnoty nep°epoΦφtßvßme v obsluze udßlosti OnCalcFields. Jsou poΦφtßny automaticky BDE nebo vzdßlen²m databßzov²m serverem.
Pou╛φvßnφ udr╛ovan²ch agregßt∙
KlientskΘ datovΘ mno╛iny poskytujφ podporu pro sumarizaci dat nad skupinami zßznam∙. Proto╛e tyto sumarizace jsou automaticky aktualizovßny p°i editaci dat v datovΘ mno╛in∞, jsou tato sumarizovanß data naz²vßna udr╛ovanΘ agregßty.
Ve svΘ nejjednodu╣╣φ form∞, udr╛ovanΘ agregßty umo╛≥ujφ zφskßvat informace typu souΦet v╣ech hodnot ve sloupci klientskΘ datovΘ mno╛iny. Jsou flexibilnφ, ale pro podporu r∙zn²ch souΦtov²ch v²poΦt∙ a k poskytnutφ mezisouΦt∙ pro skupiny zßznam∙ definujeme polo╛ky v indexu, kterΘ podporujφ seskupovßnφ.
Nßsledujφcφ body popisujφ jak to provΘst: Specifikovßnφ agregßt∙
Ke specifikaci, co chceme v klientskΘ datovΘ mno╛in∞ nad zßznamy sumarizovat, pou╛ijeme vlastnost Aggregates. Aggregates je kolekce agregaΦnφch specifikacφ (TAggregate). M∙╛eme p°idßvat agregaΦnφ specifikßtory k na╣φ klientskΘ datovΘ mno╛in∞ pomocφ Editoru polo╛ek p°i nßvrhu, nebo pomocφ metody Add vlastnosti Aggregates za b∞hu. Pokud chceme vytvo°it polo╛kovou komponentu pro agregßty, vytvo°φme trvalou polo╛ku pro agregovanΘ hodnoty v Editoru polo╛ek.
Poznßmka: Kdy╛ vytvß°φme agregovanΘ polo╛ky, pak p°φslu╣nΘ agregovanΘ objekty jsou p°idßny k vlastnosti Aggregates klientskΘ datovΘ mno╛iny automaticky.
Pro ka╛d² agregßt, vlastnost Expression indikuje jak² v²poΦet jej reprezentuje. Expression m∙╛e obsahovat jednoduch² souΦtov² v²raz jako
Sum(Field1)
nebo slo╛it∞j╣φ v²raz, kombinujφcφ informace z n∞kolika polo╛ek, jako
Sum(Qty * Price) - Sum(AmountPaid)
AgregaΦnφ v²razy zahrnujφ jeden nebo vφce sumßrnφch operßtor∙ z nßsledujφcφ tabulky:
 
Operßtor Pou╛itφ
Sum SouΦet hodnot pro numerickou polo╛ku nebo v²raz.
Avg V²poΦet pr∙m∞rnΘ hodnoty pro ΦφselnΘ, datumov∞ ΦasovΘ polo╛ky nebo v²razy.
Count Specifikuje poΦet neprßzdn²ch hodnot pro polo╛ku nebo v²raz.
Min Indikuje minimßlnφ hodnotu pro °et∞zcovou, Φφselnou nebo datumovo Φasovou polo╛ku nebo v²raz.
Max Indikuje maximßlnφ hodnotu pro °et∞zcovou, Φφselnou nebo datumovo Φasovou polo╛ku nebo v²raz.

Sumßrnφ operßtory pracujφ na hodnotßch polo╛ek nebo v²razech vytvo°en²ch z hodnot polo╛ek pomocφ stejn²ch operßtor∙ jako pou╛φvßme pro vytvß°enφ filtr∙. Sumßrnφ operßtory ale nelze vno°ovat. M∙╛eme vytvo°it v²raz pou╛φvajφcφ operßtory na sumarizovan²ch hodnotßch s jinou sumarizovanou hodnotou nebo na sumarizovanΘ hodnot∞ a konstant∞. Nelze ale kombinovat sumarizovanΘ hodnoty s hodnotami polo╛ek. Tato pravidla jsou pou╛ita v nßsledujφcφch v²razech:
 
Sum(Qty * Price) povoleno - souΦet v²raz∙ na polo╛kßch
Max(Field1) - Max(Field2) povoleno - v²raz na sumarizovan²ch hodnotßch
Avg(DiscountRate) * 100 povoleno - v²raz sumarizovanΘ hodnoty a konstanty
Min(Sum(Field1)) nepovoleno - vno°enΘ sumarizovanΘ hodnoty
Count(Field1) - Field2 nepovoleno - v²raz sumßrnφ hodnoty a polo╛ky

Agregovßnφ nad skupinami zßznam∙
Implicitn∞, udr╛ovanΘ agregßty jsou vypoΦφtßvßny tak, ╛e sumarizujφ v╣echny zßznamy v klientskΘ datovΘ mno╛in∞. NicmΘn∞ m∙╛eme specifikovat, ╛e chceme sumarizovat nad zßznamy ve skupinßch. To umo╛≥uje poskytnout bezprost°ednφ sumarizace jako jsou mezisouΦty pro skupiny zßznam∙, kterΘ sdφlejφ spoleΦnΘ hodnoty polo╛ky.
D°φve ne╛ m∙╛eme specifikovat udr╛ovan² agregßt nad skupinami zßznam∙, musφme pou╛φt index, kter² podporuje pot°ebnΘ seskupovßnφ. Kdy╛ ji╛ mßme index, kter² seskupuje pot°ebn²m zp∙sobem data, pak specifikujeme vlastnosti IndexName a GroupingLevel agregßtu k indikaci, kter² index pou╛φt a kterß skupina nebo podskupina na tomto indexu definuje seskupovßnφ zßznam∙.
Nap°. p°edpoklßdejme nßsledujφcφ Φßst z tabulky objednßvek, kterß je seskupena podle SalesRep a v SalesRep podle Customer:
 
SalesRep Customer OrderNo Amount
1 1 5 100
1 1 2 50
1 2 3 200
1 2 6 75
2 1 1 10
2 3 4 200

Nßsledujφcφ k≤d nastavuje udr╛ovan² agregßt, kter² indikuje celkovß mno╛stvφ pro ka╛dΘho prodejnφho reprezentanta:
Agg->Expression = "Sum(Amount)";
Agg->IndexName = "SalesCust";
Agg->GroupingLevel = 1;
Agg->AggregateName = "Total for Rep";
Pro p°idßnφ agregßtu, kter² sumarizuje pro ka╛dΘho zßkaznφka danΘho prodejnφho reprezentanta, vytvo°φme udr╛ovan² agregßt s ·rovnφ 2.
Udr╛ovanΘ agregßty, kterΘ sumarizujφ nad skupinami zßznam∙ jsou p°i°azeny k jistΘmu indexu. Vlastnost Aggregates m∙╛e obsahovat agregßty, kterΘ pou╛φvajφ r∙znΘ indexy. NicmΘn∞, pouze agregßty, kterΘ sumarizujφ nad celou datovou mno╛inou a ty, kterΘ pou╛φvajφ souΦasn² index jsou p°φpustnΘ. Zm∞nou souΦasnΘho indexu se zm∞nφ p°φpustnΘ agregßty. K urΦenφ, kterΘ agregßty jsou p°φpustnΘ v dan² Φas pou╛ijeme vlastnost ActiveAggs.

Zφskßvßnφ agregovan²ch hodnot
K zφskßnφ hodnot udr╛ovan²ch agregßt∙, volßme metodu Value objektu TAggregate, kter² reprezentuje agregßt. Vrßcenß hodnota udr╛ovanΘho agregßtu je pro skupinu, kterß obsahuje souΦasn² zßznam klientskΘ datovΘ mno╛iny.
Kdy╛ sumarizujeme nad celou klientskou datovou mno╛inou, pak m∙╛eme volat Value kdykoliv k zφskßnφ udr╛ovanΘho agregßtu. Pokud ale sumarizujeme nad seskupen²mi informacemi, pak musφme b²t opatrnφ aby souΦasn² zßznam byl ve skupin∞, jejφ╛ sumarizaci chceme zφskat. Z tohoto d∙vodu je dobrou my╣lenkou zφskat agregovanΘ hodnoty v p°esn∞ definovan²ch okam╛icφch, jako nap°. kdy╛ se p°esuneme na prvnφ zßznam skupiny nebo p°i p°esunu na poslednφ zßznam skupiny. K urΦenφ, kde se souΦasn² zßznam nachßzφ ve skupin∞ pou╛φvßme metodu GetGroupState.
K zobrazenφ udr╛ovan²ch agregßt∙ v datov²ch ovladaΦφch, pou╛ijeme Editor polo╛ek k vytvo°enφ trvalΘ agregovanΘ polo╛kovΘ komponenty. Kdy╛ specifikujeme agregovanou polo╛ku v Editoru polo╛ek, pak Aggregates klientskΘ datovΘ mno╛iny je automaticky aktualizovßn vlo╛enφm p°φslu╣nΘ agregaΦnφ specifikace. Vlastnost AggFields obsahuje novou agregovanou polo╛kovou komponentu a metoda FindField ji vracφ.

P°idßvßnφ informacφ specifick²ch pro aplikaci k dat∙m

V²vojß° aplikace, m∙╛e p°idat k vlastnosti Data klientskΘ datovΘ mno╛iny, svΘ informace. Proto╛e tyto informace tvo°φ s ostatnφmi daty paket, jsou takΘ obsa╛eny, kdy╛ uklßdßme data do souboru nebo do proudu. Jsou takΘ kopφrovßny, kdy╛ kopφrujeme data do jinΘ datovΘ mno╛iny. Nepovinn∞ mohou b²t i vklßdßny do vlastnosti Delta a tak aplikaΦnφ server m∙╛e tyto informace Φφst, kdy╛ zφskßvß aktualizace od klient∙.
K ulo╛enφ informacφ specifick²ch pro aplikaci do vlastnosti Data, pou╛ijeme metodu SetOptionalParam. Tato metoda uklßdß OleVariant, kter² obsahuje data pod specifikovan²m jmΘnem.
K zφskßnφ t∞chto informacφ pou╛ijeme metodu GetOptionalParam s p°edßnφm jmΘna pod kter²m jsou informace ulo╛eny.

Kopφrovßnφ dat z jinΘ datovΘ mno╛iny

Pro kopφrovßnφ dat z jinΘ datovΘ mno╛iny p°i nßvrhu, v mφstnφ nabφdce klientskΘ datovΘ mno╛iny zvolφme Assign Local Data. Zobrazen² dialog uvßdφ seznam v╣ech dostupn²ch datov²ch mno╛in v projektu. Vybereme jednu, ze kterΘ chceme kopφrovat a stiskneme OK. Kdy╛ kopφrujeme zdrojovou datovou mno╛inu, pak na╣e klientskß datovß mno╛ina je automaticky aktivovßna.
Pro kopφrovßnφ z jinΘ datovΘ mno╛iny za b∞hu, m∙╛eme p°i°azovat jejφ data p°φmo nebo, pokud zdrojem je jinß klientskß datovß mno╛ina, pak m∙╛eme kurzor klonovat.

P°φmΘ p°i°azenφ dat

M∙╛eme pou╛φt vlastnost Data klientskΘ datovΘ mno╛iny k p°i°azenφ dat klientskΘ datovΘ mno╛in∞ z jinΘ datovΘ mno╛iny. Data je OleVariant ve tvaru paketu dat. Datov² paket m∙╛eme zφskat z jinΘ klientskΘ datovΘ mno╛iny, nebo z libovolnΘ jinΘ datovΘ mno╛iny pomocφ poskytovatele. Kdy╛ datov² paket je p°i°azen vlastnosti Data, jeho obsah je automaticky zobrazovßn v datov²ch ovladaΦφch p°ipojen²ch ke klientskΘ datovΘ mno╛in∞ prost°ednictvφm komponenty datovΘho zdroje.
Kdy╛ otev°eme klientskou datovou mno╛inu, kterß pou╛φvß komponentu poskytovatele, pak datovΘ pakety jsou automaticky p°i°azeny vlastnosti Data.
Kdy╛ na╣e klientskß mno╛ina nepou╛φvß poskytovatele, pak m∙╛eme kopφrovat data z jinΘ klientskΘ datovΘ mno╛iny takto:
ClientDataSet1->Data = ClientDataSet2->Data;
Poznßmka: Kdy╛ kopφrujeme vlastnost Data jinΘ klientskΘ datovΘ mno╛iny, pak takΘ kopφrujeme denφk zm∞n, ale nekopφrujeme rozsahy nebo filtry, kterΘ mohly b²t aplikovßny. K vlo╛enφ filtr∙ a rozsah∙, musφme klonovat kurzor zdrojovΘ datovΘ mno╛iny.
Pokud chceme p°i°adit data z datovΘ mno╛iny podporujφcφ BDE, pak m∙╛eme pou╛φt jejφ vlastnost Provider ke kopφrovßnφ dat bez nutnosti p°idßnφ komponenty poskytovatele:
ClientDataSet1->Data = Table1->Provider->Data;
Pokud kopφrujeme z p°izp∙sobenΘ datovΘ mno╛iny, pak m∙╛eme vytvo°it komponentu poskytovatele datovΘ mno╛iny, p°ipojit ji k zdrojovΘ datovΘ mno╛in∞ a pak kopφrovat jejφ data:
TempProvider = new TDataSetProvider(Form1);
TempProvider->DataSet = SourceDataSet; // SourceDataSet je p°izp∙sobenß datovß mno╛ina
ClientDataSet1->Data = TempProvider->Data;
delete TempProvider;
Poznßmka: Kdy╛ p°φmo p°i°adφme vlastnost Data, pak nov² paket dat nenφ slouΦen s existujφcφmi daty. V╣echna p°edchozφ data jsou nahrazena.
Pokud chceme slouΦit zm∞ny z jinΘ datovΘ mno╛iny (mφsto kopφrovßnφ jejich dat), pak musφme pou╛φt komponentu poskytovatele.

Klonovßnφ kurzoru klientskΘ datovΘ mno╛iny

TClientDataSet poskytuje proceduru CloneCursor k umo╛n∞nφ prßce s druh²m pohledem na specifikovanou klientskou datovou mno╛inu za b∞hu. CloneCursor umo╛≥uje druhΘ klientskΘ datovΘ mno╛in∞ sdφlet data p∙vodnφ klientskΘ datovΘ mno╛iny. Je to v²hodn∞j╣φ ne╛ kopφrovßnφ v╣ech p∙vodnφch dat, ale proto╛e data jsou sdφlena, druhß klientskß datovß mno╛ina nem∙╛e modifikovat data bez ovlivn∞nφ p∙vodnφ klientskΘ datovΘ mno╛iny.
CloneCursor p°ebφrß t°i parametry: Source specifikuje klonovanou klientskou datovou mno╛inu. Poslednφ dva parametry (Reset a KeepSetting) indikujφ zda kopφrovat i jinΘ informace ne╛ data. Tyto informace zahrnujφ filtry, souΦasn² index, spojenφ s tabulkou Master (kdy╛ zdrojovß datovß mno╛ina je tabulkou Detail), vlastnost ReadOnly a libovolnß spojenφ na p°ipojovacφ komponentu nebo rozhranφ poskytovatele.
Kdy╛ Reset a KeepSetting jsou false, klonovanß klientskß datovß mno╛ina je otev°ena a nastavenφ zdrojovΘ klientskΘ datovΘ mno╛iny jsou pou╛ity k nastavenφ vlastnostφ cφle. Kdy╛ Reset je true, pak vlastnosti cφlovΘ datovΘ mno╛iny zφskajφ svΘ implicitnφ hodnoty (nenφ filtr nebo index, nenφ tabulka Master, ReadOnly je false a nejsou specifikovßny komponenty p°ipojenφ nebo poskytovatele). Kdy╛ KeepSettings je true, pak vlastnosti cφlovΘ datovΘ mno╛iny se nem∞nφ.

Pou╛φvßnφ klientskΘ datovΘ mno╛iny s poskytovatelem dat

Kdy╛ pou╛φvßme klientskou datovou mno╛inu ve vφce vrstvov²ch aplikacφch, pak klientskß datovß mno╛ina pou╛φvß rozhranφ IProvider k zφskßnφ dat z aplikaΦnφho serveru a po editaci dat, kterΘ je lokßlnφ, jsou aktualizace aplikovßny na vzdßlenou databßzi.
Tento proces popisujφ nßsledujφcφ body:

Specifikovßnφ poskytovatele dat

D°φve ne╛ klientskß datovß mno╛ina m∙╛e zφskßvat data z a aplikovat aktualizace na aplikaΦnφ server, musφ zφskat rozhranφ IProvider. Jednovrstvovß aplikace a klientskΘ aplikace pou╛φvajφcφ aktovkov² model nemajφ rozhranφ IProvider definovßno. Ve vφce vrstvov²ch aplikacφch, obvykle pou╛φvßme vlasnosti RemoteServer a ProviderName k v²b∞ru rozhranφ poskytovatele z dostupn²ch rozhranφ v klientskΘ aplikaci.
RemoteServer specifikuje jmΘno komponenty p°ipojenφ ve kterΘ zφskßme seznam poskytovatel∙. Komponenta p°ipojenφ sφdlφ ve stejnΘm datovΘm modulu jako klientskß datovß mno╛ina. Z°izuje a udr╛uje p°ipojenφ na aplikaΦnφ server, n∞kdy naz²van² Datov² agent (data broker).
P°i nßvrhu (po specifikaci RemoteServer), m∙╛eme vybrat poskytovatele v rozbalovacφm seznamu vlastnosti ProviderName v Inspektoru objekt∙. Za b∞hu m∙╛eme p°epφnat mezi dostupn²mi poskytovateli nastavenφm vlastnosti ProviderName k≤dem.

P°edßvßnφ parametr∙ na aplikaΦnφ server

KlientskΘ datovΘ mno╛iny mohou p°edßvat parametry na aplikaΦnφ server ke specifikaci, kterß data chceme poskytovat v zasφlan²ch datov²ch paketech. Tyto parametry mohou specifikovat: Hodnoty parametr∙, kterΘ na╣e klientskß datovß mno╛ina zasφlß na aplikaΦnφ server, m∙╛eme specifikovat p°i nßvrhu nebo za b∞hu. P°i nßvrhu, vybereme klientskou datovou mno╛inu a dvojit∞ klikneme na vlastnost Params v Inspektoru objekt∙. Tφm vyvolßme Editor parametr∙, kde m∙╛eme p°idßvat, ru╣it a p°esouvat parametry. V²b∞rem parametru v tomto Editoru se parametr zobrazφ v Inspektoru objekt∙, kde m∙╛eme editovat jeho vlastnosti.
Za b∞hu pou╛ijeme metodu CreateParam vlastnosti Params k p°idßvßnφ parametr∙ k na╣φ klientskΘ datovΘ mno╛in∞. CreateParam vracφ objekt parametru dan² specifikovan²m jmΘnem, typem parametru a datov²m typem. Pak m∙╛eme pou╛φt vlastnosti parametru objektu k p°i°azenφ hodnoty parametru.
Nap°. nßsledujφcφ k≤d nastavuje hodnotu parametru nazvanΘho CustNo na 605:
TParam *pParam=ClientDataSet1->Params->CreateParam(ftInteger,"CustNo", ptInput);
pParam->AsInteger = 605;
Pokud klientskß datovß mno╛ina nenφ aktivnφ, pak m∙╛eme zaslat parametry na aplikaΦnφ server a zφskat datov² paket, kter² zohled≥uje hodnoty t∞chto parametru, jednoduch²m nastavenφm vlastnosti Active na true.
Pokud klientskß datovß mno╛ina je ji╛ aktivnφ, pak m∙╛eme pou╛φt metodu SendParams k zaslßnφ hodnot parametr∙ na aplikaΦnφ server. Pak musφme explicitn∞ po╛adovat dal╣φ data z aplikaΦnφho serveru. AplikaΦnφ server op∞tovn∞ spustφ dotaz nebo ulo╛enou proceduru pomocφ nov²ch hodnot parametr∙ a pak zaΦne poskytovat data poΦφnaje prvnφm zßznamem v novΘ v²sledkovΘ mno╛in∞.
Poznßmka: M∙╛eme chtφt inicializovat hodnoty parametr∙ od souΦasnΘho nastavenφ na aplikaΦnφm serveru. Provedeme to volbou Fetch Params v mφstnφ nabφdce klientskΘ datovΘ mno╛iny p°i nßvrhu nebo volßnφm metody FetchParams za b∞hu.
Zasφlßnφ parametr∙ dotaz∙ a ulo╛en²ch procedur
Kdy╛ poskytovatel na aplikaΦnφm serveru reprezentuje v²sledek dotazu nebo ulo╛enΘ procedury, pak m∙╛eme pou╛it vlastnost Params ke specifikaci hodnot parametr∙. Klientskß datovß mno╛ina p°edßvß tyto parametry na aplikaΦnφ server, kde jsou p°i°azeny k dotazu nebo ulo╛enΘ procedu°e pat°φcφ k poskytovateli.
Poznßmka: JmΘna parametr∙ se musφ shodovat se jmΘny odpovφdajφcφch parametr∙ komponent TQuery nebo TStoredProc na aplikaΦnφm serveru.
Omezovßnφ zßznam∙ parametry
Kdy╛ poskytovatel na aplikaΦnφm serveru reprezentuje v²sledek komponenty tabulky, pak m∙╛eme pou╛φt vlastnost Params k omezenφ zßznam∙, kterΘ jsou poskytnuty vlastnosti Data.
Ka╛dΘ jmΘno parametru se musφ shodovat se jmΘnem polo╛ky v komponent∞ TTable na aplikaΦnφm serveru. Komponenta poskytovatele na aplikaΦnφm serveru zasφlß pouze ty zßznamy, jejich╛ hodnoty na odpovφdajφcφch polo╛kßch se shodujφ s hodnotami p°i°azen²mi parametr∙m.
Nap°. p°edpoklßdejme klientskou aplikaci, kterß zobrazuje objednßvky jednoho zßkaznφka. Kdy╛ u╛ivatel identifikuje zßkaznφka, pak klientskß datovß mno╛ina zasφlß jeden parametr (nap°. jmΘna CustID) jeho╛ hodnota identifikuje zßkaznφka jeho╛ objednßvky chceme zobrazit. AplikaΦnφ server pak za╣le pouze ty zßznamy, kterΘ se t²kajφ po╛adovanΘho zßkaznφka. Je to mnohem efektivn∞j╣φ ne╛ zφskßnφ v╣ech zßznam∙ objednßvek od aplikaΦnφho serveru a filtrovßnφ zßznam∙ na stran∞ klienta.

Po╛adovßnφ dat z aplikaΦnφho serveru

Dv∞ vlastnosti a t°i metody TClientDataSet urΦujφ zp∙sob zφskßvßnφ dat z aplikaΦnφho serveru ve vφce vrstvov²ch aplikacφch:
 
Vlastnost nebo metoda V²znam
Vlastnost FetchOnDemand UrΦuje zda klientskß datovß mno╛ina automaticky zφskß pot°ebnß data nebo zde je bude muset zφskßvat funkcemi GetNextPacket, FetchBlobs a FetchDetails.
Vlastnost PacketRecords Specifikuje typ nebo poΦet zßznam∙ vracen²ch v ka╛dΘm paketu dat.
Metoda GetNextPacket Zφskßvß nßsledujφcφ paket dat z aplikaΦnφho serveru.
Metoda FetchBlobs Zφskßvß libovolnou polo╛ku BLOB pro souΦasn² zßznam, kdy╛ aplikaΦnφ server nedodßvß data BLOB automaticky.
Metoda FetchDetails Zφskßvß vno°enou datovou mno╛inu pro souΦasn² zßznam, kdy╛ aplikaΦnφ server je nezahrnuje do datov²ch paket∙ automaticky.

Implicitn∞ klientskß datovß mno╛ina zφskßvß v╣echny zßznamy z aplikaΦnφho serveru. Pomocφ PacketRecords a FetchOnDemand m∙╛eme °φdit jak data jsou zφskßvßna. PacketRocords specifikuje poΦet najednou zφskßvan²ch °ßdk∙ nebo typ vracen²ch zßznam∙. Implicitn∞ PacketRecords je nastaveno na -1, co╛ znamenß, ╛e v╣echny dostupnΘ zßznamy jsou zφskßny najednou a to kdy╛ aplikace je poprvΘ otev°e nebo aplikace explicitn∞ volß GetNextPacket. Kdy╛ PacketRecords je -1, pak po prvnφm zφskßnφ dat, klientskß datovß mno╛ina nikdy nezφskß dal╣φ data, proto╛e ji╛ mß v╣echna dostupnß data.
Pro zφskßvßnφ zßznam∙ po mal²ch dßvkßch, nastavφme PacketRecords na poΦet zφskßvan²ch zßznam∙. Nap°. nßsledujφcφ p°φkaz nastavuje velikost ka╛dΘho datovΘho paketu na 10 zßznam∙:
ClientDataSet1->PacketRecords = 10;
Tento proces zφskßvßnφ zßznam∙ v dßvkßch se naz²vß inkrementßlnφ zφskßvßnφ. KlientskΘ datovΘ mno╛iny pou╛φvajφ inkrementßlnφ zφskßvßnφ kdy╛ PacketRecords je v∞t╣φ ne╛ 0. Implicitn∞ klientskß datovß mno╛ina volß GetNextPacket k zφskßnφ dat podle pot°eby. Nov∞ zφskanΘ pakety jsou p°ipojeny na konec dat ji╛ existujφcφch v klientskΘ datovΘ mno╛in∞.
GetNextPacket vracφ poΦet zφskan²ch zßznam∙. Pokud vrßcenß hodnota je stejnß jako PacketRecords, pak je╣t∞ nebyl dosa╛en konec zßznam∙. Kdy╛ vrßcenß hodnota je v∞t╣φ ne╛ 0 a men╣φ ne╛ PacketRecords, pak b∞hen tΘto operace zφskßvßnφ byl zφskßn poslednφ zßznam. Kdy╛ GetNextPacket vracφ 0, pak ji╛ ╛ßdn² zßznam nebyl zφskßn.
PacketRecord m∙╛eme takΘ pou╛φt k zφskßnφ metadatov²ch informacφ o databßzi z aplikaΦnφho serveru. K zφskßnφ t∞chto informacφ nastavφme PacketRecords na 0.
AutomatickΘ zφskßvßnφ zßznam∙ je °φzeno vlastnostφ FetchOnDemand. Kdy╛ FetchOnDemand je true (implicitn∞), pak je povoleno automatickΘ zφskßvßnφ. K zabrßn∞nφ automatickΘmu zφskßvßnφ zßznam∙ podle pot°eby, nastavφme FetchOnDemand na false. P°i tomto nastavenφ, aplikace musφ explicitn∞ volat GetNextPacket k zφskßnφ zßznam∙.
Aplikace, kterΘ pot°ebujφ extrΘmn∞ velkΘ datovΘ mno╛iny urΦenΘ pouze pro Φtenφ, mohou vypnout FetchOnDamand k zaji╣t∞nφ, ╛e klientskß datovß mno╛ina nezavede vφce dat ne╛ se vejde do pam∞ti. Mezi zφskßvßnφm, klientskß datovß mno╛ina vyprßzdnφ svou vyrovnßvacφ pam∞╗ pomocφ metody EmptyDataSet. Toto ale nelze pou╛φt, kdy╛ klient musφ odesφlat aktualizace na aplikaΦnφ server.

Aplikovßnφ aktualizacφ do databßze

Pokud klientskß datovß mno╛ina je pou╛ita jako Φßst klientskΘ aplikace vice vrstvovΘ databßzovΘ aplikace, pak zm∞ny zaznamenanΘ klientskou datovou mno╛inou existujφ pouze na klientu, dokud nejsou aplikovßny na databßzi prost°ednictvφm aplikaΦnφho serveru. K aplikovßnφ zm∞n klientskΘ datovΘ mno╛iny do databßze, volßme metodu ApplyUpdates klientskΘ datovΘ mno╛iny. ApplyUpdates p°ebφrß zm∞ny z denφku zm∞n a zasφlß je jako datovΘ pakety na aplikaΦnφ server.
ApplyUpdates p°ebφrß jeden parametr, MaxErrors. MaxErrors je celΘ Φφslo indikujφcφ chybovou toleranci chrßnφcφ p°ed zru╣enφm procesu aktualizace. Pokud MaxErrors je 0, pak v╛dy p°i v²skytu chyby aktualizace na aplikaΦnφm serveru je cel² aktualizaΦnφ proces ukonΦen. «ßdnΘ zm∞ny nejsou zapsßny do databßze a denφk zm∞n klientskΘ datovΘ mno╛iny se nezm∞nφ. Pokud MaxErrors je -1, pak v╣echny chyby jsou tolerovßny a denφk zm∞n obsahuje v╣echny zßznamy, kterΘ nemohly b²t ·sp∞╣n∞ aplikovßny. Pokud MaxErrors je kladnß hodnota a vyskytne-li se vφce chyb ne╛ je tato hodnota, pak v╣echny zm∞ny jsou zru╣eny. Pokud se vyskytne mΘn∞ chyb ne╛ je MaxErrors, pak v╣echny ·sp∞╣n∞ aplikovanΘ zm∞ny jsou zru╣eny v denφku zm∞n klientskΘ datovΘ mno╛iny.
ApplyUpdates klientskΘ datovΘ mno╛iny volß funkci Reconcile k zßpisu aktualizacφ do databßze. Reconcile je funkce zpracovßvajφcφ chyby, kterß volß funkci ApplyUpdates komponenty poskytovatele na aplikaΦnφm serveru. Funkce ApplyUpdates komponenty poskytovatele zapφ╣e aktualizace do databßze a pokusφ se opravit p°φpadnΘ chyby. Zßznamy, kterΘ nemohly b²t aplikovßny z d∙vodu chyb, jsou zaslßny zp∞t metod∞ Reconcile klientskΘ datovΘ mno╛iny. Reconcile se pokusφ opravit p°φpadnΘ zb²vajφcφ chyby volßnφm obsluhy udßlosti OnReconcileError. Tuto obsluhu musφme vytvo°it k oprav∞ chyb.
Nakonec Reconcile odstra≥uje ·sp∞╣n∞ aplikovanΘ zm∞ny z denφku zm∞n a aktualizuje Data podle proveden²ch zm∞n. Po dokonΦenφ Reconcile, ApplyUpdates oznamuje poΦet zbyl²ch chyb.

Pou╛φvßnφ klientsk²ch datov²ch mno╛in bez poskytovatele dat

KlientskΘ datovΘ mno╛iny mohou fungovat nezßvisle na poskytovateli, jako jsou aplikace zalo╛enΘ na datech v ploch²ch souborech a aplikace pou╛φvajφcφ aktovkov² model. Zde nenφ poskytovatel a klientskß aplikace nem∙╛e zφskat definice tabulek a data ze serveru a na server nelze odesφlat aktualizace. Klientskß datovß mno╛ina zde musφ:

Vytvo°it novou datovou mno╛inu

Jsou t°i zp∙soby definovßnφ a vytvo°enφ klientskΘ datovΘ mno╛iny, kterß nezφskßvß data od komponenty poskytovatele:

Zavßd∞nφ dat ze souboru nebo proudu

K zavedenφ dat ze souboru volßme metodu LoadFromFile klientskΘ datovΘ mno╛iny. LoadFromFile p°ebφrß jeden parametr, °et∞zec specifikujφcφ soubor se Φten²mi daty. JmΘno souboru m∙╛e b²t pln∞ kvalifikovanΘ, pokud to je zapot°ebφ. Pokud v╛dy zavßdφme data klientskΘ datovΘ mno╛iny ze stejnΘho souboru, pak m∙╛eme pou╛φt vlastnost FileName. Pokud FileName obsahuje jmΘno existujφcφho souboru, pak data jsou automaticky zavedena, kdy╛ klientskß datovß mno╛ina je otev°ena.
K zavedenφ dat z proudu volßme metodu LoadFromStream klientskΘ datovΘ mno╛iny. LoadFromStream p°ebφrß jeden parametr a to objekt proudu p°edßvajφcφ data.
Data zavßd∞nß LoadFromFile nebo LoadFromStream musφ b²t d°φve ulo╛ena v datovΘm formßtu klientskΘ datovΘ mno╛iny touto nebo jinou klientskou datovou mno╛inou pomocφ metody SaveToFile nebo SaveToStream.
Kdy╛ volßme LoadFromFile nebo LoadFromStream, pak v╣echna data v souboru jsou p°eΦtena do vlastnosti Data. LibovolnΘ editace, kterΘ byly ulo╛eny v denφku zm∞n p°i ulo╛enφ dat jsou p°eΦteny do vlastnosti Delta.

SluΦovßnφ zm∞n a dat

Kdy╛ editujeme data v klientskΘ datovΘ mno╛in∞, pak provedenΘ zm∞ny jsou zaznamenßny do denφku zm∞n, ale zm∞ny neovliv≥ujφ p∙vodnφ verzi dat. K ud∞lßnφ na╣ich zm∞n trval²mi, volßme MergeChangeLog. MergeChangeLog p°epφ╣e zßznamy v Data zm∞n∞n²mi hodnotami polo╛ek z denφku zm∞n.
Po provedenφ MergeChangeLog, vlastnost Data obsahuje sm∞s existujφcφch dat a zm∞n z denφku zm∞n. Tato sm∞s tvo°φ zßklad pro dßle provßd∞nΘ zm∞ny. MergeChangeLog vyprßzdnφ denφk zm∞n a nastavφ ChangeCount na 0.
Varovßnφ: MergeChangeLog nesmφme volat pro klientskΘ aplikace, kterΘ jsou p°ipojeny na aplikaΦnφ server. V tomto p°φpad∞, volßme ApplyUpdates k zßpisu zm∞n do databßze.
Poznßmka: Je takΘ mo╛nΘ sluΦovat zm∞ny s daty v samostatnΘ klientskΘ datovΘ mno╛in∞, pokud tato mno╛ina p∙vodn∞ poskytla data do vlastnosti Data. K tomuto musφme pou╛φt poskytovatele a °e╣itele.

Uklßdßnφ dat do souboru nebo proudu

Pokud pou╛φvßme klientskou datovou mno╛inu v jedno vrstvovΘ aplikaci, pak editovanß data a provedenΘ zm∞ny existujφ pouze v pam∞ti. K trvalΘmu zßznamu zm∞n je musφme zapsat na disk. Data na disk m∙╛eme ulo╛it pomocφ metody SaveToFile.
SaveToFile p°ebφrß jeden parametr, °et∞zec specifikujφcφ soubor, do kterΘho budeme zapisovat data. JmΘno souboru m∙╛e b²t pln∞ kvalifikovanΘ, je-li to zapot°ebφ. Pokud soubor ji╛ existuje, pak jeho obsah je kompletn∞ p°epsßn.
Pokud v╛dy uklßdßme data do stejnΘho souboru, pak m∙╛eme pou╛φt vlastnost FileName. Kdy╛ FileName je nastaveno, pak data jsou automaticky ulo╛ena do uvedenΘho souboru p°i uzav°enφ klientskΘ datovΘ mno╛iny.
M∙╛eme takΘ uklßdat data do proudu pomocφ metody SaveToStream. SaveToStream p°ebφrß jeden parametr a to objekt proudu p°ijφmajφcφ data.
Poznßmka: Pokud uklßdßme klientskou datovou mno╛inu v dob∞ kdy nenφ slouΦena s denφkem zm∞n, pak data nejsou automaticky slouΦena, ale denφk zm∞n je ulo╛en takΘ. Kdy╛ data op∞t zavedeme, pak denφk zm∞n obsahuje neslouΦenΘ zm∞ny. Toto je d∙le╛itΘ pro aplikace kterΘ podporujφ aktovkov² model, kde tyto zm∞ny mohou b²t aplikovßny na komponentu poskytovatele na aplikaΦnφm serveru.
Poznßmka: SaveToFile nechrßnφ ╛ßdnΘ indexy p°idanΘ ke klientskΘ datovΘ mno╛in∞.
 
19. Vytvß°enφ a pou╛φvßnφ klientskΘ datovΘ mno╛iny