32
Molnár Roland Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven Bevezetés a Delphi-s adatbázis-kezelés rejtelmeibe

Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

  • Upload
    others

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

Molnár Roland

Adatbázis-kezelő rendszerek fejlesztése Delphinyelven

Bevezetés a Delphi-s adatbázis-kezelés rejtelmeibe

Page 2: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

1

Tartalomjegyzék

Bevezetés.....................................................................................................................................3A munkához kapcsolódó gyakorlati feladatok ....................................................................3

I.Az adatbázisokról ......................................................................................................................4Alapfogalmak, elvek ...........................................................................................................4

Adatbázis ....................................................................................................................4Adatbázis-kezelő rendszer ..........................................................................................4Adatmodellek alapelemei ...........................................................................................4

Az egyed..........................................................................................................4A rekordtípus...................................................................................................4A tulajdonság...................................................................................................4A kulcs.............................................................................................................4A kapcsolat ......................................................................................................5

Adatmodell .................................................................................................................5A normálformák .........................................................................................................5

Első normálforma (1NF) .................................................................................5Második normálforma (2NF)...........................................................................5Harmadik normálforma (3NF).........................................................................6Magasabb normálformák.................................................................................7

A lookup .....................................................................................................................7Törzsadattábla.............................................................................................................7SQL.............................................................................................................................7

Adatbázis-tervezés ..............................................................................................................7II.A Delphi adatbázis-kezelő rendszere .......................................................................................8

Alapok, BDE.......................................................................................................................8Alias létrehozása, szerkesztése ...................................................................................9Tábla létrehozása, szerkesztése...................................................................................9SQL lekérdezés készítése .........................................................................................10

Komponensek....................................................................................................................10III.A Delphi adatbázis-kezelő komponensei..............................................................................10

TDataSet, mindennek az alapja.........................................................................................10Data Access komponensek................................................................................................10

TDataSource.............................................................................................10

TTable ......................................................................................................10

TQuery .....................................................................................................11

TUpdateSQL ............................................................................................12

TBatchMove.............................................................................................12Data Controls komponensek .............................................................................................12

TDBGrid ..................................................................................................12

TDBNavigator..........................................................................................13

TDBText ..................................................................................................13

TDBEdit ...................................................................................................13

TDBMemo ...............................................................................................13

TDBImage................................................................................................13

TDBListBox.............................................................................................13

TDBComboBox .......................................................................................13

Page 3: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

2

TDBCheckBox.........................................................................................13

TDBRadioGroup ......................................................................................13

TDBLookupListBox.................................................................................13

TDBLookupComboBox ...........................................................................14

TDBRichEdit............................................................................................14

TDBCtrlGrid ............................................................................................14

TDBChart.................................................................................................14Nyelvi problémák..............................................................................................................14TDataModule ....................................................................................................................14

IV.Egy adatbázis-kezelő alkalmazás elkészítése .......................................................................15Tervezés ............................................................................................................................15A DataModule...................................................................................................................15Az ablakok ........................................................................................................................16

Ablaktípusok.............................................................................................................17A főképernyő ............................................................................................................18Táblamegjelenítő ablakok.........................................................................................18Adatlapok..................................................................................................................20Műveletvégző ablakok..............................................................................................21Kimutatások..............................................................................................................22Folyamatkijelzők (ProgressBar-ok) .........................................................................23Nyomtatás, riport ......................................................................................................23Project.......................................................................................................................24

V.Egyéb problémák ...................................................................................................................25Hibakezelés .......................................................................................................................25Hálózat használata Paradox rendszerrel ............................................................................26Biztonsági problémák........................................................................................................27

Biztonsági mentés.....................................................................................................27Adatsérülések kezelése .............................................................................................27

Telepítő készítése ..............................................................................................................28Készítsünk CD-t! ......................................................................................................30

VI.Lezárás .................................................................................................................................30Irodalomjegyzék ........................................................................................................................31

Page 4: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

3

Bevezetés

A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejlesztő rendszere. Elsősorban adatbázis-rendszerek készítésére szánják, de gyakorlatilag bármilyen szoftvert el lehet készíteni vele. Mivel mindig isérdekelt a programozás és a modern technológia, autodidakta módon foglalkozni kezdtem vele (a főiskolaitanórákon az 1992-es dátumú Turbo Pascal 7.0 volt a „legújabb” fejlesztőkörnyezet, amellyel találkoztam).Később már komolyabb alkalmazásokat is fejlesztettem Delphi-vel, így a számítástechnikának ez a területe lettaz, amivel a legtöbbet foglalkoztam. Rengeteg tapasztalatot gyűjtöttem, amelyet mindig is szerettem volnamegosztani olyanokkal, akiknek szükségük van rá. Ezért választottam ezt a témát dolgozati témának. Én személyszerint a Delphi-vel való ismerkedésem idején szívesen forgattam volna egy ilyen munkát, elkerülve ezzelrengeteg bosszúságot és kísérletezést. Ezt a témát választva remélem, hogy ez a munka másokhoz is eljut, éssegítő kezet nyújt mindazoknak, akik közelebbről is meg szeretnének ismerkedni a Delphi-vel.

Ez a dolgozat azoknak szól, akik most ismerkednek a Borland Delphi fejlesztőeszközzel, és szeretnékmegtenni az első lépéseket az adatbázis-kezelő rendszerek fejlesztése felé. Ez a dolgozat egy rövid, de lényegretörő kalauz, mely végigvezet a kezdetektől egészen a telepítő készítéséig minden nagyobb állomáson, amelyenegy adatbázis-kezelő szoftver fejlesztése során át kell haladni. Célja nem az, hogy megmutassa, hogyan kellfejleszteni, hanem az, hogy megmutassa, hogyan lehet elkezdeni. „Minden kezdet nehéz” – hangzik a kopottmondás. Ezen a nehéz kezdeten igyekszik átsegíteni olvasóját. Végigolvasva, követve a tanácsokat már bátranhozzákezdhet a Kedves Olvasó a fejlesztéshez. Ne várjon azonban teljes körű leírást vagy magyarázatot, hiszenmindenről részletes információ található a Delphi súgójában (Help), és én nem azt kívántam magyarítani. Sokkalinkább egy átfogó segítséget szeretnék nyújtani, mindenhol utalva a Delphi Help-re.

Ahhoz, hogy e munka tanulmányozása eredményes legyen, a következő dolgok szükségesek:- Idő, hiszen ez nem megy egyik pillanatról a másikra.- Kísérletező kedv, mert programozni tanulni csak úgy lehet, ha kísérletezgetünk.- Angoltudás, mivel a Delphi és a hozzá tartozó súgó angol nyelvű, így a helyes használat érdekében legalább

minimális angoltudással és egy jó szótárral kell rendelkezni.- Számítógép és egy telepített Delphi 3, 4 vagy 5

A dolgozat írásakor Delphi 5-öt használtam, így előfordulhat, hogy a többi verzióban egy-két dologmáshogy és máshol van, de a lényeg mindegyiknél megegyezik.

A dolgozat felépítését tekintve az elmélettől halad a gyakorlat felé. Először adatbázis-kezelésialapfogalmakat ismertet, majd a Borland adatbázis-kezelésének elvi működését magyarázza, azután pedig rátéraz adatbázis-kezelő rendszerek fejlesztésének lépéseire. Végül különböző gyakorlati problémák megoldásáranyújt hasznos tanácsokat.

A dolgozatban sokat fogok hivatkozni a Delphi súgójára, a következőképpen: (Delphi Help: Témakör).Az itt megadott témakört beírva a Tárgymutató ablak kereső sorába, megtaláljuk az oda vonatkozó bővebbleírást. Az irodalomjegyzékben szereplő irodalmakra a következőképpen utalok: [jegyzékszám/oldalszám] (pl.:[2/213] = Szelezsán János Adatbázisok c. könyvének 213. oldala).

A munkához kapcsolódó gyakorlati feladatokJelen munka készítése előtt már volt szerencsém adatbázis-kezelő alkalmazásokat fejleszteni, így kellő

tapasztalatot szereztem a Delphi-s Paradox rendszerek működtetéséről, programozásáról. A dolgozatomban ezenmunkákról készült képernyőképek (és egy-két helyen ezekből kimásolt kódrészletek) találhatóak. Ezek a munkákazonban nem kapcsolódnak konkrétan a dolgozat tárgyához, hiszen általánosságban beszélek a feladatokról.Nem láttam tehát sok értelmét annak, hogy ezekkel bővebben foglalkozzak. A pontosság kedvéért azértszeretném közölni, milyen munkák ezek.

Az egyik feladat egy helyi rádió reklámadminisztrációjának számítógépesítése volt. Az adatbázisrendkívül egyszerű, mindössze három fő- és négy altáblából áll. A három főtábla közül az egyik a reklámokadatait tárolja (felvétel időpontja, hirdetőpartner, hirdetésszervező, futás kezdete, vége, darabszám, fizetésdátuma, módja, a reklám szövege, típusa, stb.). A második táblában a hirdetőpartnerek, a harmadikban ahirdetésszervezők adatai vannak (név, cím, telefonszám, stb.). A négy altábla közül egy a reklámtípusokat, egy afizetésmódokat, egy a felhasználókat, egy pedig a felhasználói típusokat tárolja. A táblák között egyszerű 1:Nrelációk vannak.

Page 5: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

4

A másik feladat ennél lényegesen bonyolultabb: egy étterem rendelés-, számla-, és raktárnyilvántartásátkellett megoldani. A rendszer két részből áll: az éttermi program a rendelésekkel és a számlákkal foglalkozik, araktár program pedig a raktárkészlettel, és az éttermi program által regisztrált rendelések alapján (a sajátösszetevő-adatbázist használva) a raktári tételek mennyiségének automatikus aktualizálásával. A rendszer kétadatbázist (étterem és raktár), és összesen 29 Paradox táblát tartalmaz. Az éttermi program az általa tárolthatalmas adatmennyiség (rendelések és számlák) ellenére megfelelő sebességgel dolgozza fel az adatokat,köszönhetően annak, hogy a rendelések és számlák adatait két-két táblában is tárolja. Egyikben az aktuálisakat, amásikban a régebbieket, melyekkel a program csak zárás esetén foglalkozik. Érdekes feladat volt még aszámlanyomtatók kezelése, melyet úgy oldottam meg, hogy meghajtóprogram (driver) nélkül működjön.

Mindkét szoftver lehetővé teszi a hálózati használatot, mely igazán az étterem programnál volt nagykihívás, hiszen nagyobb forgalom idején egyszerre több számítógépen veszik föl a rendeléseket és adják ki aszámlákat, így rendkívül sűrű és nagy az adatmozgás.

Az említett munkák készítése alatt szerzett tapasztalataim próbálom átadni ezen dolgozat keretein belül.

I. Az adatbázisokról

Alapfogalmak, elvekEbben a részben az adatbázisokkal kapcsolatos általános fogalmakkal ismerkedünk meg.

AdatbázisAmikor az ember adatbázis-kezelő szoftverrel dolgozik, hajlamos azt hinni, hogy minden, amit azzal

végez, az adatbázis és adatbázis-kezelés. Ez azért van, mert nagyon sokan nincsenek tisztában az adatbázisfogalmával. Néhány adatfájl még önmagában nem adatbázis, csupán adattáblák halmaza. Ahhoz, hogyadatbázissá váljon, a táblák közötti kapcsolatokat is definiálni kell.

Gondoljunk például arra, hogy van két táblánk, az egyikben nevek, a másikban címek. Mindkettőnekvan egy kód nevű mezője is. Ez a leírás önmagában még nem egy adatbázist határoz meg, csupán két, egymástólfüggetlen adattáblát írtunk le. A dolog akkor válik adatbázissá, ha kikötjük a következőt: a neveket és a címekettartalmazó táblában lévő kód összekapcsolja a két táblát úgy, hogy egy, a neveket tároló táblában lévő névhez azazonos kódú, a címeket tároló táblában lévő cím tartozik. Ezzel definiáltuk az adatkapcsolatot.

Az adatbázison tehát voltaképpen adatoknak kapcsolataikkal együtt való ábrázolását, tárolásátértjük. [2/13]

Adatbázis-kezelő rendszerAz adatbázis önmagában semmit nem ér. A felhasználó számára akkor válik értékké, ha megadunk

hozzá egy olyan szoftvert, amellyel az adatbázist kezelni tudja. Az ilyen szoftvert adatbázis-kezelő rendszerneknevezzük. Az adatbázis-kezelő rendszereknek két fő funkciója van: az adatdefiníció (az adatbázis szerkezeténekdefiniálása, a szerkezet feltöltése konkrét adatokkal, illetve ezek módosítása, törlése), valamint a lekérdezés(adatok visszakeresése, kimutatások készítése). [2/21]

Adatmodellek alapelemei

Az egyed„Egyednek hívunk minden olyan dolgot (objektumot), ami minden más dologtól (objektumtól)megkülönböztethető, és amiről adatokat tárolunk.” [2/33]

A rekordtípus„Az adatbázis-kezelő rendszerekben (…) az egyedtípust rekordtípusnak hívjuk. Ez a legkisebbcímezhető egység (ennél kisebb részeire nem lehet hivatkozni az adatbázisnak).” [2/34]

A tulajdonság„Az egyedeket tulajdonságokkal (attribútumokkal) írjuk le. A tulajdonság az egyed egy jellemzője, amimegadja, meghatározza az egyed egy részletét.” [2/35] A tulajdonság és az attribútum azonos jelentésűfogalmak, és a továbbiakban felváltva használjuk őket.

A kulcs

Page 6: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

5

„Amennyiben egy tulajdonság vagy tulajdonságok egy csoportja egyértelműen meghatározza, hogy egyegyed melyik értékéről, előfordulásáról van szó (vagyis az egyedhalmaz melyik eleméről), akkor ezeketa tulajdonságokat együtt kulcsnak nevezzük” [2/36]

A kapcsolat„Kapcsolatnak nevezzük az egyedek közötti viszonyt.” [2/38] A kapcsolat fajtái:Egy-egy típusú kapcsolat (1:1 kapcsolat): olyan kapcsolat, ahol „az egyik egyedhalmaz mindegyikeleméhez a másik egyedhalmaznak pontosan egy eleme kapcsolódik (tehát a két egyedhalmazegymásba kölcsönösen egyértelműen képezhető le).” [2/40]Egy-több típusú kapcsolat (1:N kapcsolat): „Azt mondjuk, hogy az A egyed és a B egyed között egy-több (1:N) kapcsolat van, ha az A egyedhalmaz mindegyik eleméhez a B egyedhalmaz több eleme istartozhat.” [2/40]Több-több típusú kapcsolat (N:M kapcsolat): „Több-több (jelben N:M) típusú kapcsolatnaknevezzük az A egyed és a B egyed közötti kapcsolatot, ha az A egyedhalmaz minden eleméhez a Begyedhalmaz több eleme tartozhat, és fordítva egy B-beli elemhez is több A-beli elemet rendelhetünkhozzá.”[2/41]

AdatmodellEzek után már definiálhatjuk, mi is az adatmodell: „Az adatmodell egyedek, tulajdonságok és

kapcsolatok halmaza, amely absztrakt módon tükrözi a valós objektumoknak, azok jellemzőinek(tulajdonságainak) és viszonyainak (kapcsolatainak) elvont kategóriáit.” [2/48]

A normálformákAz adatbázisok belső szerkezetét ún. normálformák jellemzik. Ha egy adatbázis eleget tesz bizonyos

feltételeknek, akkor azt mondjuk, hogy egy adott normálformában van.

Első normálforma (1NF)„Egy R relációról azt mondjuk, hogy első normálformában van, ha minden sorában pontosan egyattribútumérték áll.” [2/87]Ez első hallásra lehet, hogy bonyolultnak hangzik, annál is inkább, hogy az adatbázis-kezelők csakolyan adatbázist fogadnak el, amely 1NF-ben van.Egy példával lehet a legjobban érzékeltetni, mit is jelent ez valójában:

NÉV SZAKKÉPZETTSÉGNagy Géza gépészmérnök, közgazdász, műszerészKiss János lakatosBíró Ödön fodrász, lakatos

A fenti táblázat nincs 1NF-ben, mert a SZAKKÉPZETTSÉG mezőben néhol több érték is szerepelhet.Ezt úgy is lehetne ábrázolni, hogy minden egyes szakképzettséget külön sorba teszünk:

NÉV SZAKKÉPZETTSÉGNagy Géza gépészmérnök

közgazdászműszerész

Kiss János lakatosBíró Ödön fodrász

lakatos

Amennyiben ezt első normálformára szeretnénk hozni, a legegyszerűbb, ha a több attribútumértékettartalmazó sort annyi sorra bontjuk, amennyi az attribútumértékek száma:

NÉV SZAKKÉPZETTSÉGNagy Géza gépészmérnökNagy Géza közgazdászNagy Géza műszerészKiss János lakatosBíró Ödön fodrászBíró Ödön lakatos

Így a táblázat már 1NF-ben van.

Második normálforma (2NF)

Page 7: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

6

