Delphi - Több logikai érték tárolása adatbázisban egyetlen mezőben, és az ezek beállítására szolgáló DBFlagCheckBox komponens

forráskód letöltése
Előfordulhat, hogy egy adatbázis rekordjában több logikai értéket kell tárolnunk, például amikor egy űrlapon több kérdésre igaz vagy hamis választ adhat a felhasználó. Ekkor a szokásos művelet az, hogy az adatbázis szerkezetét úgy alakítjuk ki, hogy minden kérdéshez egy-egy logikai típusú mezőt rendelünk. 5-10, vagy akár több mezőnél viszont ez nem túl praktikus, hiszen az is megoldható, hogy egy mezőben akár 32 logikai értéket is eltároljunk egyszerre. Létrehozunk egy olyan CheckBox komponenst is, amellyel az ilyen típusú mezők adatait kényelmesen be lehet állítani.
A mellékelt példaprogram megnyitása előtt a *.pas-ban lévő komponenst telepítenie kell a Delphi alá. Ehhez válassza a Component - Install Component menüpontot.
Az ötlet nem új, hiszen gyakran alkalmazzuk például függvények esetében, amikor ún. flag-eket állítunk be. A lényeg abban áll, hogy egy integer (egész) típust használunk a logikai értékek tárolására. Az egész típus 32 bites, és minden bit egy-egy logikai értékhez tartozik. Ha a bit értéke 1, a logikai érték igaz, amikor 0, akkor hamis. Ebben az esetben egy kapcsolónak csak két állása lehetséges, nem létezik az ún. szürkített (nem értelmezett) állapot.
A kapcsolók tárolásához tehát elég egy egész típusú mezőt létrehozni az adatbázisban, illetve ha 32-nél több logikai értéket akarunk tárolni, akkor még egyet, és így tovább.
Az adatok tárolása tehát megoldott, nézzük meg, hogy ez hogyan is történik. Tegyük fel, hogy van 10 logikai értékünk, amelyből az 1., a 4. és a 9. érték igaz, a többi pedig hamis. Ekkor összeadjuk az igaz értékekhez tartozó bitek helyi értékét, ami 1 + 8 + 256 = 265, és ezt a számot tároljuk el az adatbázisban. Ez eddig rendben is volna, ám nem várhatjuk el a felhasználótól, hogy ő a kapcsolók kényelmes használata helyett kiszámolja ezt az értéket, és mondjuk egy DBEdit mezőbe beírja. Éppen ezért létrehozunk egy DBFlagCheckBox nevű komponenst, ami ugyanúgy használható, mint a normál DBCheckBox, de integer, vagy más egész típusú mezőhöz kapcsolható.
Az új komponens osztályt a TCustomCheckBox osztályból származtatjuk, és létrehozunk benne egy TFieldDataLink típusú objektumot, valamint ehhez egy DataSOurce és egy DataField property-t. A DataField property-hez készítünk egy property szerkesztőt, amelyben csak egész típusú mezők választhatók ki.
A Flag property-ben adható meg, hogy a CheckBox a mező melyik sorszámú bitjéhez tartozik. Az első bit sorszáma 1, a másodiké 2, a harmadiké 3, és így tovább. Tehát nem a bit helyi-értékét kell megadni, hanem a sorszámát. A Flag property-ben megadott bit értékét a GetFlagValue függvény adja vissza.