Egy reláció akkor van második normálformában, ha első normálformában van, és minden nem-kulcstulajdonsága teljesen függ a kulcstól. [2/93]Nézzük pl. a következő, az előzőnél kissé bonyolultabb, 1NF-ben lévő táblát, ahol számlák adataittároljuk. A SZSZ a számlaszám, a TKOD a tételkód, a TNÉV a tételnév, az EÁR az egységár rövidítése.

ELADÁSSZSZ DÁTUM VEVŐ VEVŐCÍM TKOD TNÉV DB EÁR ÁR234 2000.02.11. XYZ Kft Bp. Nagy út 10. 142 Kifli 5 20 100234 2000.02.11. XYZ Kft Bp. Nagy út 10. 264 Tej 3 40 120235 2000.02.20. UVT Kft Ózd, Híd út 3. 245 Kakaó 6 10 60235 2000.02.20. UVT Kft Ózd, Híd út 3. 142 Kifli 4 20 80

A kulcsot a számlaszám (SZSZ) és a tételkód (TKOD) alkotják, hiszen ketten együtt egyértelműenmeghatároznak egy rekordot (ezeket dőlt betűvel jelöljük). A táblázat nincs 2NF-ben, mert vannakbenne olyan másodlagos attribútumok, amelyek nem az egész kulcstól, csak az azt alkotó egyesattribútumoktól függnek.A DÁTUM függ az SZSZ-től, mert egy számlához egyazon dátum tartozik. Ez igaz a VEVŐ-re, és aVEVŐCÍM-re is. Hasonlóképpen belátható, hogy a TKOD is rendelkezik azzal a tulajdonsággal, hogytöbb másodlagos attribútumot egyedül is meghatároz (TNÉV, EÁR).A 2NF-re hozás egyszerű művelet: a relációt több, 2NF-ben lévő táblázatra bontjuk. A mi esetünkben ezkét táblát (ELADÁS1 és TÉTELEK) fog eredményezni, és azoknak a kulcsai az ELADÁS táblánkkulcsának két attribútuma lesz:

ELADÁS1SZSZ DÁTUM VEVŐ VEVŐCÍM TKOD DB ÁR234 2000.02.11. XYZ Kft Bp. Nagy út 10. 142 5 100234 2000.02.11. XYZ Kft Bp. Nagy út 10. 264 3 120235 2000.02.20. UVT Kft Ózd, Híd út 3. 245 6 60235 2000.02.20. UVT Kft Ózd, Híd út 3. 142 4 80

TÉTELEKTKOD TNÉV EÁR142 Kifli 20264 Tej 40245 Kakaó 10

A két tábla közötti kapcsolatot a TKOD valósítja meg. Ezzel a relációt második normálformára hoztuk.

Harmadik normálforma (3NF)Egy reláció harmadik normálformában van, ha második normálformában van és egyetlen másodlagosattribútuma sem függ tranzitívan a kulcstól. [2/100]Egy C tulajdonság akkor függ tranzitívan az A kulcstól, ha meghatározza a kulcstól szintén függő Btulajdonság is. [3/224]Vegyük alapul az előbbi ELADÁS1, 2NF-ben lévő táblát. A SZSZ meghatározza a VEVŐ attribútumot,az pedig meghatározza a VEVŐCÍM-et. Ez azt jelenti, hogy a VEVŐCÍM tranzitívan függ a SZSZkulcstól, mivel azt meghatározza a nem kulcs VEVŐ tulajdonság is. A tábla tehát nincs 3NF-ben.Ahhoz, hogy 3NF-ben legyen, ugyanazt a műveletet kell elvégezni, mit az imént: föl kell bontanunk atáblát. Itt azonban fel kell ismerni egy másodlagos kulcsot is: VEVŐ. Ez lesz a két új tábla közöttikapcsolat.

ELADÁS2SZSZ DÁTUM VEVŐ TKOD DB ÁR234 2000.02.11. XYZ Kft 142 5 100234 2000.02.11. XYZ Kft 264 3 120235 2000.02.20. UVT Kft 245 6 60235 2000.02.20. UVT Kft 142 4 80

VEVŐKVEVŐ VEVŐCÍMXYZ Kft Bp. Nagy út 10.UVT Kft Ózd, Híd út 3.

Page 8: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

7

Így kiküszöböltük a tranzitív függősséget, a reláció 3NF-ben van. Természetesen a modellhez tartozikmég a TÉTELEK tábla is, de azt az előző példához képest változatlanul hagyjuk, hiszen az megfelel a3NF feltételeinek is.

Magasabb normálformákA harmadik normálforma a minimum, amit egy adatbázis tervezésnél be kell tartani. Ne gondoljuktehát, hogy ez a normalizálás csúcsa. Léteznek magasabb szintű normálformák is (BCNF, 4. és 5. NF),ezek tárgyalása azonban kimerítené ezen dolgozat kereteit, ezért nem foglalkozunk velük.

A lookupEzzel a szóval sokat fogunk még találkozni a dolgozat folyamán. Angolul keresést, utánanézést jelent.Az adatbázis-kezelőkben a táblák közötti kapcsolat megvalósítására használják. Segítségével az iméntipéldáinkban szereplő ELADÁS1 és TÉTELEK táblát összekapcsolhatjuk úgy, hogy a megjelenítettvégeredmény egy ELADÁS-hoz hasonló táblázat lesz, ahol a TNÉV és az EÁR ún. lookup mezők,amelyek valójában nincsenek a táblázatban, csupán az adatbázis-kezelő helyezi oda őket, az általunkdefiniált kapcsolat alapján. Ez a kapcsolat a következőképpen néz ki: ELADÁS1.TKOD <==>TÉTELEK.TKÓD. Így a program a TKÓD alapján a TÉTELEK táblából gyakorlatilag „behúzza” azadatokat az ELADÁS1 táblába.Ezzel azonban korántsem merülnek ki a lookup által nyújtott lehetőségek. Táblázatunkban ugyanis nemmuszáj megjeleníteni a TKÓD mezőt, így a felhasználó azt látja, hogy ha felvesz egy új számlát, aVEVŐ mezőnek ad értéket, holott valójában a TKÓD-ot manipulálja. Ezt azonban a rendszer ügyesenelrejti előle.Hasonlóképpen állíthatunk lookup kapcsolatot az ELADÁS2 és a VEVŐK táblázatok között is, a VEVŐmező alapján.Így az ELADÁS2, a VEVŐK és a TÉTELEK (3NF-ben lévő) táblák használatával megjeleníthetjük úgyaz adatbázist, hogy az ELADÁS (csupán 1NF-ben lévő) táblát lássuk. Így nem veszítjük el anormalizálás által biztosított előnyöket, a felhasználó viszont egy helyen lát mindent, így neki nem kelltudnia, mi is az a normalizálás.

TörzsadattáblaA normalizálás folyamán keletkeznek olyan táblák, amelyek a többihez képest viszonylag állandónak

mondhatók (példánkban ilyen a TÉTELEK, ill. a VEVŐK tábla). Ezeket a táblák mindig valamilyen főbb táblávalvannak kapcsolatban (itt: ELADÁS1, ill. ELADÁS2). Az ilyen táblákat törzsadattábláknak nevezzük. Atörzsadattáblák (értelemszerűen) törzsadatokat tartalmaznak. A törzsadatok manipulációját általában a programkarbantartó egységében vagy automatikusan szokták megoldani.

SQLAz SQL (Structured Query Language = Strukturált lekérdező nyelv) egy szabványosított (ISO 9075)

adatbázis-kezelő nyelv. Alapvetően két része van: adatdefiníciós nyelv (DDL, Data Definition Language) ésadatmanipuláló nyelv (DML, Data Manipulation Language). A DDL segítségével táblákat hozhatunk létre,törölhetünk, stb., míg a DML-lel beszúrhatunk, szerkeszthetünk, törölhetünk, illetve lekérdezhetünk adatokat egyvagy több táblából.

A Delphi természetesen támogatja az SQL-t. Komponensein keresztül könnyen építhetünk bealkalmazásunkba SQL-utasításokat. Mivel ebben a munkában a Paradox rendszerekről van elsősorban szó, azSQL-t bővebben nem tárgyaljuk.

Adatbázis-tervezésAz előző részben megtudhattuk, hogyan kell az adatbázist egyszerűsíteni, normalizálni. A szabály tehát

az, hogy úgy kell megtervezni az adatbázist, hogy az legalább a harmadik normálforma követelményeinek elegettegyen. A gyakorlatban azonban ez nem mindig működik.

Az általam készített éttermi alkalmazásban található például olyan eset, amikor a rendelés fejlécét és atörzsét tartalmazó táblákban egyaránt szerepel az asztal kódja, holott elég lenne csupán a fejlécben tárolni, hiszenegy rendelés tételeihez csupán egy asztalkód tartozhat. Azért volt szükség ennek ellenére erre a megoldásra, merta számlázásnál asztalok szerint kell szűrni (mindig csak egy asztalhoz tartozó rendeléseket kell megjeleníteni), ésjelentősen felgyorsította a működést az eredeti tervben nem szereplő asztalkód mező a rendelések törzsét tárolótáblában. A másik eset, amikor hasonló problémával találkoztam, a számlák rész- és végösszegének tárolása volt.Kénytelen voltam ugyanis eltárolni a bruttó árát is a számla tételeinek, illetve a számla bruttó végösszegét, pedigezeket egyértelműen meg lehet határozni, mivel az adatbázis tartalmazza a tételek nettó árait és ÁFA-kulcsait, dekiszámításuk jelentősen lassította volna a működést. Mondhatnánk azt is, hogy a nettó árat sem kellene tárolni,hiszen azt is egyértelműen meghatározhatjuk, de gondolni kellett arra, mi történik, ha valaminek megváltozik azára. Ekkor ugyanis az eredeti modell szerint (amelyben még nem tároltam a számlák összegeit) a régebben

Page 9: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

8

kiadott számlák összege is megváltozott, így hamis adatokat kaptunk. A végleges megoldással már nemjelentkezhet ez a probléma, hiszen a számla a kiadásának időpontjában aktuális árakat tartalmazza.

Egy szó, mint száz, nem lehet agyon optimalizálni az adatbázist. Megfogalmazhatjuk tehát az adatbázis-tervezés egyik legfontosabb titkát (amelyben Halassy Béla könyve is megerősített): „Sohasem szabad azadatszerkezetet egyszerűsíteni a programbonyolultság rovására.” [3/207]

Azt természetesen mondani sem kell, hogy az adatbázis-tervezés két fontos szabálya: mindennek bennekell lennie, amire szükség van, és semminek nem szabad benne lennie, amire nincs szükség. Hogy ismét HalassyBéla szavait idézzem: „Az a jó adatféle, ami nincs.” [3/155]. Mert ami nincs, azzal nem kell foglalkozni, nemfoglal helyet, nem vesz igénybe processzoridőt, és nem kell fáradozni vele. Tehát fölösleges adatokatsemmiképpen ne tároljunk. Ami viszont kell, az kell. Ezek a kijelentések lehet, hogy triviálisnak hangzanak, defontosnak tartom leszögezni őket, mert sokszor nem tartjuk be ezeket, és későn ébredünk rá, hogy hibáztunk.

Az adatbázis-tervezés bonyolult dolog. Rengeteget lehet hibázni, de a leggyakoribb hiba, ha nemismerjük eléggé a működési mechanizmusokat, azaz nem tudjuk, mire lesz szükség. Ezért nagyon fontos, hogyelőtte tájékozódjunk, és a feladatot nagyon pontosan határozzuk meg. Ha megkérnek, hogy készítsünk egybizonyos alkalmazást, ne elégedjünk meg ennyivel, kérdezzük meg, hogyan kell működnie. Ezzel rengetegvesződséget megspórolhatunk. Elmondható tehát az is, hogy az adatbázis-tervezés (de igaz ez aprogramtervezésre is) másik legfontosabb szabálya a minél pontosabb feladat-meghatározás.

II. A Delphi adatbázis-kezelő rendszere

Eddig az adatbázisokról általánosságban beszéltünk. Most áttérünk igazi témánkra, a Delphi-srendszerek fejlesztésére. Ehhez ismernünk kell a Delphi adatbázis-kezelő rendszerének működési alapjait.

Alapok, BDEA BDE a Borland Database Engine rövidítése, amely egy Windows alapú 32 bites adatbázis-motor.

Feladata, hogy kapcsolatot teremtsen a fizikai adatbázis és az azt kezelő alkalmazások között, és ezzelmegkönnyítse a Borland fejlesztőrendszereit használó programozók munkáját. Leveszi vállunkról atáblaformátumok kezelését, és alapvető adatbázis-kezelő rutinokat tartalmaz. A BDE a következő adatbázisokattámogatja: dBASE, Paradox, Text, FoxPro, Access, InterBase, Oracle, Sybase, Microsoft SQL, ODBC(Microsoft Open Database Connectivity). A programozó ezek közül szabadon választhat, anélkül, hogymódosítaná programját. Minden formátumnak saját, független meghajtója (drivere) van. Ezeken kívül azonbanvannak megosztott szolgáltatások is, amelyeket minden driver használhat. Ilyen pl. a Buffer Manager (bufferkezelő), a Sort Engine (rendező motor), stb.

A Delphi adatbázis-kezelése teljes mértékben a BDE motorra épül, a Delphi minden DB komponenseezt használja az adatok közvetlen vagy közvetett eléréséhez. A komponensek a BDE API (Application ProgramInterface) függvényeken keresztül működtetik a Database Engine-t. A BDE függvényei objektum-orientáltanépülnek fel, így azok elérése egyszerű és strukturált.

A Database Engine főbb részei a következők:- BDE mag (BDE core): a rendszer magját képező .DLL fájlok tartoznak ide.- BDE API függvények: alapvető adatbázis-műveleteket tartalmazó függvénytár, mely tartalmaz adatbázis

kezelésre, konfigurálásra, hibakezelésre, lekérdezésre, tranzakciókra használható függvényeket.- Adatbázis meghajtók (Database Drivers): ide tartozik az öt standard meghajtó (Paradox, dBASE, FoxPro,

Access, és Text).- Opcionális meghajtók (Optional Drivers): egyéb meghajtókat tartalmaz (InterBase, DB2, Informix, Oracle,

Sybase, Microsoft SQL Server).- Query motorok (Query Engines): az SQL (Structured Query Language – Strukturált lekérdező nyelv)

motorok.- BDE Administrator: a BDE beállításait végző program (BDEADMIN.EXE).- Database Desktop: adatbázis fájlok kezelését végző segédprogram, mellyel egyszerűen hozhatunk létre,

tölthetünk ki, vagy módosíthatunk különféle formátumú táblákat. Ezen kívül SQL lekérdezéseket iskészíthetünk segítségével.

A BDE fontos szolgáltatása még az ún. alias-ok kezelése. Az alias-ok segítségével elnevezhetjükadatbázisunkat, hogy később ezen a néven hivatkozzunk rá, annak fizikai helyétől függetlenül. Standardadatbázisoknál az alias gyakorlatilag egy egyszerű mutató, ami egy adott könyvtárra mutat. SQL adatbázisoknálviszont már egyéb információkat is tartalmaz (felhasználónév, jelszó, stb.).

A BDE-nek rengeteg beállítási lehetősége van, és általában az alapértelmezett beállítások nem felelnekmeg az igényeinknek. Telepítéskor ezért mindig célszerű végignézni ezeket a beállításokat. Ezt a BDEAdministrator (DBEADMIN.EXE) programmal tehetjük meg. A beállítások közül megemlítünk néhány

Page 10: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

9

fontosabbat. Ilyen pl. a Langdriver, amivel a nyelvet állíthatjuk be. Ilyet minden egyes driver beállításai közötttalálunk, mivel a driverekhez egyenként adhatjuk meg, milyen nyelvvel dolgozzanak. Ez a változóalapértelmezetten 'ascii' ANSI értékre van állítva. Ha magyar, ékezetes szövegeket is tárolunk azadatbázisunkban, célszerű ezt HUN 852 DC értékre állítani. Mivel mi elsősorban a paradox rendszerekkelfoglalkozunk, ezért a Paradox driver beállításait nézzük meg. Itt a Langdriver változónak a Paradox HUN 852DC értéket kell adni.

Ha hálózaton keresztül használunk paradox táblákat, két dologra kell odafigyelnünk. Az egyik a NetDir. Ez a paradox hálózati kontroll fájl (PDOXUSRS.NET) helyét határozza meg. Ez a fájl hangolja össze atáblákat hálózaton keresztül elérő programokat. Fontos, hogy ha több számítógépről használunk hálózatonkeresztül egy adatbázist, ezt a változót minden számítógépen be kell állítani úgy, hogy az ugyanoda mutasson.Célszerű az adatbázist tároló számítógép egyik könyvtárát megadni. Csak akkor tudjuk egyszerre többszámítógépről használni az adatbázisunkat, ha ezt a változót helyesen állítjuk be. A változónak mindigvalamelyik meghajtó, vagy megosztott könyvtár gyökerére kell mutatnia.

Másik fontos beállítás hálózati használat esetén a Local Share. Ezt a System/INIT beállítások közötttaláljuk. Ha egyszerre több programból szeretnénk elérni egy adatbázist, ezt igazra (TRUE) kell állítani. Ha eztnem tesszük meg, az adatbázist a hálózaton keresztül elérő programok nem tudják frissíteni az adatbázispillanatnyi változásait.

Alias létrehozása, szerkesztéseHa létrehozunk egy adatbázist, első dolgunk, hogy létrehozunk számára egy alias-t. Ezt többféleképpen

is megtehetjük: használhatjuk erre a BDE Administrator-t, a Database Desktop-ot, és az SQL Explorer-t is. Én azelsőt ajánlom, mert kezelése egyszerűbb: az Object/New menüpontot kiválasztva meg kell adni az adatbázistípusát (mi Standard adatbázisokkal foglalkozunk), majd be kell írni az alias nevét, és ki kell tölteni a jobboldalon a Path mezőt. Ezzel kész is az alias. Ha az SQL Explorer-t használjuk, az eljárás ugyanez. A DatabaseDesktop esetében már másként kell eljárni: Tools/Alias Manager menüpont, az ablakon New gomb, megadjuk anevet és utat, majd a Keep New gombra kattintva elmentjük.

Ha ezek után ezzel az alias-szal szeretnénk dolgozni, egy valamit még érdemes megtenni: beállítani aDatabase Desktop munkakönyvtárának ezt az alias-t (File/Working Directory). Ez azért célszerű, mert aDatabase Desktop mindig a munkakönyvtárát nyitja meg, ha a megnyitó vagy a mentő ablakot használjuk.

Tábla létrehozása, szerkesztéseEzeket a műveleteket a Database Desktop-pal tudjuk elvégezni. Kattintsunk a File/New/Table…

menüpontra. Válasszuk ki a tábla típusát. Mivel ebben a munkában Paradox rendszerekkel foglalkozunk,válasszuk a Paradox 7-et. A táblázat kitöltése nem bonyolult, viszont jobb oldalon találunk néhány opciót (alenyíló listából választhatjuk ki őket).

A Validity Checks segítségével a kijelölt mező értékére vonatkozó beállításokat tehetjük meg. Ezekértelemszerűen kitöltendők. Figyeljünk arra, hogy melyik mezőkre használjuk, illetve nem használjuk a RequiredField opciót. Ha ez be van kapcsolva, a táblázatba nem lehet elmenteni rekordokat úgy, hogy ez a mező nincskitöltve. Ez akkor hasznos, ha a mezőre mindenképp szükség van. Ha ugyanis elfelejtjük a programban kitölteni,azonnal hibaüzenetet kapunk. Az esetleges lefagyások miatti üresen való elmentést is megakadályozhatjuk enneksegítségével.

A Secondary Indexes segítségével manipulálhatjuk a másodlagos indexeket. Jó tudni, hogy akkorműködik rendesen egy index, ha tulajdonságaiban be van jelölve a Maintained jelölőnégyzet. Ezt viszont csakakkor tudjuk bejelölni, ha van legalább egy elsődleges indexünk (a mező-táblázatban a Key oszlopban csillaglátható). A Maintained opció egyébként arra vonatkozik, hogy a BDE automatikusan frissítse-e a másodlagosindexeket. Ha ez nincs bejelölve, manuálisan kell megoldanunk az újraindexelést.

Ha valamilyen adatbázis-rendszert készítünk, előfordulhat, hogy ügyelnünk kell a biztonságra. Ezértajánlatos az adatbázis tábláit jelszóval védeni. Egy adatbázison belül célszerű ugyanazt a jelszót használni. Ezt ajelszót nem szükséges a felhasználóknak tudni, mivel beépíthetjük a programunkba. Így csak azok a programoktudnak hozzáférni az adatbázishoz, amelyek ismerik ezt a jelszót. Az egyéb biztonsági intézkedéseket(felhasználók kezelése, azok eltérő jogai, stb.) már a programunkon belül intézhetjük. A Paradox tábláklehetőséget nyújtanak arra is, hogy több jelszót adjunk meg, és azokhoz különböző jogokat rendeljünk (AuxilaryPassword). Ezt akkor érdemes csak használni, ha több program is hozzáférhet egy adatbázishoz, de mindegyikükmás-más jogosultságokkal. Ezt a problémát így a legegyszerűbb lekezelni.

Mint azt az imént említettem, fontos az is, hogy milyen nyelvű a tábla. Ezt táblánként megadhatjuk(Table Language). A Database Desktop először mindig az alapértelmezett nyelvet állítja be a táblának (ezt aBDE Administrator-ban definiálhatjuk, lásd föntebb), de meg is változtathatjuk kedvünk szerint.

Ha már mindent beállítottunk, a Save As gombbal menthetjük a táblát.

Page 11: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

10

SQL lekérdezés készítéseSQL lekérdezést a legegyszerűbben a Database Desktop-pal készíthetünk (File/New/SQL file). Ezt

szerkeszthetjük, menthetjük, futtathatjuk. Ha egy Delphi programba szeretnénk SQL-t építeni, a lekérdezéstmindig célszerű itt megírni és kipróbálni (az SQL-ről bővebben: Program files\Common files\BorlandShared\BDE\localsql.hlp).

KomponensekA Delphi-ben az adatbázis-kezelést komponenseken keresztül valósíthatjuk meg. A komponenseket

mozaikként egymáshoz illesztve alakítjuk ki a programunk szerkezetét. A komponensek biztosítják aprogramozó és a BDE közötti kapcsolatot. Alapvető műveleteket tartalmaznak, melyek felhasználásával könnyenvalósíthatjuk meg elképzeléseinket. Komponensek nélkül szinte elképzelhetetlen a munka, használatukkal nemkell törődnünk a kezelt adatbázis típusával, formátumával, lényegesen emberközelibb programozást biztosítanak.

III. A Delphi adatbázis-kezelő komponensei

A Delphi adatbázis-kezelő komponensei közül azokat a standard komponenseket vesszük sorra,amelyek a native táblák kezeléséhez szükségesek. Ezeket a standard komponenseket két részre osztva találjukmeg a Delphi eszköztárán: Data Access (adathozzáférés), és Data Controls (adatkontroll, adatvezérlés). Akomponensek leírásában nem a teljességre törekszem, hanem a lényegesebb dolgok kiemelésére. Bővebbeketezekről a Delphi Help-ben olvashatunk.

TDataSet, mindennek az alapjaA TDataSet osztály minden olyan komponens alap osztálya, amely sorokban és oszlopokban megjelenő

adatot reprezentál. Ez az osztály tartalmazza az alapvető táblamanipulációs metódusokat, tulajdonságokat, stb.Munkánk során sokszor fogunk ezzel az osztállyal találkozni.

Data Access komponensekIde azok a komponensek tartoznak, amelyek segítségével megvalósítjuk az adathozzáférést, az adatbázis

fájljaival való kapcsolatot, ezek a komponensek kapcsolják össze az adatokat az adatmegjelenítő, manipulálóobjektumokkal.

TDataSourceEz a komponens teremt kapcsolatot az ún. DataSet komponensek és a vizuális adatmegjelenítő

(manipuláló) komponensek között. A DataSet komponensek azok a komponensek, amelyek valamilyenadathalmazt biztosítanak (TTable, TQurey). A komponens Dataset tulajdonságát kell a megfelelő komponensre(Table-re vagy Query-re) állítani.

TTableA TTable segítségével beépíthetünk egy táblát a programba. A komponens a BDE-t használva

hozzáférést biztosít egy adatbázis-táblához. Ennek segítségével kezelhetőek az adatok (navigáció, hozzáfűzés,módosítás, törlés, stb.).

Ha felhelyezünk egy ilyen komponenset a form-ra, az első dolog, amit tennünk kell, a táblázatfájlnevének megadása. Ehhez először a DatabaseName-et kell megadnunk, amennyiben létrehoztunk azadatbázisunk részére alias-t. Ezt a TableName tulajdonság beállítása követi. A lenyíló listában megtalálhatjuk azadatbázisunk fájljait, vagy ha nem használunk alias-t, a program könyvtárában lévő fájlokat.

Az IndexName beállításával megadhatjuk az index nevét, de használhatjuk erre a célra az IndexDefsvagy az IndexFieldNames tulajdonságokat is (bővebbekért ld. a súgót). Az indexeket természetesen futásidőbenis változtathatjuk, kivéve ha a CachedUpdates be van kapcsolva.

A CachedUpdates módot akkor használjuk, ha gyorsabb adathozzáférést szeretnénk megvalósítani,illetve minimalizálni szeretnénk a hálózati forgalmat. Ha ez be van kapcsolva, a BDE a memóriában tárolja azadatokat, és azokat nem menti lemezre, egészen addig, amíg meg nem hívjuk az ApplyUpdates metódust. Tehátha ezt nem tesszük meg, a módosítások elvesznek. A CachedUpdates mód akkor is hasznos lehet, ha olyanalkalmazást készítünk, amiben fontos, hogy akár nagy mennyiségű adatmódosítás is visszavonható legyen, ez a

Page 12: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

11

legegyszerűbb módja: ha vissza szeretnénk vonni a változásokat, csupán a CancelUpdates metódust kellmeghívnunk.

A tulajdonságok között találunk egy Active nevűt. Ezzel már akár szerkesztő módban is bekapcsolhatjuka táblát, de használhatjuk futásidőben az Open ill. a Close helyett is. Célszerű azonban szerkesztő módban nembekapcsolni, mert bizonyos esetekben megnehezítheti a munkánkat, hiszen ilyenkor lefoglalja az adatbázist, ígymás program (pl. Database Desktop) nem biztos, hogy hozzá tud férni.

A TTable eseményei között megtaláljuk a navigáció és az adathozzáférés összes eseményét, ezen kívülpedig hibakezelést is végezhetünk velük. Érdemes őket végignézni.

Segítségükkel például egyszerűen megoldhatjuk a törlésre való rákérdezést, illetve a törlésmegakadályozását bizonyos esetekben, stb.

A TTable metódusai (az egyszerűbbek) már csekély angoltudással rendelkezők számára is egyszerűenmegjegyezhetők: törölni a Delete-tel, hozzáfűzni az Append-del kell, stb. (bővebbeket ld. Delphi Help: TTable).

Fontos lehet, hogy a Table mezőit magunk is megadhatjuk. Ha akarjuk, nem kerül bele minden mező afizikai fájlból, de mi is adhatunk hozzá mezőket. Ezt a komponensre való dupla kattintással tehetjük meg alegegyszerűbben. A megjelenő ablak műveleteit a jobb gombbal való kattintással érhetjük el. Az Add all fieldsminden mezőt behelyez, ami a fájlban található. Új mező létrehozása esetén (New field) meg kell adnunk, hogyaz adatmező (Data field), számolt mező (Calculated field), vagy Lookup (kereső) mező legyen. Számítottmezőnél a tábla OnCalcFields eseményébe írhatjuk be a végzendő számításokat (figyeljünk arra, hogy be legyenkapcsolva az AutoCalcFields, mely biztosítja, hogy a számolt mezőket automatikusan számoljuk). A Lookupmező arra szolgál, hogy más táblából (DataSet) keressünk ki egy rekord egy mezőjét (Result field), amelynekvalamely mezője (Lookup Keys) megegyezik a jelen tábla egy mezőjének aktuális értékével (Key field). Ennekmegértéséhez itt egy egyszerű példa:

Van két táblánk:Nevek (szemelykod, nev)Lakas (szkod, lakhely)A Table1-ben szeretnénk látni a neveket és a hozzá tartozó lakhelyet is.A Table1 forrása legyen a Nevek. A Table2 a Lakas táblát biztosítja.A hozzájuk tartozó DataSet-ek értelemszerűen DataSet1, DataSet2.Adjuk hozzá a Table1 mezőihez mindet (Add all fields). Majd hozzunk létre egy új mezőt. Válasszuk aLookup field rádiógombot, majd töltsük ki a Lookup definition-t: Key Fields=szemelykod,DataSet=DataSet2, Lookup Keys=szkod, Result Field=lakhely.Az eredmény magáért beszél.

Ha a tábla mezőit hozzáadtuk a mezőlistához, azokat kiválasztva szerkeszthetjük őket az ObjectInspector segítségével. A rengeteg lehetőség közül egy hasznos dolgot emelnék ki, ez pedig a DisplayName,melyben azt a szöveget adhatjuk meg, amivel meg szeretnénk jeleníteni a rekordot. Ez azért hasznos, mertmezőneveknek általában rövidítéseket használunk, de ezeket a felhasználónak nem kell tudnia. Ha ezt atulajdonságot beállítjuk, ezen túl az adatokat megjelenítő komponensek ezt a nevet fogják kiírni.

A táblában található adatokat a Filter tulajdonság segítségével szűrhetjük is (amennyiben a Filteredtulajdonság true). Ennek megvan a megfelelő szintaktikája, amelyet a Help-ben a TBDEDataSet.Filter témaköralatt találjuk meg. Szűrés esetén a táblázatban csak a szűrőfeltételnek eleget tevő rekordok jelennek meg.

TQueryEz a komponens egy olyan DataSet-et épít be a programba, ami SQL kifejezésen alapul. Arra

használjuk, hogy SQL lekérdezéseket hajtsunk végre a segítségével. Azért hasznos ez a komponens, mert ezzelegyszerre több táblát is elérhetünk, illetve összekapcsolhatunk, valamint számításokat, rendezéseket,leválogatásokat is nagyon könnyen végezhetünk vele (az SQL nyelvből adódóan).

Itt is találunk a Table-höz hasonló tulajdonságokat és eseményeket. Ebből is látszik, hogy csak abbankülönbözik a TTable-től, hogy az adatforrása egy SQL lekérdezés. Természetesen a Query által visszaadottadatokat módosítani nem tudjuk, de magával a Query-vel végezhetők adatmódosító műveletek (Update, Delete,stb.), mivel ezeket az SQL nyelv lehetővé teszi. Ekkor a komponens nem ad vissza táblát. Az SQL lekérdezést akomponens SQL nevű tulajdonságában adhatjuk meg. Ha lekérdezést írunk, és még nem érezzük magunkat eléggyakorlottnak, célszerű a lekérdezést először a Database Desktop-pal elkészíteni, lefuttatni, és ha működik,utána átvinni a programunkba, így ugyanis egyszerűbb a hibaellenőrzés. Ha pedig valakinek nem tetszik aDelphi string-szerkesztő ablaka, a Code Editor gomb megnyomásával használhatja a normál kódszerkesztőablakot is. Ennek azért van előnye, mert itt az SQL parancsokat a Delphi felismeri, és kiemeli.

A TTable-höz hasonlóan ennél a komponensnél is működik a filter.Metódusai közül az ExecSQL nevűt említeném meg, mellyel lefuttathatjuk a lekérdezésünket.

Természetesen a TTable-höz hasonlóan itt is működik az Open és a Close is.

Page 13: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

12

TUpdateSQLHa már a Query-nél tartunk, érdemes megemlíteni a TUpdateSQL komponenset, amely kifejezetten

adatmódosításra szolgál. Itt külön törlő (DeleteSQL), módosító (ModifySQL) és hozzáfűző (InsertSQL) SQL-tadhatunk meg. Ezeket is az ExecSQL metódussal tudjuk futtatni, csak itt meg kell adnunk, hogy milyen módbanindítjuk el (törlő, módosító, beszúró).

TBatchMoveElőfordulhat, hogy szükségünk van arra, hogy egy táblából bizonyos adatokat egy másik táblába

másoljunk. Erre kitűnő eszköz ez a komponens. Fontos, hogy forrásnak (Source) és célnak (Destination) TTabletípust kell megadni, tehát az adott táblának léteznie kell a programban.

Minden ilyen esetben ajánlatos ezt a komponenset használni, mivel ezzel lehet a leggyorsabbanadatokat mozgatni. Még ha SQL-ben egyszerűbbnek is tűnik egy ilyen művelet (mondjuk egy Insert vagyUpdate), a gyakorlat azt mutatja, egy query lefuttatása nagyságrendekkel több időt vesz igénybe – ami kevésadatnál még nem érzékelhető, de minél több adat van, annál lassabb lehet egy ilyen lekérdezés. Ezzel akomponenssel ráadásul nem csak másolni, hanem törölni is lehet (a céltáblából törli azokat az adatokat, amelyekmegvannak a forrásban is).

Data Controls komponensekIde az adatokat megjelenítő, kontroláló vizuális komponensek tartoznak.

TDBGridEgyszerű táblamegjelenítő komponens. Egy TTable (vagy TQuery)objektum tartalmát jeleníti meg,

standard formában (a táblázat oszlopai a mezők, sorai a rekordok). A tábla tartalmát szerkeszteni is tudjuk asegítségével (amennyiben a ReadOnly tulajdonsága false). A szerkesztés a standard táblázatkezelőprogramokhoz hasonlóan történik (érdemes vele kísérletezni). Szerkesztésre való használatát azonban csakmódjával javaslom, mert amilyen kevés dolga van vele a programozónak, annál több bosszúságot okozhat ez akomponens. Ennek több oka is van. Egyrészt a felhasználók számára bizonyos esetekben bonyolultnak tűnhet ezaz adatszerkesztési mód, másrészt a szerkesztést teljes egészében a komponens oldja meg, azaz nekünk nehezebbdolgunk van, ha egyénileg szeretnénk megvalósítani ezeket. Használata ezért csak egyszerűbb táblázatokszerkesztésére ajánlott. Kitűnő viszont arra, hogy összesített adatokat, lekérdezéseket (SQL), valamint listákatjelenítsünk meg vele. Ha szerkeszteni szeretnénk a tartalmát, célszerű erre a célra külön ablakot (adatlapot)gyártani, ami megkönnyíti a szerkesztést (lásd: V. fejezet).

A komponens Options tulajdonságát kinyitva rengeteg beállítási lehetőséget találunk. Ezek közülnéhányat emelnék csak ki. A dgEditing tulajdonságot false-ra állítva kikapcsolhatjuk a szerkesztő módot, így azadatokat nem lehet módosítani. A dgRowSelect bekapcsolásával egyrészt automatikusan kikapcsoljuk aszerkesztést, másrészt engedélyezzük, hogy a táblázatnak mindig egy teljes sora legyen kijelölve. Ezzel azonbancsínján kell bánni, mert ha nem fér ki egyszerre a táblázat összes oszlopa, és tovább lapozunk a gördítősávon,hogy láthatóvá tegyük a többi oszlopot is, majd valamelyik sorra kattintunk, a táblázat automatikusan visszaállúgy, hogy az első oszlop lesz látható. Ez a jelenség csak a dgRowSelect bekapcsolt állapotánál jelentkezik, éssokszor kellemetlenségeket okoz. Figyeljünk arra is, hogy amennyiben a dbRowSelect be van kapcsolva, adbEditing-et nem tudjuk true-ra állítani. A dgIndicator a táblázat bal oldalán lévő indikátor-oszlopot kapcsoljabe, illetve ki. Ez az indikátor sokszor hasznos, mert látjuk az aktuális rekordot, és annak állapotát (szerkesztett,beszúrt, stb.).

Sokszor lehet arra szükség, hogy a táblázatból csak meghatározott mezőket jelenítsünk meg, illetvehogy csak meghatározottakat tudjunk szerkeszteni. Erre szolgál a DBGrid oszlopszerkesztője (Column Editor),amit a Columns tulajdonság gombjára kattintva érhetünk el (ezen kívül megnyithatjuk ezt az ablakot akomponensre való dupla kattintással, illetve a helyi menüjéből is). Alapértelmezésben ez az ablak üres, tehát atáblázat minden mezőt megjelenít, amit a hozzá tartozó Table tartalmaz. A helyi menüből (jobb gomb), illetve azablak eszköztárából is elérhető Add All Fields paranccsal azonban hozzáadhatjuk az összes mezőt, hogy aztánsaját kedvünk szerint szerkeszthessük azokat. Az ablak egy sorára kattintva az Object Inspector-banmegjelennek annak tulajdonságai, amelyek segítségével minden lényegi jellemzőt beállíthatunk. Nagy táblázatokesetén például ajánlatos különböző színű oszlopokat használni. Ha pedig valamelyik mezőre nincs szükségünk,egyszerűen kitörölhetjük ebből a listából.

Van a komponensnek egy apró, ám néha elég zavaró hibája: a görgetősávot nem hagyományos módonkezeli. A csúszka mérete ugyanis mindig állandó, és nem követi a görgetést, mivel ha az első elem az aktív, acsúszka legfelül van, ha az utolsó elemen állunk, akkor legalul, minden egyéb esetben pedig a sáv kellősközepén. Sőt, ha föl-le görgetünk, és az aljára illetve a tetejére lapozunk a táblázatban, a csúszka csak akkormozdul el a sáv aljára ill. tetejére, ha az első ill. utolsó elem az aktív, és észreveszi, hogy nem tud tovább

Page 14: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

13

görgetni (EOF vagy BOF). Ez a hiba jelentősen megnehezítheti a táblázatban való navigálást, mivel nem látjuk,hogy hol járunk benne.

TDBNavigatorEz egy egyszerű komponens, mely csupán az alapvető tábla-navigációs parancsok kiadására szolgál:

lapozhatjuk vele adatainkat, szerkeszthetjük, elmenthetjük, törölhetjük (stb.) őket. A VisibleButtons tulajdonságsegítségével megadhatjuk, mely gombok legyenek láthatóak.

A következőkben olyan komponensekről lesz szó, amelyekhez hasonlók megtalálhatók a Standardkomponensek között is. Ezért ezek használatát nem részletezem, csupán a standard változattól való eltérésekre ésaz adatbázis-kezelő vonatkozásaira térek ki.

TDBTextA standard TLabel-höz hasonló statikus adatmegjelenítő komponens, mely egy adatforrás egy

mezőjének aktuális értékét jeleníti meg. Szerkesztésre nem használható. A DataSet és a DataField tulajdonságsegítségével adható meg a megjeleníteni kívánt mező forrása és neve.

TDBEditEnnek is megvan a standard párja, a TEdit, melytől csupán annyiban tér el, hogy szövegét egy tábla egy

mezőjének aktuális értékéből veszi, illetve szerkesztésénél ezt a mezőértéket módosítja. Hasonló a TDBText-hez.

TDBMemoMemo típusú mezők megjelenítésére szolgáló komponens. Használata ennek is triviális.

TDBImageSzintén egyszerű komponens, amely a képeket tartalmazó mezők megjelenítésére szolgál.

TDBListBoxEz egy olyan speciális ListBox, melynek elemei (Items) egy adott tábla adott mezőjének lehetséges

értékeit tartalmazhatja. Az aktuális értéket – amennyiben az megtalálható a listában – automatikusan kijelöli. Azadott mező értékének szerkesztése úgy történik, hogy a listából (kattintással) kiválasztunk egy elemet, és az kerülbe új értékként a mezőbe. A lehetséges elemeket a TStrings típusú Items tulajdonságában adhatjuk meg.

Akkor használjuk, ha egy mezőnek csak adott értékei lehetnek, így a felhasználó semmiképpen nem tudmás értéket beállítani (pl. neme: férfi/nő).

TDBComboBoxOlyan a TComboBox nevű standard komponensből készült lenyíló lista, mely az imént említett

TDBListBox-hoz hasonlóan működik, csak itt a lista a lenyitó gomb megnyomása után jelenik meg.

TDBCheckBoxLogikai (boolean) típusú adatmezők megjelenítésére és szerkesztésére szolgáló jelölőnégyzet.

Használata ugyancsak triviális.

TDBRadioGroupA TDBListBox-al megegyező funkciókat lát el, rádiógombok használatával.

TDBLookupListBoxOlyan ListBox, amely lookup (kereső, lásd: II. fejezet) mező működtetésére szolgál. Egy tábla egy

mezőjének értékét jeleníti, illetve szerkeszti. A lista elemeit a ListSource (TDataSet) forrás ListField mezőjének

Page 15: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

14

rekordjai alkotják. A KeyField tulajdonságba a ListSource azon mezőjét állítjuk be, amely alapján keresniakarunk a ListSource-ban. Természetesen a DataSource és a DataField a manipulálandó adat forrását és mezőjétadja meg.

TDBLookupComboBoxA TDBLookupListBox-hoz hasonló, csak ennél lenyíló listából választhatunk értéket.

TDBRichEditRichText szerkesztő, amely tartalmát memo típusú mezőben tárolja. Olyan helyzetekben célszerű

használni, amikor szükség van a szövegek formázott tárolására (például ha olyan szövegeket tárolunk, melyeketesetleg nyomtatni is fogunk, és szükségünk van alapvető formázási lehetőségekre), ugyanis ez a komponens (aszabvány RichText formátumot használva) formázással együtt kezeli a mező tartalmát (így hagyományosTDBMemo-val megjelenítve nem a kész szöveget, hanem annak forráskódját kapjuk).

TDBCtrlGridOlyan táblázat, amely egy adatforrás rekordjait jeleníti meg, szabad formájú elrendezésben. Ez azt

jelenti, hogy különböző adatmanipuláló objektumokat helyezünk el a táblázat legfelső sorába, amiket a programfutásakor a komponens megsokszoroz, és minden egyes sorban ugyanazzal a kiosztással megjeleníti a rekordokadatait. A táblázatra azonban csak bizonyos adatmanipuláló komponenseket helyezhetünk föl (például TDBEdit,TDBListBox, stb.). a DataSource tulajdonságot a DBCtrlGrid-nek kell beállítani, a rajta lévő objektumokDataSource nevű tulajdonsága nem állítható.

TDBChartAdatbázison alapuló grafikon készítésére szánt komponens. Mivel használata, működése olyan

szerteágazó, és sokrétű, hogy talán egy külön munkát is megérne, nem foglalkozunk vele. Érdemes megtekintenidemóját, a Delphi könyvtárában a Demos\Teechart\teedemo.dpr fájlt megnyitva és futtatva.

Nyelvi problémákA Delphi adatbázis-kezelő komponenseit használva hamar rábukkanunk az angol nyelvű szövegekre,

melyeket a komponensek működés közben jelenítenek meg. Például ha egy DBGrid-et vagy DBNavigator-thasználunk, és bekapcsolva hagyjuk a ConfirmDelete tulajdonságot, majd törölni próbálunk egy adatot, azonnalelénk ugrik a következő kérdés: „Delete Record?”. Ha tovább játszadozunk a komponensekkel, az esetlegeshibajelzéseket is angolul fogjuk megkapni. Ez egy magyaroknak szánt, magyar nyelvű program esetében nemmutat jól, és – amennyiben a felhasználó nem tud angolul – különösen zavaró lehet.

„Mit tehetünk?” – hangzik a kérdés. A válasz egyszerű, de nem kézenfekvő: át kell írni az angolszövegeket magyarra. Hogy hol? A Delphi könyvtárában a Source\Vcl könyvtárban található egy dbconsts.pasnevű fájl. Ebben csak a Db-komponensekkel kapcsolatos szövegek vannak definiálva, mint konstansok. Ezeketegyszerűen át kell írni, és a nyelvi problémáink nagy része megoldódik, méghozzá örökre. (Célszerű utána ezt azátszerkesztett fájlt biztonságos helyre is elmenteni.) Amennyiben még mindig van angol szöveg a programban, aDelphi 5-öt használóknak van még egy lehetősége: a Project\Languages menüpont, ahol némi ügyeskedés utánlefordíthatjuk a programban található összes string-et (bővebbeket ld. Delphi Help: languages: adding to aproject).

TDataModuleHa már próbálkoztunk néhány bonyolultabb ablak összeállításával, láthatjuk, hogy a nem vizuális

adatkomponensek (mint például a TTable és társai) sok helyet foglalhatnak el a form-on. Ezt kiküszöbölendőszületett a TDataModule komponens, mely egy olyan ablak, amelyen csak nem vizuális komponenseket lehetelhelyezni. Előnye, hogy áttekinthetőbbé tudjuk tenni a programunkat, mivel ezen az ablakon bárhová tehetjük akomponenseket, és az ablak is bármekkora lehet, hiszen nem jelenik meg futás közben. Másik előnye, hogy haegy ablakra kiteszünk egy komponenset, annak lenyitjuk a DataSource tulajdonságát, a Delphi az aktuális form-on lévőkön kívül felkínálja azokat az objektumokat is, amelyek a DataModule-on vannak.

Delphi 5-öt használók még adat-diagrammot is készíthetnek a DataModule segítségével.

Page 16: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

15

IV. Egy adatbázis-kezelő alkalmazás elkészítése

A továbbiakban arról lesz szó, milyen módszerekkel és feltételekkel készíthetünk adatbázis-kezelőalkalmazásokat Delphi-ben.

TervezésA programok készítésének első és legfontosabb fázisa ez. Gondos tervezés nélkül nem szabad (és

igazán nem is lehet) elkezdeni egy fejlesztést. A program először mindig a fejlesztő agyában születik meg, éscsak aztán kezdődik a kódolás. Félreértés azonban ne essék! A program gondos megtervezése nem azt jelenti,hogy sorról sorra megírjuk előre a kódot, hanem hogy átgondoljuk működési elvét, rendszerét. A gyakorlatimegvalósításon elég kódolás közben gondolkodni, mert ha jó a tervezés, nincs probléma vele. Csak akkorkezdjünk el programot tervezni, ha az adatbázis már gondosan megterveztük és elkészítettük. Annak ugyanisfüggetlennek kell lennie a programtól.

Fontos szempont programtervezésnél, hogy rendszere átlátható és könnyen bővíthető legyen. Mivel aDelphi objektumorientált fejlesztőrendszer, nekünk is objektumorientáltan kell gondolkodnunk. Aprogramunknak jól kell illeszkednie az általa használt adatbázis felépítéséhez. Minden feladatot az elvárt módonkell megoldania. Fel kell készülni arra is, hogy az „éles” használat során hatalmas adatmennyiségekhalmozódhatnak föl, így mindenre meg kell keresnünk a legoptimálisabb megoldást. Gyakori hiba, ha a fejlesztőnem gondol arra, hogy jóval több adat kerül majd az adatbázisba, mint amennyivel tesztelte. Az nem elég, ha atesztek során a program szép eredményeket produkál. Mindig el kell gondolkozni azon, nem lehet-e még jobban,még egyszerűbben, még gyorsabban megoldani a feladatokat.

Az ablakokat is érdemes előre megtervezni, így áttekinthetőbb lesz a programterv, és később isgyorsabban halad a munka. És persze a megrendelőnek meg lehet mutatni ezeket a terveket, ami nem egy utolsószempont.

Ez a fejezet nem programot tervezni tanít, inkább segítő kezet nyújt a tervezéshez és a kódoláshoz.

A DataModuleHa túl vagyunk a tervezésen és az adatbázis létrehozásán, az új Project megnyitása után első dolgunk

egy új Data Module megnyitása (File/New/Data Module). Ebbe kerülnek bele aztán a táblák (TTable), és azSQL-ek (TQuery). Mindegyiknek be kell állítani a DatabaseName tulajdonságát, illetve a forrását (TableNameés SQL). Ha ezeket meg is szeretnénk jeleníteni, csatlakoztatnunk kell hozzájuk egy-egy DataSource-t (ki kellhelyezni őket, majd a DataSet tulajdonságukat a megfelelő értékre állítani).

Ezek után be kell állítanunk a lookup kapcsolatokat.El kell döntenünk, hogy egy-egy táblát vagy Query-t mikor szeretnénk használni. Ha a program futása

során állandóan (vagy elég gyakran) szükségünk van rá, célszerű ezt a program futásának kezdetén megnyitni(nem ajánlatos már szerkesztő módban megtenni ezt, az Active tulajdonság true-ra állításával, mert ez akésőbbiekben problémákat okozhat). Ehhez érdemes a táblákat tartalmazó DataModule OnCreate eseményébehelyezni a megnyitási blokkot. A megnyitást mindig ajánlatos Try-blokkba tenni (ld. Delphi Help: Try...exceptstatements; VI. fejezet). Így ha nem sikerül megnyitni valamelyik táblát, az esetleges hibákat az Except részbenle tudjuk kezelni. A legegyszerűbb ilyen megnyitási blokk így néz ki:

TryTable1.Open;Table2.Open;Query1.Open;//stb…

ExceptShowMessage(’Hiba! A táblák megnyitása meghiúsult.’);Halt;

End;

Használhatunk persze olyan táblákat és lekérdezéseket is, amelyeket csak néha, vagy egy adott modulmegnyitásakor kell megnyitnunk. Ekkor értelemszerűen járjunk el, és a megfelelő helyre helyezzük az Open-eket, hogy elkerüljük a fölösleges erőforrás-pazarlást.

Ha a táblákhoz jelszó is tartozik, a jelszavakat a Session.AddPassword metódus segítségével tárolhatjukel. Így a programunk tudni fogja a jelszót (vagy jelszavakat), és nem fog külön rákérdezni. Az AddPasswordmetódust mindig a megnyitás előtt kell meghívnunk.

Ha még csak most kapizsgáljuk a Delphi adatbázis-kezelését, még nincs rá szükségünk, de későbbfelmerül a kérdés: „Mi lesz, ha törlődik az alias, vagy olyan gépen indítjuk el a programunkat, ahol van BDE,elérhető az adatbázis is, de még nincs hozzá alias?” Ebben az esetben vagy kézzel hozzuk létre, vagy (és ez aszebb megoldás, hiszen ehhez a felhasználónak nem kell ismernie BDE Administrator-t) a programunkkal

Page 17: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

16

végeztetjük el ezt a munkát. A megoldás alapesetben egyszerű, le kell kérdezni, hogy létezik-e az adott alias, ésha nem, létre kell hozni. Ez addig jó, amíg a programunk indítási könyvtárához képest fix helyen található azadatbázis könyvtára (mondjuk a program könyvtárában van egy Database könyvtár). Használhatjuk azonban azadatbázist hálózaton keresztül is. Ekkor nem tudhatjuk, hol lapul az adatbázisunk. Ekkor bizony a vétlenfelhasználóval kell megkerestetnünk azt.

Ilyen problémák megoldására a következő módszert ajánlom. Ha a programot és az adatbázist egyazonszámítógépre telepítjük, az adatbázis mindig legyen a program könyvtárában, például egy Database nevűalkönyvtárban. Így ha nem létezik az alias, egyszerűen létrehozzuk, és beállítjuk neki könyvtárként ezt akönyvtárat. Arra is fel kell azonban készülni, hogy az adatbázist egy másik számítógépen szeretnénk tárolni.Ilyenkor a programnak célszerű megnéznie, létezik-e ez a bizonyos Database könyvtár. Ha nincs, akkorbizonyára valahol máshol kell lennie. Ekkor a legjobb, ha közöljük a felhasználóval, hogy nem tudjuk, hol azadatbázisa, és legyen szíves, mutassa meg nekünk. Ezt egy egyszerű fájlmegnyitó ablakkal is megtehetjük. Ha ezmegvan, már létrehozhatjuk az alias-t. A figyelmes programozó az ekkor megadott könyvtár nevét eltárolhatjaegy fájlban, így ha legközelebb „eltűnik” az alias, csak onnan kell kiolvasni annak helyét, nem kell afelhasználót nyaggatni ezzel.

Egyébként aggodalomra semmi ok, az alias-ok nem szoktak „csak úgy eltűnni”. Ez a problémaáltalában a program első indításakor jelentkezik. Persze a program telepítőjével (ld.: VI. fejezet) is létrehozhatjukaz alias-t, de tapasztalatom azt mutatja, hogy az ékezetes könyvtárnevekkel (ha az adatbázis elérési útjában vanékezet) vigyázni kell.

A probléma programon belüli megoldására itt egy egyszerű példa (a DataModule OnCreateeseményében):

var ActDir:string; {az aktuális könyvtárat fogjuk ebben tárolni}DBDir:string; {az adatbázis könyvtárát tároljuk ebben}

{…}if not Session.IsAlias('En_Aliasom') thenbeginGetDir(0,ActDir); {Lekérjük az aktuális könyvtár nevét}if DirectoryExists(ActDir+'\Database')then DBDir:=ActDir+'\Database'elsebeginShowmessage('_Hibaüzenet_');Form1.OpenDialog1.Directory:=ActDir; {Az OpenDialog valamely

létező form-on kell, hogy legyen!}if not Form1.OpenDialog1.Execute then Halt {ha a felhasználó

mégsem-mel lépett ki, megszakítjuk a program futását}DbDir:=Form1.OpenDialog1.Directory;

end;try{Létrehozzuk az alias-t:}Session.AddStandardAlias('EN_Aliasom', DbDir, 'PARADOX');{Mentjük a BDE beállításait:}Session.SaveConfigFile;

finallyShowmessage('Az adatbázis inicializálása befejeződött.');

end;ChDir(ActDir); {visszaállítjuk az aktuális könyvtárat}

end;{…}//Itt jöhet a táblák megnyitása...

Ha ezzel is kész vagyunk, a táblák egyes eseményeihez hozzá kell rendelnünk a saját eljárásainkat. Megkell adnunk, mi történjen, ha a felhasználó ki akar törölni egy adatot, vagy újat akar beszúrni, stb., azaz ki kelldolgozni a táblák eseményeit. Főként érinti ez a számított mezőket, hiszen azok számítási algoritmusát a táblákOnCalcFields eseményében kell kifejteni. Hogy ezen felül mire van még szükség, azt a program milyensége és aprogramozó ízlése határozza meg.

Az ablakokAz alkalmazások fejlesztése során nagy hangsúlyt kell fektetnünk az ablakok kialakítására, hiszen a

programot a felhasználónak készítjük, és a felhasználók számára fontos a jó megjelenés és a könnyűkezelhetőség. Elsődleges szempont mindig a funkció. Mindennek a helyén kell lennie, és megfelelően, logikusankell működnie. Emellett azonban figyelnünk kell arra is, hogy fölösleges, zavaró dolgok ne kerüljenek a

Page 18: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

17

képernyőre. Csak azt jelenítsük meg, ami információ-tartalommal bír. A redundanciát lehetőleg kerüljük.Ablakunkat továbbá minél átláthatóbbá kell tennünk. A felhasználók azt szeretik, ha egy általuk is követhető,egyszerű logika alapján épülnek fel a kezelőfelületek. Ez sokszor okoz fejtörést a fejlesztőnek, mivel ő a belsőműködése felől szemléli a programját. Akkor jó egy program, ha a felhasználónak nem szükséges tisztábanlennie a belső működéssel.

Ha az ablak funkcionálisan megfelelő felépítésű, még nem biztos, hogy könnyen kezelhető. Ehhezelőször is mindent jól láthatóvá és használható méretűvé kell tennünk. Ez alatt elsősorban a betűtípust és méretet,valamint a gombok és egyéb objektumok nagyságát értem. A Windows által használt alapértelmezettbetűtípusnál (MS Sans Serif 8) a 10-es méretű Arial olvashatóbb, ezért célszerű a form-unk létrehozása utánrögtön erre beállítani a form Font tulajdonságát. Ez a beállított érték lesz érvényes a form-ra kerülőobjektumokra is. Ha van a képernyőn hely, a gombokat érdemes az alapértelmezetthez képest egy kissémegnagyítani.

Programunkat átláthatóbbá tehetjük továbbá azzal, ha a szabványos gombok (TButton) helyett TBitBtn-thasználunk, amelyre kis képeket lehet helyezni (Glyph), ezzel megkönnyítve a felismerésüket. Elegendőképecskét találunk a Delphi képtárában, amelyet telepítéstől és verziótól függően a Delphi könyvtárán belül azImages\Buttons, vagy a Program files\Common Files\Borland Shared\Images\Buttons könyvárban keressük.

Találkozhatunk olyan esettel is, amikor a programot a megrendelő érintőképernyős monitoron szeretnéhasználni. Ekkor már tervezéskor figyelnünk kell az ablakokon található kezelők méretére, mert egy mármeglévő ablakot átszabni úgy, hogy minden megfelelő méretű legyen, sokszor nagy vesződségekkel jár. Ha nemfér el minden szükséges funkció egy ablakban, akkor célszerű azokat egymás után megjelenőpárbeszédablakokba helyezni. Ekkor figyeljünk arra, hogy logikusan, lépésről lépésre haladjunk. Itt említemmeg, hogy azok az objektumok, amelyek rendelkezhetnek gördítősávval, a Windows gördítősáv-beállításaithasználják. Ez gyakran kicsinek bizonyul. Ebben az esetben célszerű a felhasználót felszólítani, hogy amegfelelő helyen tegye meg a szükséges beállításokat a Windows-ban. Ha erre felkészülünk, a programunkatcélszerű nagy gördítősáv-mérettel is kipróbálnunk, hogy ne később érjen meglepetés.

Létezik még egy erős buktató az ablakok tervezésében és kivitelezésében. Ez pedig a felbontás kérdése.Nem mindegy ugyanis, hogy milyen felbontásban tervezzük meg az ablakot, és hogy azt milyen felbontásbanfogják használni. Gyakori hiba, hogy valaki egy 1024x768 méretű képernyőn tervezi meg az ablakjait, de azt egy800x600-as képernyőn fogják futtatni, és azon bizonyos dolgok kilógnak a képből. De az ellenkezője iselőfordulhat, amikor egy kisebb felbontásra tervezett programot nagyobb felbontásban futtatunk, és hatalmasüres helyek jelennek meg az ablakok jobb szélén és alján. A problémára több megoldás is van. Először iscélszerű skálázható ablakokat készítenünk. Ekkor azt kell meghatározni, hogy melyik komponens melyikirányba legyen mozdítható. Erre rendelkezésünkre áll a komponensek Anchors tulajdonsága. Ennek négy logikaitípusú eleme van (Left, Top, Right, Bottom), amelyekkel meghatározhatjuk, hogy a komponens az ablak melyikszéléhez legyen rögzített távolságra (célszerű kísérletezni vele). Jól skálázhatóvá tehetjük alkalmazásunkat, hamegfelelően használjuk a komponensek Align tulajdonságát (ez nem minden komponensnek van, és nemösszekeverendő az Alignment-tel). Ha pl. alClient-re állítjuk, a komponens kitölti a teljes területét az ablaknakvagy annak a panelnek, amelyre helyeztük. Érdemes egyébként TPanel-eket használni, objektumok egycsoportjának megjelenítésére, mert a segítségükkel csoportosíthatjuk a komponenseket, és a TPanel-nek is vanAlign tulajdonsága. Az Align tulajdonságot alLeft-re, alTop-ra, alBottom-ra vagy alRight-ra állítvaértelemszerűen a megfelelő oldalra zárva jelenik meg a komponens.

Csúnya, de sokszor elkerülhetetlen megoldás, ha az ablak (form) automatikus görgetését (AutoScroll)használjuk ki. Bizonyos speciális szoftvereknél azonban nem érdemes ilyenekkel vesződni, hanem egyszerűenmeg kell határozni egy felbontást, amelyben a program működik. Ha pedig a program elindításakor nemmegfelelő a felbontás, figyelmeztetni kell erről a felhasználót (a kép méretét a Screen.Height, ill. a Screen.Widthtulajdonságok segítségével kérdezhetjük le a legegyszerűbben).

AblaktípusokAlkalmazásunk tervezésénél figyelembe kell vennünk, hogy hogyan fogják használni. Két elrendezési

típus közül választhatunk. Az egyik a hagyományos (SDI) ablakok, amikor egy újonnan megnyíló ablak a többifölé rajzolódik, és esetleg váltogathatunk a megnyíló ablakok között. Ha ezt a megoldást használjuk, oda kellfigyelnünk arra, hogy a párbeszédablakok mögötti ablak ne legyen elérhető (az Enabled tulajdonsága legyenfalse, vagy nem a Show, hanem a ShowModal metódussal jelenítjük meg a párbeszédablakot).

Használhatjuk azonban az ún. MDI ablakokat is. Ezek előnye, hogy a gyermekablakok a szülőablakonbelül nyílnak meg (ezt a megoldást használják pl. a szövegszerkesztők is). Ehhez állítsuk a főablak FormStyletulajdonságát fsMDIForm-ra, a gyermekablakokét pedig fsMDIChild-ra. MDI ablakokat használva a Windowsrengeteg lehetőséget nyújt, így egyszerűen készíthetünk ilyen alkalmazásokat (ld.: Delphi Help: MDIapplications).

Szintén érdemes megfontolni, hogy az általunk készített program az egyedüli alkalmazás-e, amithasználni fognak a számítógépen. Ha igen, akkor hasznos lehet, ha a programot teljes képernyőn futtatjuk,eltakarva ezzel a Windows tálcáját is (ehhez a WindowsState-et wsMaximized-re, a BorderStyle-t pedig bsNone-ra kell állítani). Így a felhasználó nem tud véletlenül rossz helyre kattintani, elindítva ezzel valamilyen nem

Page 19: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

18

kívánatos alkalmazást. Ha viszont más szoftvereket is használnak egy időben az általunk készítettel,mindenképpen adjunk arra lehetőséget, hogy a programot minimalizálni lehessen, és futásakor el lehessen érni aStart menüt és a tálcát.

A főképernyőA szoftverek egyik legfontosabb eleme (vizuális szempontból), a programmodulok közötti összekötő

kapocs, a főképernyő. Nem szabad tehát elhanyagolnunk ezt sem, a modulokhoz hasonlóan, körültekintően kellbánnunk vele. A főképernyő milyensége elsősorban attól függ, hogy alkalmazásunk hagyományos SDI, vagyMDI ablakokat használ.

Hagyományos ablakok esetén a hagyományos főképernyő-struktúra használata ajánlott. Ez azt jelenti,hogy a program különböző funkcióit a főképernyőn elhelyezett nyomógombokhoz rendeljük (ha túl sok ilyenfunkció van, használhatjuk azt a megoldást, amikor egy gombot lenyomva egy legördülő menü [Popup Menu]jelenik meg). A gombok elhelyezkedése esztétikailag és logikailag is fontos, de lényegében a fejlesztő ízlésehatározza meg milyenségét.

Ha MDI ablakokat használunk, a program funkcióit az ablak tetején, menüsorban, illetve eszköztár-sorban érdemes elhelyezni. Mindkettőhöz teljes támogatást nyújt a Windows. Megadhatunk pl. egy menüpontot(WindowMenu), amelybe a Windows automatikusan beírja a nyitva lévő gyermekablakok listáját, és segítségévelkönnyedén át is válthatunk egy másikra.

Igényes fejlesztők szépíthetik az alkalmazásukat úgy is, hogy a főképernyő hátterébe valamilyen képethelyeznek el (ilyenkor a TImage nyújtja a segítő kezet). Internetről letölthető komponensekkel a gombok teljesátalakítását („textúrázását”) is meg lehet oldani. Minden csak ötletek kérdése. A felhasználók pedig szívesebbendolgoznak szép programokkal.

A többi ablak szépítését azonban nem kell túlzásba vinni, mert ez sokszor a használhatóság káráraválhat.

Egy hagyományos főképernyő, textúrázott gombokkal és háttérrel…

…és egy egyszerűbb elrendezésű, lenyíló menüvel

Táblamegjelenítő ablakokMegszokott dolog, hogy ha adatbázisról beszélünk, rögtön összekapcsolt táblázatok sokaságára

gondolunk. Adatbázis-kezelő programok sokasága jeleníti meg táblázatban adatait. Ez azonban nem jelenti azt,hogy ez minden esetben jó. Csak akkor szükséges ilyen ablakokat alkalmazni, ha szükség van a rögzített adatok

Page 20: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

19

sokaságának áttekintésére, összehasonlítására. (Tehát egy jegykiadó-nyomtató programban fölösleges az eddigfölvett jegyek listájának megjelenítése, hiszen visszamenőleg csak bizonyos kimutatásokat, lekérdezéseketvégzünk, de a konkrét adathalmazra nincs szükségünk.)

Ezek után, ha úgy gondoljuk, hogy mégis szükségünk van táblázatra, azt inkább csakadatmegjelenítésre, és nem szerkesztésre ajánlatos használni. A táblázattal történő adatmegjelenítésnek van egynagy előnye: ha ügyesen csináljuk, a felhasználó egyszerűen és gyorsan navigálhat, kereshet, rendezhet, szűrhetbenne.

Egy általános táblázat-ablaknak a következő részei lehetnek: (1) maga a táblázat, (2) a navigációs panel,(3) műveletvégző panel, (4) szűrő panel, (5) információs sáv (státuszsor). Ezek közül természetesen nemkötelező mindnek szerepelni, és egyéb dolgot is megjeleníthetünk, igény szerint.

A táblázatot (1) természetesen DBGrid-del valósítjuk meg (erről a komponensről már szót ejtettünk aIV. fejezetben). Az első, amit meg kell tennünk vele, hogy testre szabjuk a megjelenítését az Options és aColumns tulajdonságok segítségével. Beállítjuk a megjelenítendő mezőket, esetleg azok színét, méretét, stb. ezekután gondolnunk kell az eseményeire. Gyorsbillentyűket definiálhatunk az OnKeyPress és az OnKeyDownesemény segítségével, és itt tudjuk megoldani a rendezés kérdését is. A leggyakoribb megoldás ugyanis egytáblázatban a rendezés beállítására, hogy amelyik oszlop fejlécére kattint a felhasználó, a szerint az oszlopszerint rendezzük az adatokat. Ehhez azonban tudni kell, hogy rendezni csak akkor tudunk, ha azt az adatokatbiztosító Table lehetővé teszi, azaz a definíciójában szerepel az adott mező szerinti index (Query használataesetén a rendezési sorrendet csak a lekérdezés módosításával és újrafuttatással változtathatjuk meg).Amennyiben erre lehetőségünk van, a megoldás egyszerű: a DBGrid OnTitleClick eseményében figyeljük, hogymelyik oszlopra történt a kattintás, és az annak megfelelő értékre állítjuk a tábla indexét. Érdemes még ilyenkora fejléc betűtípusát megváltoztatni (pl. félkövérre, vagy aláhúzottra), hogy könnyen látható legyen az aktuálisrendezés. Arra figyeljünk, hogy a lookup mezők szerint nem lehet rendezni. Így csak a kapcsolatot megvalósítókulcs szerint rendezhetünk (ami általában szám), és egyáltalán nem garantált, hogy ez meg fog felelni azízlésünknek. Megoldás lehet az, hogy SQL lekérdezéseket használunk, illetve ezeket vegyítjük a táblákkal.(Találkoztam már olyan megoldással, hogy a két legfontosabb lookup-mezőhöz tartozott egy-egy Query, és haazon mezők fejlécére kattintott a felhasználó, a tábla helyett a Query-t kapcsolta be a program a táblázatadatforrásául, a Query-t pedig minden adatmódosításnál újrafuttatta. Ez kissé lassúnak tűnhet, de mindenképpencélravezető.).

A navigációs panel (2) a másik dolog, amire szinte mindig szükség van. Szerepe akkor nagy, ha márnagyon sok adatunk van a táblázatban, és gyorsan el szeretnénk jutni egy adott rekordhoz. Ami biztosan kell, aza táblázat első és utolsó rekordjára mozgató gomb (segítségünkre van a TDBNavigator). A másik egy, akulcsmezőkhöz rendelt ugró-sáv. Ezt egy egyszerű TEdit-tel és egy gombbal tudjuk megvalósítani. Ha a gombrakattint a felhasználó, az adatbázisban megkeressük a begépelt szöveghez legközelebb eső adatot(Table.FindNearest). Fontos, hogy ezt csak kulcsmezőkkel tudjuk elvégezni. Nehezebb a dolgunk, ha egylookup-mező értékeit is bevesszük. Ekkor abban a táblában kell keresni, amelyikből a lookup szedi a rekordokat,és a talált rekord kulcsértékét kell megkeresni a táblázatunkban.

Külön panelen illik elhelyezni azokat a gombokat, amelyekkel műveleteket végezhetünk (3). A háromalapvető műveletnek mindenképpen ott kell lennie (beszúrás, módosítás, törlés), de ide kerülhetnek a nyomtatás,szűrés és egyéb lekérdezések gombjai. Ha lehet, használjunk BitButton-okat (TBitBtn), és helyezzünk ki rájukkülönböző kis képeket. Bizonyos esetekben használhatunk szerkesztő objektumokat is (DBEdit, DBComboBox,stb.), mentő és elvető gombokkal kísérve.

A szűrő panelnek (4) nem muszáj mindig látszania, inkább egy gombbal ki-be kapcsolgathatjuk. Aszűrőt úgy kell elkészítenünk, hogy a lehető legtöbb adatra tudjunk vele szűrni. Itt is fontosnak tartommegemlíteni, hogy lookup típusú mezőkre nem lehet szűrni, ezt máshogy kell megoldanunk, például úgy, hogy alookup mező forrástáblájából minden adatot kilistázunk egy ComboBox-ba, és egy adott elem kiválasztásánálrákeresünk arra a kapcsolt táblában, majd a talált mező kulcsértéke szerint szűrjük a táblázatunkat. AComboBox-ot normál szűrőknél is használhatjuk, de azt minden adatmódosítás esetén újra fel kell tölteni. AComboBox-ba elhelyezhetünk egy (mind) elemet is, melyet kiválasztva az adott mezőre való szűréstkikapcsoljuk. A mind-et azért kell zárójelbe tenni, mert a zárójelet rendezésnél a Windows előre helyezi, ígybiztosak lehetünk abban, hogy ez a felirat az első elemek között lesz (a rendezéshez be kell kapcsolni aComboBox-on az AutoSort-ot). Szűréshez ízlés szerint természetesen használhatunk Edit-et is, de vigyázzunk: haaz Edit OnChange eseményére (ez az esemény akkor hívódik meg, amikor változtatjuk az Edit tartalmát)változtatjuk a szűrőfeltételt, erősen lelassíthatjuk alkalmazásunkat azzal, hogy minden billentyűleütésre hosszasműveleteket végzünk. Használjunk inkább frissítő-gombot.

A mai alkalmazásokban teljesen általánosnak mondható a státuszsorok (5) használata. Mi seódzkodjunk ilyeneket használni, ha másra nem, hát arra, hogy az egérmutató alatt lévő objektumról adunk bennerövid leírást. Ezt úgy tehetjük meg, hogy az objektumok Hint („buborék-súgó”) tulajdonságába egy | jel után egyhosszabb leírást írunk, az Application.OnHint eljárásba pedig megadjuk, hogyStatusBar.SimpleText:=Application.Hint. (Delphi 5-öt használók ezt az TApplicationEvents komponenssegítségével tehetik meg, a régebbi verziókban ezt kézzel kell hozzárendelni az eseményhez úgy, hogy készítünkegy saját eljárást, és egyenlővé tesszük az Application.OnHint értékével. Ld: Delphi Help: Hint, OnHint,

Page 21: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

20

GetLongHint example.) Természetesen a státuszsorba kiírhatjuk az aktuális rekord állapotát, vagy bármi mást,amit a felhasználóval közölni akarunk (a TStatusBar használatáról ld. a Delphi Help: TStatusBar).

A gyorsabb használhatóság érdekében nagy hangsúlyt kell fektetnünk a billentyűkombinációkalkalmazására. Ide nem csak a gombokon lévő aláhúzott karaktereket vehetjük be, hanem használhatjuk afunkcióbillentyűket is. Ebben az esetben az OnKeyDown eseményt használhatjuk.

Egy táblamegjelenítő ablak, szűrőkkel

AdatlapokEgy rekord szerkesztésére legjobb eszköz az adatlap. Itt minden szükséges információ egy helyen van,

de mindig csak az aktuális rekordról kapunk információkat. Adatlapot a legegyszerűbben úgy készíthetünk, hamegnyitjuk a megfelelő tábla FieldsEditor ablakát, kijelöljük a szükséges mezőket, majd egérrel ráhúzzuk az újablakra. A hatás: megjelennek a megfelelő típusú, méretű, megfelelően beállított szerkesztőkomponensek, amegfelelő címkékkel ellátva. Ha ezek mellé kiteszünk egy DBNavigator-t, kész is az adatlapunk. Azigényesebbek persze saját gombokat is használhatnak. Néha célszerű azt a cselt bevetni, hogy az adatlapmegjelenésekor nem szerkeszthető (hiába próbál a felhasználó valamit is módosítani), csak a szerkesztő gombmegnyomása után. Ehhez az adatlaphoz tartozó DataSet AutoEdit tulajdonságát kell false-ra állítanunk.

Ennél nagyobb gondosságra is szükség van azonban, ha egy, a program törzsét képező táblázatadatlapját készítjük. Nem mindegy ugyanis a mezők sorrendje, elhelyezkedése. Ha például az adatlapnak léteziknyomtatott megfelelője is (amit ezen adatlap alapján töltenek ki, vagy fordítva), a számítógépen lévő adatlap jó,ha a papíron lévőnek a pontos mása. De ha nem is áll fenn ilyen helyzet, ismét gondoljunk arra, hogy ezt aprogramot a felhasználóknak írjuk, így az ő kényelmük a legfontosabb. Oda kell figyelni arra, hogy akomponensek sorrendje (Tab Order) megfelelő legyen, azaz a TAB billentyűt nyomogatva milyen sorrendbenlépkedhetünk az adatlapon (ennek beállítása: a form vagy label kijelölése után Edit/Tab Order menüpont).Érdemes továbbá a mezőkhöz gyorsbillentyűket rendelni, hogy minél könnyebb legyen egy adott mezőhözugrani. Ehhez a címkék szerepét betöltő label-ek feliratában (Caption) az & jellel meg kell jelölni a megfelelőbetűket (Az & jel utáni karaktert a Windows automatikusan aláhúzza), majd a FocusControl nevűtulajdonságukban be kell állítani a hozzárendelt mezőt. Ha ezt megtettük, a felhasználó az aláhúzott betű ALTbillentyűvel együtt történő lenyomásával a FocusControl-ban megadott mezőbe tud ugrani, és azt szerkeszteni.

A lookup mezőkre általában DBLookupComboBox-okat szokás használni az adatlapokon. Ennek az ahátránya, hogy csak a listában szereplő elemek közül választhatunk. Ez persze egyértelműen következik a lookupmező működéséből – mondhatnánk. De a felhasználó nem tudja, mi az a lookup. Ez nem is róható föl ellene.Inkább a fejlesztőnek kell megoldania, hogy ha nem szerepel egy elem a listában (törzsadattáblában), amire éppszükség lenne, akkor valamilyen módon fel lehessen venni úgy, hogy ne kelljen az adatlapot elhagyni. Alegegyszerűbb, ha a lookupcombobox mellé helyezünk egy nyomógombot, amellyel elérhető az adotttörzsadattábla ablaka, ahol módosíthatjuk a tartalmát. Másik megoldás, ha egy új elemet létrehozó gombothelyezünk ki, amely egy üres adatlapot jelenít meg. Ezt kitöltve a program fölveszi az elemet a törzsadattáblába,majd azt beírja a lookup mezőbe.

Az adatlapok készítésekor gondolnunk kell arra, hogy minél automatikusabban működjenek. Egyrésztlétezhetnek alapértékei az egyes mezőknek (pl. dátum esetén az aktuális dátum), másrészt előfordulhat, hogy egymező értékéből lehet következtetni egy másik mező értékére is. Jó példa erre, hogy ha egy megrendelő adatlapona partner kiválasztása után, ha annak van bankszámlaszáma, a fizetésmódnál a banki átutalást, ha pedig nincs,akkor a készpénzfizetést jelöli ki a program. Az ehhez hasonló módszerek hosszútávon jól beváltják a hozzájukfűzött reményeket.

Egy igen hasznos és egyben látványos megoldás a „színváltós” mezőobjektumok használata. Ez aztjelenti, hogy a mezők színe az állapotuktól függ: más színe van, ha szerkeszthető, ha csak olvasható; de ami alegfontosabb: más színe van, ha aktív (benne van a kurzor). Ez egy nagyon látványos, de legalább annyirahasznos lehetőség, amit a Delphi komponensek írói még nem fedeztek fel, de már jó pár alkalmazásban lehet

Page 22: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

21

találkozni vele. Ha valaki ilyet szeretne használni a programjában, két dolgot tehet: vagy ír egy sajátkomponenst, ami tudja ezt a lehetőséget, vagy pedig a programon belül kezeli le ezt a problémát. Az elsőmegoldás kicsit bonyolultnak tűnik, de csak egyszer kell megtenni. A másodikat egyszerűbb, de minden egyesprogramba külön bele kell építeni. Ha komponenst írunk, először tanulmányozzuk át a Delphi Help megfelelőfejezeteit (Creating a new component), csak aztán fogjunk bele. Ha ez már meg van, arra kell figyelni, hogy aszínváltást nem az onEnter, illetve onExit eljárásokba, hanem a

procedure CMEnter(var Message: TCMGotFocus); message CM_ENTER;

illetve a

procedure CMExit(var Message: TCMLostFocus); message CM_EXIT;

deklarációjú eljárásokba kell foglalni.Abban az esetben viszont, ha programon belül oldjuk meg, nem kell mást tenni, mint hogy a megfelelő

objektumok onEnter és onExit eseményében megadni a megfelelő színeket. Egy eseménykezelő persze egyszerretöbb objektumhoz is tartozhat, ekkor viszont célszerű a következőképpen megadni a színeket:

(Sender as TControl).Color:=SajatSzin;

Sorolhatnám még azon lehetőségeket, amelyekkel szebbé és használhatóbbá tehető egy alkalmazás.Minden csak a fejlesztő fantáziáján és ötletességén múlik.

Egy adatlap, „színváltós” beviteli mezőkkelFigyeljük meg, hogy a kapcsolódó táblákba (hirdető neve, szervező neve) közvetlenül vehetünk fel új rekordot az„Új hirdető”, ill. az „Új szervező” feliratú gombokkal. További érdekesség, hogy a reklám szövegét formázni is

lehet (RTF).

Műveletvégző ablakokEbbe a kategóriába sorolom azokat a párbeszédablakokat, amelyek nem egyszerű adatbázis-

manipulációt, hanem valamilyen összetettebb műveletet végeznek. Ezeket azért kell elkülönítenünk, mertfelépítésükben, működésükben teljesen másak, mint mondjuk az adatlapok. Ezeket az ablakokat általában arrakészítjük fel, hogy valamilyen (általában meghatározott) felhasználói műveletsorozatra valamilyenmeghatározott adatbázis-műveletsorozatot hajtson végre. Itt ne egy új név felvételére gondoljunk egytelefonkönyv-program keretein belül, hanem például egy éttermi rendszer fizetés-moduljára, ahol egy számláhoztöbb asztal, tetszés szerinti rendelései tartozhatnak.

Az ilyen feladatok elvégzésére három módszer kínálkozik. Az első, amikor egy ablakra rakjuk ki azösszes szükséges objektumot, melyekkel elvégezhető a műveletsor. Itt figyelni kell az átláthatóságra, és arra,hogy ne legyen az ablak zsúfolt. Ha nem elég nagy az ablak, és nem fér el rajta minden, akkor jöhet szóba amásodik lehetőség, az egymás után felbukkanó ablakok használata. Ezeknél fontos, hogy mindegyiken legyen

Page 23: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

22

visszalépési lehetőség (Mégsem gomb). A harmadik módszer a legszebb, és manapság egyre nagyobb teret hódítmagának: a varázsló. Ennek persze csak akkor van értelme, ha szabadon oda-vissza lépkedhetünk benne, illetvebármikor kiléphetünk belőle. Nagyon fontos, hogy kerüljük a felesleges szövegeket és oldalakat (üdvözlő oldal,elköszönő oldal, stb., ld. legtöbb Microsoft varázsló), csak a lényegre figyeljünk. Jó, ha minden oldalon vanvalamilyen alapértelmezett beállítás (lehet ez az előző alkalommal használt érték), mert így még könnyebbenvégig lehet menni a varázslón. A Delphi sajnos varázsló komponenset nem tartalmaz, de nagyon egyszerűenkészíthetünk magunknak egyet a TNotebook (Win 3.1 fül) segítségével, amely több lapból áll, és lapjaira bármitföltehetünk.

Rendelés az éttermi rendszerrel (műveletvégző ablak): a típusokra egyszer kattintva kiválaszthatjuk a baloldalonmegjelenítendő tételeket, azokra egyszer kattintva pedig felvehetjük a rendelésbe őket.

KimutatásokAz adatbázis-kezelő programok fontos részét képezik a kimutatások. Ezek alatt általában valamilyen

szempontból csoportosított, valamilyen szűrővel ellátott, valamilyen rendezési elvet követő adatmegjelenítéstértünk. A feladat bonyolultságától függ, hogy egy kimutatásnak hogyan kell kinéznie, mit kell megmutatnia. Aza jó kimutatás, amellyel minél több szempontból lehet adatokat csoportosítani. Kimutatások készítésénél szinteelkerülhetetlen az SQL-lekérdezések (Select-ek) használata. A lekérdezésekkel természetesen lehet számítottadatokat is megjeleníteni, összevonni, stb. (bővebbeket a Local SQL Guide-ban).

Az SQL-lekérdezéseket használó kimutatások fontos jellemzője, hogy menet közben nem tudunkváltoztatni a feltételeken (kivéve a szűrőket), csak ha újrafuttatjuk a lekérdezést. Ezért célszerű a feltételeket akimutatás megjelenítése előtt bekérni a felhasználótól, majd lefuttatni az SQL-eket, és aztán megjeleníteni azokeredményeit. Ezek után sem szabad azonban elfeledkezni a feltételekről: érdemes azokat kijelezni a kimutatás-ablakban is. A kimutatás-ablak szerkezete tetszőleges lehet, de ha egyszerre több táblázatot jelenítünk meg, aztmindenképpen érdemes egy TPageControl megfelelően feliratozott lapjaira helyezni, hogy minél áttekinthetőbblegyen.

Gyakran használunk kapcsolt táblákat, amikor egy adat törzse egy táblában, az egyéb adatai (amelybőltöbb rekord is lehet) pedig egy másik táblában szerepelnek. Ekkor a legszebb megoldás, ha mindkét táblázatotmegjelenítjük, de úgy, hogy az egyik táblában egyszerre csak egy, a másik táblában kiválasztott elem részleteijelenjenek meg. Ezt pedig a legegyszerűbben úgy tehetjük meg, ha az egyik tábla MasterSource-át ésMasterFields-ét a másik táblának megfelelő DataSource-ra, illetve mezőjére állítjuk.

Ha pl. van két táblánk:TableNevek(személykód, név) (DataSourceNevek)TableLakas(személykód, lakhely) (DataSourceLakas)(Egy személyhez több lakhely is tartozhat.)Ekkor a következőket kell tennünk:

Page 24: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

23

TableLakas.MasterSource:=DataSourceNevek;TableLakas.IndexFields:=’személykód’;TableLakas.MasterFields:=’személykód’;

Példa a kimutatásra: zárás az Étterem programmal

Folyamatkijelzők (ProgressBar-ok)Előfordulhat, hogy a programunk olyan műveleteket végez, amelyek viszonylag időigényesek. Ekkor

nem túl jó, ha ezt csupán egy homokórás egérkurzorral jelezzük (ezt egyébként az Application.CursorcrHourGlass értékre állításával tehetjük meg), hanem folyamatkijelzőket (ProgressBar-okat) használunk. Így afelhasználó meg tudja ítélni, hogy mennyi van még hátra, és az is nyilvánvalóvá válik számára, hogy a programnem fagyott le, hanem dolgozik.

Erre a feladatra természetesen a TProgressBar komponens használható. A dolog egyszerű:megszámoljuk hány műveletet végzünk, és azt megadjuk a ProgressBar-nak (Max). Ezután minden műveletetkövetően léptetjük (StepIt). Ha tudjuk, hogy a műveletek nem lesznek folyamatosak (a műveletek végrehajtásiideje között nagyok a különbségek), célszerű a Smooth értéket kikapcsolva hagyni, így nem olyan feltűnő.Kalkulálhatunk azzal is, hogy egy hosszabb művelet után esetleg többet léptetünk egyszerre. Ami nagyon fontos,hogy mindenképpen legyen valóság alapja a folyamatkijelzőnknek. Ha tehetjük, célszerű szövegesen is közölni,hogy éppen mit csinál a program (ez hibakeresésnél is jól jöhet).

Mindez azonban semmit nem ér, ha nem jelenik meg. Normális esetben ugyanis a Windows nemdolgozza fel a komponenseknek küldött üzeneteket, miközben mi egy eljáráson belül műveleteket végzünk. Eztnekünk kell megtenni, az Application.ProcessMessages segítségével (ezt minden StepIt után be kell írnunk).Ezzel megoldódik a probléma. Természetesen máshol is alkalmazhatjuk a ProcessMessages metódust, aholzavaró, hogy sokáig nem frissülnek az ablakok.

Nyomtatás, riportGyakran van arra szükség, hogy amit az adatbázisunkban (vagy esetleg SQL lekérdezésünkben)

tárolunk, papíron is megjelenítsük. Erre a Delphi is lehetőséget nyújt a QuickReport komponenscsomagsegítségével (QReport fül). Az új riportot elhelyezhetjük a form-on, de létrehozhatjuk önálló ablakként is(File/New/Report). Használata nagyon egyszerű: beállításait a jobb egérgombbal elérhető menüből és az ObjectInspector segítségével tehetjük meg. A riportra ezek után rápakolhatjuk a megfelelő komponenseket a QReporteszköztárból. Használatukat a mellékelt példaprogramok segítségével könnyen megérthetjük (a Delphikönyvtárán belül a Demos/Quickrpt könyvtárban találjuk őket). A lényege az, hogy Band-eket kell elhelyeznünk,

Page 25: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

24

amelyeknek különböző típusai lehetnek (BandType tulajdonság), majd ezekben helyezzük el az adatokatmegjelenítő komponenseket (pl. QRDBText). A komponenseket széleskörűen konfigurálhatjuk, kényünk-kedvünk szerint.

Programunkon belül a QuickReport Preview metódusát meghívva nyomtatási képet mutathatunk meg.Ezt célszerű alkalmazni, mert a felhasználók szeretik látni, mi fog a nyomtatott papírra kerülni. A Preview ablakhasználata egyszerű, de célszerű magyarítani a Delphi könyvtárán belül a Lib/qrprev.dfm fájl megnyitásával ésátírásával.

Egy QuickReport-tal készített nyomtatási kép

ProjectHa már mindennel kész vagyunk, nem árt, ha végignézzük a Project beállításait (Project/Options). A

Forms lapon beállíthatjuk, hogy melyik form legyen az alkalmazásunk fő formja (Main Form), valamint hogymely formokat hozza létre automatikusan a program (amelyeket futásidőben, kézzel kívánunk létrehozni, azokattöröljük a listából). Az Application lapon megadhatjuk, mi legyen a program neve (Application.Title, ez jelenikmeg a tálcán) és hogy mi legyen az ikonja (Application.Icon). Bármennyire is lényegtelennek tűnik, nagyhangsúlyt kell fektetnünk az alkalmazás ikonjának kiválasztására. A felhasználók ugyanis az alapján azonosítjáka programunkat, így annak utalnia kell funkciójára, vagy mindenképpen egyedinek, az általában használatosikonoktól eltérőnek kell lennie. A Compiler oldalon a fordítóra vonatkozó beállításokat tehetjük meg. Végsőfordítás esetén (ha már teljesen kész vagyunk a programmal, és nem óhajtunk több hibakeresést végezni)célszerű a Runtime errors és a Debugging panelen mindent kikapcsolni, ezzel is csökkentve a programerőforrásigényét. Hasonló okokból érdemes bekapcsolni a Code generation-ban az Optimization-t. Még egy fülvan, ami érdekes számunkra, ez pedig a Version info. Itt a programnak azon tulajdonságait állíthatjuk be,amelyeket a Windowsban, az exe tulajdonság-lapján is megtekinthetünk. A mezőket kitöltve megadjuk averziószámot (a Build szám automatikus növelésére is van lehetőségünk), a szerzőt, a tulajdonost, stb.

Ha már ezeken is túl vagyunk, jöhet az utolsó Build, majd a használat. Sok sikert!

Page 26: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

25

V. Egyéb problémák

HibakezelésEbben a részben a hibák kezelésének alapjaival ismerkedünk meg, hogy itt szerzett tudásunkat

felhasználhassuk az adatbázis-kezelő rendszerek készítése során, hiszen egy adatbázis kezelése során rengeteghibalehetőség van, sokuk független attól, hogy a programot hogy írtuk meg.

A Windows a hibakezelést ún. exception-ökkel oldja meg. (Az exception jelentése: kifogás, kivétel,kivételes esemény, megszakítás. A magyar nyelvű Windows-okban kivételnek fordítják, holott a kivételesesemény, vagy a megszakítás jobban illene rá.) Kivétel akkor jön létre, ha egy hiba, vagy egyéb eseménymegszakítja a program normál futását. A kivétel az irányítást egy kivétel-kezelőnek (exception handler) adja át,ami lehetőséget ad arra, hogy elkülönítsük a program normál futását a hibakezeléstől. A kivétel információt (amiáltalában egy hibaüzenet) tud átvinni attól a ponttól, ahol előidézték, addig a pontig, ahol lekezelik. Ha egyalkalmazás használja a SysUtils unitot, minden futtatási hiba (runtime error) automatikusan kivétellékonvertálódik. Olyan hibák, amelyek más esetben megszakítanák a program futását – mint pl. kevés memória,nullával való osztás, általános védelmi hiba – elfoghatók és kezelhetők. A kivételek is objektumok, ígyhasználatuk könnyen elsajátítható. (Delphi Help: Exceptions: Owerview)

Saját magunk is létrehozhatunk ilyen kivételeket, a raise kulcsszó segítségével. A legegyszerűbben akövetkező példa alapján járhatunk el:

raise EMathError.Create(‘Hiba történt! Kutykurutty!’);

A hibák kezelése sem sokkal bonyolultabb ennél. A legegyszerűbb, ha a problémás műveleteket ún. try-blokkba tesszük. Ez a következőképpen néz ki:

TryX := Y/Z;

excepton EZeroDivide do HandleZeroDivide;

end;

Az on után a hiba típusát (pontosabban a kivétel osztályának nevét) írjuk, a do után pedig meghívhatjuka kezelő eljárásunkat.

Ha azt szeretnénk, hogy a kritikus művelet után mindenképpen végrehajtódjanak bizonyos műveletek,és csak azután keletkezzen kivétel, használhatjuk a try..finally szerkezetet is:

Reset(F);try{...} // fájlműveletek az F fájllal

finallyCloseFile(F);

end;

A hibakezelésnek van még egy fontos része, ez pedig a komponensek hibaeseményei. Nevük általában akövetkezőképpen néz ki: On*Error. Nevük utal mivoltukra, pl. a TTable OnDeleteError eseménye akkorkeletkezik, ha egy adat törlése meghiúsult. Ezek használatával rengeteg hibalehetőséget kiszűrhetünk,kezelhetünk. Ehhez jól kell tudnunk használni az Exit, az Abort, ill. a Halt eljárásokat.

Az Exit kilép az aktuális eljárásból. Ha a főprogramban van, a program kilép, ha egy meghívotteljárásban van, visszaadja a vezérlést arra a pontra, ahol az eljárást meghívtuk. Akkor használjuk, ha olyan esetáll fenn, amely mellett az eljárás nem folytatható.

Az Abort megszakítja az aktuális folyamatot anélkül, hogy hibát generálna. Használatát a következőpélda jól mutatja:

procedure TForm1.Table1BeforePost(DataSet: TDataSet);beginif DBEdit1.Text = '' thenAbort;

end;

Tehát a Table1 tábla mentés (Post) előtt meghívott eseményében (BeforePost) megnézzük, hogy üresenhagyta-e a felhasználó a DBEdit1 által reprezentált mezőt. Ha igen, az abort-tal megszakítjuk a műveletet, és ígynem engedélyezzük a mentést.

A Halt azonnal megállítja a program futását, és a paraméterként megadott hibakóddal kilép. Csak akkorhasználjuk, ha a program futtatása egyáltalán nem folytatható.

A fentiek ismeretében nyugodtan elkezdhetünk hibaelhárító, kezelő programrészeket írni.

Page 27: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

26

Hálózat használata Paradox rendszerrelGyakori feladat, hogy egy PARADOX adatbázist több számítógépről szeretnénk egyszerre használni.

Ehhez azonban még nem feltétlenül szükséges kliens-szerver alkalmazást készíteni, ha jól dolgozik az ember,megfelelő platform erre a PARADOX is. Úgy kell tehát megtervezni az alkalmazásunkat, hogy ne okozzon nekigondot, ha vele egy időben egy másik program is dolgozik az adatbázisán. A probléma látszólag ugyanaz, mintamikor egy számítógépen egyszerre futó több program éri el ugyanazt az adatbázis. Az erre való felkészítésazonban nem elég. Az adatbázis ugyanis másként viselkedik, ha a programok nem egyazon számítógépen futnak.

Elsőnek arra kell figyelnünk, hogy ha egy program szerkesztésre megnyitott egy adatot, azt egy másikprogram csak olvasásra tudja megnyitni. Ezért le kell kezelnünk azt az esetet, amikor a másik program ismegpróbálja szerkeszteni azt. Ennek a legegyszerűbb módja, ha a táblák OnEditError eseményébe beírjuk akövetkezőt: E.Message:= 'Nem sikerült megnyitni az adatot. Lehet, hogy egy másik felhasználó épp szerkeszti.';.Ezzel azt érjük el, hogy hiba esetén a Delphi ezt az üzenetet fogja kiírni. A többivel nem kell foglalkoznunk,hiszen a Delphi automatikusan megszakítja a hibát okozó folyamatot.

Gyakori eset, hogy egy adatbázisban egy egyed azonosítására egy számértéket (kódot) használunk, amitminden egyes új egyed felvételekor eggyel növelünk. Ez a növelés pedig úgy történik, hogy az új egyed a kódjátúgy kapja meg, hogy a legnagyobb kódhoz hozzáadunk egyet. Ekkor azonban előfordulhat az, hogy két programegyszerre hoz létre egy-egy új egyedet (vagy az egyik megnyitja, de még nem menti, amikor a másik ismegnyitja). Így mindkét program azonos kóddal szeretné elmenteni az adatot, ami nem túl szerencsés (és nem islehet, ha ez a kód az egyedüli elsődleges kulcs). Az ehhez hasonló esetek megoldására az tűnik megfelelőnek,hogy mihelyst létrehozzuk az új egyedet, megkapja a megfelelő kulcsot (kódot), és rögvest mentjük is, majd újramegnyitjuk szerkesztésre. Így a felhasználó vagy a program korlátlan ideig „gondolkodhat” az adatok kitöltésén,az egyed helye biztosított az adatbázisban.

Fontos kérdés hálózat használata esetén a frissítés megvalósítása. Minden művelet előtt frissíteni, aműveleteket követően pedig rögzíteni kell az adatokat. A programok ugyanis nem veszik „maguktól” észre aváltozásokat, amiket egy másik program okozott. Ezért célszerű a táblák Refresh metódusát használni, mielőttvalamilyen műveletbe kezdünk. Mivel a BDE az adatokat a memóriában (bufferekben) tárolja, azok nem íródnakki rögtön a merevlemezre, így a változásokat csak az adott számítógépen futó programok érzékelhetik (mivelegyszerre csak egy BDE futhat, és az szolgálja ki az összes BDE-programot). Gondolnunk kell tehát arra, hogyegy esetleges meghibásodás vagy áramkimaradás esetén, továbbá ha egy másik számítógép szeretné az aktuálisadatokat lekérdezni, ez az elv nem követhető. Ezért minden művelet elvégzése után érdemes a bufferek tartalmáta merevlemezre írni a FlushBuffers metódus segítségével, ha pedig CacheUpdate módot használunk, azApplyUpdates-el (a CacheUpdate üzemmódról a TTable-nél volt szó, a IV. fejzetben).

Ezeket betartani azonban még mindig csak fél siker. Ahhoz, hogy egyszerre több számítógépen futóprogramok (pontosabban BDE-k) megfelelő módon kezelhessék az adatállományokat, a BDE megfelelőbeállításait is el kell végezni. A BDE ugyanis az adatbázis megnyitásakor annak könyvtárában ún. lock-fájlokat(paradox táblák használata esetén ez a paradox.lck és a pdoxusrs.lck) helyez el. Ezekben tárolja azt, hogy melytábláknak mely rekordjait nyitották meg szerkesztésre, így azokhoz csak olvasási hozzáférést enged. Ahhozviszont, hogy egyszerre több program (BDE) a hálózaton keresztül elérje ezt az adatbázist, össze kell hangolniőket. Erre szolgál a pdoxusrs.net fájl, amit a BDE a neki beállított NET DIR változó értékének megfelelő helyrehelyez el, illetve ott keresi. Ezért fontos, hogy az összes BDE egy helyen (a hálózat egyik megosztottkönyvtárában) keresse ezt a fájlt. Tehát minden számítógépen megfelelően kell beállítani a BDE Administrtatorprogramban a Configuration/Drivers/Native/Paradox elem NET DIR paraméterét (azon a gépen, ahol az adatokvannak, a C:\-t érdemes beállítani, a többi gépen pedig értelemszerűen ezt a könyvtárat képviselő hálózatimegosztás nevét). Ha a beállítások nem helyesek, a program leállhat azzal, hogy az adatbázist valaki máshasználja.

Ha már a BDE beállításainál tartunk, ismét megemlítem, hogy a sikeres hálózati működés érdekében aConfiguration/System/INIT/LOCAL SHARE változót TRUE-ra kell állítani, különben az adatokat nem tudjákfrissíteni a hálózaton keresztül az alkalmazások.

Ha olyan programot írunk, amely hálózaton, több példányban működik, gondolnunk kell arra, hogybizonyos műveletek kizárólagos megnyitást követelnek maguknak (ilyen pl. a tábla ürítése, az EmptyTable), azazekkor csak egy példányban futhat a programunk. A legjobb és legegyszerűbb az, hogy a művelet elvégzése előttközöljük a felhasználóval, hogy zárja be a többi alkalmazást. Ha pedig mégis hiba lép föl, még egyszerfigyelmeztetjük erről.

A fentiekből látszik, hogy a Paradox rendszereket nem arra találták ki, hogy egyszerre több százprogram férjen hozzá egy adatbázishoz. Néhány program viszont tökéletesen működik hálózatban, ha betartjuk aszabályokat. A tapasztalatom azt mutatja, hogy megfelelő odafigyeléssel ezeket a hibalehetőségeket ki lehetiktatni, és végeredményben egy jól használható alkalmazást kapunk.

Page 28: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

27

Biztonsági problémákElőfordulhat, hogy az adatbázis megsérül. Mit kell, mit lehet ilyenkor tenni? Milyen kilátásaink vannak,

hogyan háríthatjuk el a hibát, és hogyan előzhetjük meg? Ezek a kérdések minden fejlesztőt foglalkoztatnak.Ebben a részben megoldást keresünk rájuk.

Biztonsági mentésA károk megelőzésének legegyszerűbb módja, ha biztonsági másolatot készítünk adatainkról.

Egyszerűbb fájlsérüléseket kivédhetünk azzal, hogy az adott merevlemezre másoljuk le az adatokat. Biztosraazonban csak akkor mehetünk, ha ezt egy másik adathordozóra tesszük meg (történhetnek ugyanis olyan károk,amelyek a merevlemez adatainak teljes elvesztésével járnak együtt).

Biztonsági másolat készítésére rengeteg módszer kínálkozik. Először is el kell döntenünk, hogy erről mimagunk kívánunk gondoskodni, vagy rábízzuk a felhasználóra. Ha nem akarjuk a felhasználókat ilyenekkelterhelni, érdemes a programunkba épített automatizmussal megoldani. Persze az is megoldás, ha különprogramot készítünk erre a célra, amit a Windows Feladatütemezőjével adott időszakonként futtatunk. Ehhezazonban már ismerni kell a Feladatütemező vezérlését, vagy a telepítés során kézzel be kell konfigurálni. Ha afelhasználóra bízzuk a dolgot, beépíthetjük a programunk karbantartó moduljába, vagy írhatunk rá különprogramot, amelynek parancsikonjára kattintva automatikusan lefut. A legrosszabb megoldás, ha nem teszünksemmit, hanem a felhasználóra bízzuk, hogy készítsen kézzel (valamilyen fájlkezelővel, Intézővel) másolatot azadatbázis fájljairól. Ez ugyan nem valami felhasználóbarát, de ha tudjuk, hogy a felhasználó képes erre, mindentovábbi nélkül építhetünk rá.

A biztonsági mentés kétféle lehet. Vagy mindig ugyanazokat a fájlokat írjuk felül az aktuálisadatbázissal, vagy minden alkalommal egy külön dátummal ellátott könyvtárba másoljuk azokat, lehetővé téve,hogy egyszerre több biztonsági másolat is elérhető legyen. Arra kell ekkor figyelmet fordítanunk, hogy sokbiztonsági mentés mérete már elég jelentős lehet, és nem túl szerencsés ezzel terhelni a háttértárakat. Meg kelltehát oldanunk az elavult biztonsági mentések törlését is.

Ami nagyon fontos: nem nekünk érdekünk az adatok biztonságos tárolása és mentése, hanem afelhasználónak.

Ha már megoldottuk a biztonsági másolat készítését, már csak a visszatöltéssel kell törődnünk. Amásolatot ugyanis azért készítjük, hogy probléma esetén könnyen vissza lehessen tölteni azt az eredetiadatfájlokat felülírva.

A feladat programozása nem bonyolult, mindössze az adatbázis fájljait kell másolgatni a CopyFile(windows unit) függvény segítségével. A dolog jelentősége ott van, hogy gondoltunk rá, és nem a felhasználónakkell ezzel törődnie.

Azt, hogy milyen időközönként mentünk, attól tegyük függővé, hogy mennyire gyakran változik azadatbázis, és ezek a változások mennyire rekonstruálhatók.

Adatsérülések kezeléseAz adatsérülés általában úgy mutatkozik meg, hogy program indításakor, vagy futásakor valamilyen

hibaüzenetet kapunk a BDE-től, amelyben hibás adatfájlokról, megnyithatatlan táblákról tájékoztat minket. Azesetek többségében a hiba javítható, mivel nem a táblák, csak a hozzájuk tartozó járulékos fájlok sérülnek.Ezeket a sérüléseket általában a program futásának váratlan megszakadása okozza, amely történhet a mihibánkból, de lehet a Windows hibája is. Hálózati használat esetén egy váratlan kapcsolatszakadás (érintkezésihiba, stb.) is okozhat ilyen hibát, ugyanúgy, mint az áramszünet.

Hogy jobban lássuk a helyzetet, tisztázzuk, milyen fájlok tartoznak egy Paradox alapú adattáblához. Azelső a .db fájl, ami maga a tábla. Ha ez sérül, nem tudunk igazán mit kezdeni vele, a biztonsági mentéshez kellnyúlnunk.

A többi, egy táblához tartozó fájlnak a pont előtti neve megegyezik a .db fájl pont előtti nevével.Ha használjuk a tábla Validity Checks (érvényesség vizsgálat) lehetőségét, automatikusan létrejön egy

.VAL fájl, ami ezeket a beállításokat tárolja. Ha ez sérül meg, a 12036 kódú, .VAL file is out of date (.VAL fájlelavult) hibaüzenetet kapjuk, mikor megpróbáljuk megnyitni az adatállományt. Ezt úgy tudjuk kivédeni, haletöröljük. Ekkor azonban elvesztjük az imént említett lehetőségeket, így inkább újra kell gyártanunk ezt a fájlt(hogy hogyan, azt majd a későbbiekben tisztázzuk).

Az elsődleges indexszel kapcsolatos információk a .PX fájlban tárolódnak. A többi, másodlagos index-információk a .GX? és a .GY? fájlokban vannak (a ? helyén szám, illetve betű található, attól függően, hogyhányadik az index). Ha ezek közül sérül valamelyik, a 8961-es kódú Corrupt table/index header (hibástábla/index fejléc) hibaüzenetet kapjuk. Ezen a problémán a tábla újraindexelésével lehet segíteni (ha nemállítunk be indexet a táblának, hibás index-állományokkal is megnyithatjuk).

Ahhoz, hogy az imént felsorolt hibákat ki tudjuk javítani, szükségünk van a táblák definícióira. Ezértazokat el kell tárolnunk a hibajavító programban. Ezt nagyon egyszerűen úgy tehetjük meg, hogy létrehozzuk amegfelelő táblákat (TTable), majd jobb egérgombbal kattintva, az Update Table Definition menüpontsegítségével beállítjuk a meződeklarációkat (amiket a tábla a FieldDefs tulajdonságában tárol) és az

Page 29: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

28

indexdeklarációkat (ezek az IndexDefs-ben vannak). Ha mindezt elvégeztük, a Table-ök már ismerik a tábláinkstruktúráját, definícióját. Így már bármikor létrehozhatunk egy ennek megfelelő, üres táblát, a CreateTablemetódus segítségével. Ezt a lehetőséget használhatjuk fel a sérült fájlok javítására, a következőképpen: hasérültnek találunk egy állományt (a .db fájl kivételével), letöröljük, majd egy SQL lekérdezésben megnyitjuk atáblát (a SELECT * FROM tábla.db lekérdezést használva), és meghívjuk a táblához tartozó Table CreateTablemetódusát. Ezzel létrejött egy új, üres tábla, amelynek struktúrája hibátlan, a tábla előző adatait pedigátmenetileg a Query-ben tároljuk. A következő lépés az adatok átmásolása a Query-ből a Table-be. Ezt akorábban szintén bemutatott TBatchMove segítségével végezhetjük el. Ha ezek után sem tudjuk megnyitni atáblát, sajnos nem tudunk rajta segíteni.

A tábláknak vannak olyan tulajdonságai is, amelyeket nem tudunk a TTable-ben eltárolni, és ezáltal aCreateTable metódussal létrehozott tábla sem tartalmazza. A leggyakoribb ilyen tulajdonság, amiveltalálkozunk, a jelszó. Ezért ezt magunknak kell megadni, a tábla létrehozása után. A dolog abból a szempontbólnem egyszerű, hogy nincs meg a megfelelő eljárás, amivel egy táblának jelszót állíthatnánk be. Némi keresgetésután azonban találunk egy példát, méghozzá a Borland Database Engine Online Reference-ben (megtalálható aStart menüben is, a Delphi-n belül a Help/Borland Database Engine menüben, valamit a BDE könyvtárában).Ha ebben az állományban rákeresünk az AddMasterPassword szóra, és a kiadott találatot megnyitva az oldalExample 4: Add a master password to a Paradox table alcímet viselő részből az eljárást kimásoljuk, máris vanegy saját jelszóhozzáadó rutinunk (ami egyébként a DbiDoRestructure nevű BDE API függvényt használja).

Sokszor nem elég az adatokat fizikailag ellenőrizni. Hibás működés esetén ugyanis előfordulhatnakkitöltetlen mezők, amik rengeteg bosszúságot okozhatnak. Érdemes tehát a táblák tartalmát is ellenőrizni, éslehetőség szerint a kellő helyen beavatkozni. Hogy be lehet-e avatkozni, és ha igen, milyen módon, azt a konkrétfeladat illetve adatbázis határozza meg, ezért részletekbe nem bocsátkozunk.

Egy szoftver fejlesztése során gondolnunk kell arra is, szükséges-e naplózni a műveleteket, és ha igen,ezt milyen módon oldjuk meg. A naplózás azért tölt be fontos szerepet egy szoftver működésében, mertsegítségével könnyen visszakereshetők a műveletek, és könnyebben megy a hibakeresés is (főleg ha a hiba egyegyszerű felhasználó „keze alatt” keletkezett, aki még a hibajelenséget, illetve a hibaüzenetet sem tudjafelidézni). A naplózás legegyszerűbb módja, ha minden eseményt beírunk egy naplófájlba, dátummal, idővelellátva. Használhatjuk például a TListBox-ot, melybe a Lines.Add metódussal beszúrhatunk egy sort, aLines.SaveToFile-lal pedig egyszerűen kimenthetjük tartalmát a paraméterben megadott fájlba.

A várt adatforgalomtól függően óránként, esetleg naponta megnyitunk egy újabb naplófájlt, és abbafolytatjuk a naplózást. Ha a fájljainknak txt kiterjesztést adunk, a Jegyzettömbbel könnyen megjeleníthetőeklesznek. Ügyelnünk kell azonban arra, hogy az elavult naplófájlokat néha törölni kell, mert az egy könyvtárbantárolható fájlok száma a legtöbb Windows-os rendszerben véges (bármilyen kicsik is ezek a fájlok).

A biztonság kérdése nagyon fontos egy programnál, főleg ha azt valaki üzemszerűen használja, ésfontos adatokat tárol és kezel segítségével. A biztonsági intézkedések hosszútávon jelentenek előnyt, és beváltjáka hozzájuk fűzött reményeket. Ezen védelmi mechanizmusok ellenére azonban nem engedhetjük megmagunknak azt a luxust, hogy kevésbé törődjünk a rendszerünk egyéb részeinek helyes, biztonságosműködésével, hiszen ezeket a biztonsági intézkedéseket a program által okozott hibáknál nem igazán tudjukkihasználni.

Telepítő készítéseHa egy általunk készített programot felhasználás céljából más kezébe adjuk, gondoskodnunk kell egy

telepítőprogramról. Ez főleg igaz azokra a programokra, amelyek használják a Borland Database Engine-t,mivel azt a számítógépekre külön telepíteni kell (persze ezt megtehetjük a Delphi telepítő CD-jéről is, de az nemaz igazi). A Delphi programcsomag tartalmaz egy InstallShield Express nevű programot, amellyel könnyen ésgyorsan készíthetünk komplett telepítőkészletet. Előnye a többi, Interneten fellelhető ingyenes vagy olcsóbbtelepítő-készítőkkel szemben, hogy kifejezetten Delphi-hez készült, így támogatja a BDE-t. A program nemtartozik közvetlenül a Delphi-hez, a Delphi telepítő CD-jéről, mint önálló programot tehetjük fölszámítógépünkre.

A programban, ha új telepítőt készítünk, először meg kell adnunk annak nevét és helyét. Ha testreszabható telepítőt (Custom Setup) szeretnénk készíteni, jelöljük be az Include a custom setup typejelölőnégyzetet. A Create gomb megnyomása után megjelenő Setup Checklist-ben különböző opciókat találunk.Ezeken egyenként végig kell mennünk. A teljesség igénye nélkül most végignézzük a lehetőségeket.

Set the Visual DesignAz App Info lapon a program általános jellemzőit adhatjuk meg. Itt kell kiválasztanunk, melyik fájl a

programunk futtatható állománya (Application Executable). A Main Widow-ban a telepítő hátterét, a Features-ben pedig az automatikus Uninstall-t kapcsolhatjuk be.

Specify InstallShield Objects for DelphiEbben a csoportban állíthatjuk be, milyen Delphi komponenseket telepítsen az általunk készített

telepítő. Számunkra a BDE a legfontosabb. Ezt meg is találjuk a General fülön belül. Kiválasztva egy beállítóvarázsló jelenik meg. Első lépésben a telepítendő BDE komponenseket adhatjuk meg. Ha Full BDE Installation-t választunk, a teljes BDE belekerül a készletbe, de a Partial-lal mi adhatjuk meg ezeket a részeket. Ha Paradox

Page 30: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

29

rendszerben dolgozunk, elég a Paradox Driver-t bejelölni. Ha használunk valami mást is (pl. SQL-t),értelemszerűen azt is be kell jelölnünk. A következő lapon alias-okat hozhatunk létre. Itt célszerű megadni aprogram által használt alias-okat. Ezeknek a tulajdonságait kettővel arrébb be is állíthatjuk. Érdemes még akomponensek közül kiválasztani a BDE Control Panel File-t, melynek segítségével a Vezérlőpultból is elérhetőa BDE Administrator program.

Specify Components and FilesA telepítőben a fájlokat csoportosítjuk. Vannak programfájlok, adatbázisfájlok, súgófájlok, stb.,

melyeket ilyen módon csoportba szervezünk, így telepítéskor könnyen kiválaszthatóak a szükséges részek. AGroups lapon létre kell hoznunk a használni kívánt csoportokat, és azokhoz hozzáadni a megfelelő fájlokat. AComponents-ben megadhatjuk, hogy ezek a csoportok milyen komponenseken belül legyenek, a Setup Types-banpedig azt, hogy mely telepítési típus (Egyéni – Custom, Tipikus – Typical, Minimális – Compact) hogyantartalmazza ezeket a komponenseket.

Select User Interface ComponentsA telepítőnek megmondhatjuk, hogy milyen dialógus-ablakok jelenjenek meg a telepítés folyamán. Itt

helyezhetjük el a felhasználói licenszszerződést (Software Licence Agreement), valamint az „olvass el”dokumentumot (Readme Information), stb.

Specify Folders and IconsItt parancsikonokat hozhatunk létre a programunk különböző fájljairól, amit a telepítő a megadott helyre

létrehoz majd.Ha mindent beállítottunk, a Disk Builder segítségével létrehozhatjuk a telepítőt. Ha kész, nincs más

hátra, mint lemezre másolni.

Az InstallShield

Page 31: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

30

Készítsünk CD-t!Manapság egy telepítőt CD-n illik kiadni. Emellett egyre nagyobb teret hódít az automatikus CD,

amelyet a meghajtóba helyezve elindul egy héjprogram, amivel elindíthatjuk a CD-n lévő telepítőket. Ilyettermészetesen mi is készíthetünk. Egy megfelelő telepítő-indító héjprogram megírása nem jelenthet gondot.Néhány felirat és gomb. De hogyan futtatunk programot? Sajnos a Delphi-ben nincs egyszerű programfuttatórutin, ellenben a Delphi Demos\Doc\Filemanex könyvtárában található egy fmxutils.pas nevű unit, melyet a Binkönyvtárba másolva, a programunk uses-listájába írva használatba is vehetünk. Ebben találunk egy ExecuteFilefüggvényt, amellyel már könnyedén futtathatunk bármit (egyébként használhatnánk a ShellExecute APIfüggvényt is, de ez egyszerűbb). Egy dologra viszont nagyon oda kell figyelni: ha automatikusan indul a CD-nlévő héjprogram, nem biztos, hogy a Windows a CD gyökérkönyvtárából futtatja. Ezért a futtatni kívánt telepítőfájlnevét célszerű a héjprogram fájlnevéből kiszámítani. Kiváló eszköz erre a nulladik paraméter (ParamStr(0)).Ez ugyanis mindig a teljes fájlnév. Ebből az ExtractFilePath függvénnyel kivesszük a könyvtárnevet, ígymegkapjuk a héjprogram könyvárát (a héjprogramot a CD gyökérkönyvtárában érdemes elhelyezni). Ebből márkönnyen megvan a futtatni kívánt telepítő teljes fájlneve.

ExecuteFile(ExtractFilePath(ParamStr(0))+ 'Telepítő\Setup.exe','', ExtractFilePath(ParamStr(0)),0);

Így ez a következő fájlt futtatja (ha a program helye D:\): D:\Telepítő\Setup.exe.Most már csak azt kell megoldani, hogy a héjprogramunk automatikusan induljon. A CD

gyökérkönyvtárában létre kell hozni egy autorun.inf nevű állományt, amelynek a következő sorokat kelltartalmaznia:

[autorun]OPEN=Program.exe

Ha pedig ikont is szeretnénk (amit szintén a CD gyökerében helyezhetünk el):

ICON=Ikon.icovagy használhatjuk a programunk ikonját is:ICON=Program.exe,0

A leírtak alapján már bárki elkezdhet telepítőt készíteni. Egy jó tanács azonban elkél: Mindig próbáld kia telepítőt, mielőtt kiadod a kezedből!

VI. Lezárás

Az adatbázis-kezelő alkalmazások fejlesztésének rögös útján könnyű elbukni. Az ember mindig a sajáttapasztalataiból (és főleg kárából) tanul a legjobban. Nincs olyan könyv vagy kiadvány, ami minden speciálisproblémával foglalkozna. Korunkban viszont egyre inkább a speciális, lokalizált, a felhasználó igényeire szabottrendszerekre van szükség. Az általános szoftverek ideje lejárt. Azokat már megírták mások (többek is). A maiprogramozóknak két lehetőségük van: vagy beolvadnak egy szoftvercégbe, és ott fejlesztik sokadmagukkal akülönböző általánosabbnak mondható alkalmazásokat, vagy egyéni vállalkozásba fognak, és speciális, egyediproblémák megoldására szakosodnak.

Zárásként nem áll szándékomban okoskodni, és elmondani, „miért jó ez a dolgozat” és „milyentanulságai vannak”. Ezt az Olvasóra bízom. Én csupán azt remélem, sikerült átadnom azt, amit szerettem volna.Remélem dolgozatom elérte célját, és a Kedves Olvasó talált benne olyat, ami a hasznára vált.

Köszönöm.

Page 32: Adatbázis-kezelő rendszerek fejlesztése Delphi nyelven · 3 Bevezetés A Borland Delphi napjaink egyik legfejlettebb alkalmazás-fejleszt rendszere. Els sorban adatbázis-rendszerek

31

Irodalomjegyzék

1. Borland Delphi 5.0 Online Help (beleértve a BDE Help-et és a Win32 Programmers Reference-et is)2. Szelezsán János: Adatbázisok, LSI Oktatóközpont, Budapest3. Halassy Béla: Az adatbázistervezés alapjai és titkai, IDG Magyarországi Lapkiadó Kft., Budapest, 19944. Thomas Binzinger: Delphi, Kossuth Kiadó, 19985. Dr. Szabó László: A Delphi 2.0-ról röviden, oktatási segédlet, Miskolc, 20006. Marco Cantú: Delphi 3 mesteri szinten, I-II. kötet, Kiskapu Kiadó, Budapest, 19987. Gray Cornell: Delphi tippek és trükkök, Panem Kft., Budapest, 1997

Ajánlott Internet-címek:- Delphi Software Online: www.animare.hu/dso- Magyar Delphi levelezőlista: www.szechenyi-nkzsa.sulinet.hu/delphi- Borland Magyarország: www.borland.hu- Borland Home Page: www.borland.com- Deplhi HomePage: www.borland.com/delphi/index.html- Deplhi Developer Support: www.borland.com/devsupport/delphi/