2. Adatbázis kezelés - ADO (ActiveX Data Objects) programozása Visual Basic-ben.

Mint azt már említettem, a mostani alkalommal - folytatva az elkezdett példaalkalmazást - bemutatom, hogyan készíthetünk adatbázis kezelő alkalmazásokat Visual Basic-ben. Az adatbázis-kezelő "motor", amit használni fogok az ún. ADO (ActiveX Data Objects) objektummodell. Mivel segítségével szinte minden ma ismert adatbázis formátum a megfelelő biztonsággal és gyorsasággal kezelhető, úgy döntöttem Ő lesz a kiválasztott.

Elsőként egy nézzük át mi is ez az ADO.
 

Az ADO-ról röviden

Az ADO azért készült, hogy a Microsoft legújabb és legnagyobb teljesítményű adathozzáférési modelljének, az OLE DB-nek az alkalmazásszintű felülete legyen. Az OLE DB minden adatforráshoz hatékony hozzáférést biztosít. Az ADO és az OLE DB együtt alkotják a Universal Data Access (univerzális adathozzáférés) stratégia alapjait. Az OLE DB univerzális hozzáférést biztosít mindenféle adathoz. Az ADO a fejlesztők számára egyszerűbbé teszi a programozást. Az ADO az OLE DB-re épül, így kihasználja az OLE DB gazdag, univerzális adathozzáférési eszköztárát.

Az ADO népszerűségét annak köszönheti, hogy

    • egyszerűen használható,
    • különböző típusú adatbázisok elérhetőségét támogatja,
    • igen egyszerűen kezelhető felület,
    • több eszközt és nyelvet támogató felület.
Az ADO korábbi elődeinek (RDO (Remote Data Objects) és DAO (Data Access Objects)) legjobb tulajdonságait egyesítette. Továbbra is megtartotta azok hierarchikus felépítését, nyelvi konvencióit. Az ADO egyszerű felépítése átláthatósága végett igen könnyen megtanulható a mai fejlesztők számára.
 

Az ADO objektumszerkezete

Az ADO egyik célja, hogy az OLE DB leggyakrabban használt tulajdonságait egyesítse, ezért objektummodellje olyan programozható objektumokból épül fel, melyek olyan platformokon alkalmazhatók, ami támogatja mind a COM-ot, mind az OLE Automationt

Az ADO hét objektumot és négy objektumgyűjteményt tartalmaz:

Objektumok:

    • Connection
    • Command
    • Recordset
    • Error
    • Field
    • Property
    • Parameter
Objektum gyűjtemények:
    • Fields
    • Parameters
    • Properties
    • Errors

 

Az objektummodell hierarchikus felépítése:
 

Az ADO objektummodell központi elemei a Connection, Recordset és a Command objektumok. A Connection objektum valósítja meg a kapcsolatot a kiválasztott adatforrással. Különböző OLE DB providerek (kiszolgálók) esetén a Connection objektum különböző metódusai és tulajdonságai használhatók.
 
 

Connection objektum

Egy adatbázis kapcsolat kiépítése előtt konfigurálni kell a használandó Connection objektumot. Ezt a megfelelő tulajdonságainak beállításával érhető el:

  • ConnectionString: a kapcsolat kiépítéséhez szükséges adatok, tulajdonságok beállítása.
    Felépítése:

    ‘Provider= ‘ : az OLE DB kiszolgáló neve
    ‘Data Source=' : adatforrás neve (pl.: ODBC bejegyzés, SQL szerver neve)
    ‘User ID=' : felhasználó azonosító
    ‘Password=' : jelszó

    Pl.: "Provider=Microsoft.Jet.OLEDB.3.51;Persist Security Info=False;Data Source=C:\Examles\Sample1.mdb"

    A fenti példa szemlélteti egy Microsoft Jet adatbázisra (Microsoft Access) történő kapcsolódás előkészítését. (A példaalkalmazásunkban is Access adatbázist használunk...)
     
     

  • ConnectionTimeout: beállíthatunk egy másodpercben megadott időt. Ha Connection megnyitása nem sikerül, a megnyitás az itt megadott ideig várni fog. Ha letelik az idő egy lekezelhető hiba generálódik.
  • Mode: az adott Connectionra vonatkozóan az adathozzáférés módja állítható be.
    Pl.: adModeRead - csak olvasható adatok
    adModeReadWrite - írható és olvasható adatok
     
Ezen adatok előzetes beállítása után megnyitható a Connection objektum. A megnyitáshoz az Open metódus használható. Ha a ConnectionString az előzőekben megfelelően beállításra került a metódus nem igényel paramétereket. Ellenkező esetben paraméterként megadható a ConnectionString, a User ID és a Password.

Az így létrehozott Connection objektumokon tranzakció követés is megvalósítható. A BeginTrans metódus meghívásával indítható a tranzakció, amit CommitTrans (tranzakció érvényesítés) és a RollBackTrans (tranzakció visszavonás) metódusokkal zárhatunk.

Command objektum

A Command objektum segítségével különböző parancsokat adhatunk ki az adatbázis kiszolgálónak. Ezek a parancsok lehetnek különböző lekérdezések, felparaméterezett lekérdezések. Az, hogy milyen parancsokat használhatunk, az adatbázis kiszolgálótól függ.

A Command objektum az ActiveConnection tulajdonságától függően, létrehozhat egy új kapcsolatot, vagy már egy meglévőt használva hajthatja végre a megadott parancsot. Ha az ActiveConnection egy már meglévő Connection objektumra mutat, akkor a Command objektum ezen Connection kapcsolatát használja. Ha az ActiveConnection tulajdonság egy kapcsolat-karakterláncot tartalmaz, a Command objektumhoz egy új kapcsolat jön létre. Több Command objektum esetén is használható ugyanannak a Connection objektumnak a kapcsolata.

A Command objektum CommandText tulajdonságában megadható egy lekérdezés karakterlánc. Ez a lekérdezés lehet szabványos SQL lekérdezés vagy adatdefiniáló nyelv, de itt megadható egy tárolt eljárás neve is. Létrehozhatók különböző tábla és összetett lekérdezések is, melyek végrehajtása egy rekordhalmazt eredményez.

A lekérdezés-karakterlánc típusa megadható a CommandType tulajdonságban. A CommandType tulajdonsághoz az adCmdText, az adCmdTable, az adCmdStoreProc vagy az adCmdUnknown értékek állíthatók be. Ha a lekérdezés-karakterlánc egy SQL-utasítás, a CommandType tulajdonság adCmdText értékét be kell állítani. Ha a lekérdezés-karakterlánc egy tárolt eljárás vagy egy tábla neve, az adCmdStoreProc vagy az adCmdTable értéket kell beállítani.

Ha az adCmdTable értéket állítottuk be, a Command objektum a lekérdezés-karakterláncot a select * from tablename szintaxissal hajtja végre. Ha az adCmdUnknown értéket állítottuk be, a Command objektumnak további lépéseket kell elvégeznie a lekérdezés-karakterlánc típusának meghatározásához, ami csökkenti a teljesítményt.

A következő példa egy SELECT utasítás végrehajtását mutatja be, amely egy Recordset objektumot ad vissza:

Egy command és egy recordset objektum deklarációja

Dim Cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
' Egy kapcsolat-karakterlánc vagy egy Connection objektum használata.
Cmd.ActiveConnection = "DSN=pubs;UID=sa"
Cmd.CommandText = "select * from adatok"
Cmd.CommandTimeout = 15
Cmd.CommandType = adCmdText
Set rs = Cmd.Execute()
rs.Close
A DSN=pubs;UID=sa ODBC kapcsolat-karakterlánc az ActiveConnection tulajdonságban szerepel. A 'select * from adatok' utasítás a CommandText tulajdonságban található, és mivel ez egy SQL-utasítás, a CommandType tulajdonság beállítása adCmdText. A CommandTimeout értéke 15 másodperc. 'A select * from adatok' SQL-utasítás egy Recordset objektummal térhet vissza, amely az rs Recordset objektumot jelöli ki.

A következő példa egy olyan tárolt eljárás végrehajtását mutatja be, amely nem ad vissza Recordset objektumot.

Dim Cmd As New ADODB.Command
' Egy kapcsolat-karakterlánc vagy egy Connection objektum használata.
Cmd.ActiveConnection = "DSN=pubs;UID=sa"
Cmd.CommandText = "myADOProc"
Cmd.CommandTimeout = 15
Cmd.CommandType = adCmdStoredProc
Cmd.Execute
A myADOProc tárolt eljárás a CommandText tulajdonságban szerepel. A CommandType tulajdonság beállítása a végrehajtott objektum típusának megfelelően adCmdStoredProc, melynek eredményeként a {call myADOProc} SQL-utasítás áll elő. Mivel e tárolt eljárás végrehajtása után nem készül eredményhalmaz, nincs kijelölt Recordset objektum.

A Parameters gyűjtemény és a Parameter objektum

A Parameters gyűjtemény paraméter információkat és adatokat szolgáltat a Command objektum számára. A Parameters gyűjtemény Parameter objektumokból áll. A Parameters gyűjteményre, illetve a Parameter objektumra csak akkor van szükség, ha a Command objektum lekérdezés-karakterlánca paramétereket igényel.

A különálló paraméter információk (például méret, adattípus, irány és érték) minden egyes Parameter objektum segítségével olvashatók és írhatók. A paraméterek irányának négy típusa van: bemeneti, kimeneti, ki- és bemeneti, valamint visszatérési érték. Egy Parameter objektum szolgálhat bemeneti paraméterként, adatot tároló kimeneti paraméterként vagy egy tárolt eljárás visszatérési értékeként. A Parameters gyűjtemény Refresh metódusa rákényszerítheti a szolgáltatókat a paraméter információk frissítésére, azonban ez sok időbe telhet.

Hosszú adattípusok kezelésekor az AppendChunk metódus használható az adatok töredékekben való beírásához. A következő példák azt szemléltetik, hogyan kell paramétereket létrehozni egy tárolt eljáráshoz.

    Dim cmd As New ADODB.Command
    Dim rs As New ADODB.Recordset
    Dim prm As ADODB.Parameter
    ' Egy Command objektum definiálása a tárolt eljáráshoz.
    cmd.ActiveConnection = "DSN=pubs;uid=sa"
    cmd.CommandText = "myADOParaProc"
    cmd.CommandType = adCmdStoredProc
    cmd.CommandTimeout = 15
    ' A tárolt eljárás új paraméterének beállítása.
    Set prm = Cmd.CreateParameter("Type", adChar, adParamInput, 12, "Business")
    Cmd.Parameters.Append prm
    ' A parancs végrehajtásakor rekordhalmaz létrehozása.
    Set rs = Cmd.Execute
    While (Not rs.EOF)
        Debug.Print rs(0)
        rs.MoveNext
    Wend
Az ActiveConnection, CommandText, CommandType és CommandTimeout tulajdonságok értéke megegyezik az előző példabeli értékekkel. A myADOParaPro tárolt eljárás egy olyan bemeneti paramétert vár, melynek adattípusa character és mérete 12. A CreateParameter metódus hozza létre a megfelelő Parameter objektumot, melynek jellemzői: az adattípus adChar karakter, a paraméter típusa adParamInput bemeneti paraméter és az adat hossza 12. A Parameter objektum neve Type, és mivel ez egy bemeneti paraméter, a Business adatértéket is tartalmazza.

A paraméter beállítása után a Parameter objektumot az Append metódus fűzi hozzá a Parameters gyűjteményhez. A myADOParaProc tárolt eljárás lefut, és létrejön egy Recordset objektum.

A Recordset objektum

A Recordset objektum metódusokat biztosít az eredményhalmazok kezeléséhez. Segítségével a rekordhalmazok átvizsgálhatók, új rekordok vihetők fel, módosíthatók, rekordok törölhetők. A Recordset objektum tartalmaz egy Fields gyűjteményt, melynek segítségével az egyes rekordok értékei visszakereshetők, módosíthatók.

Egy Recordset objektum megnyitásakor automatikusan megnyílik egy kurzor. A Recordsetben megadható a használni kívánt kurzor típusa és helye. A CursorType tulajdonság beállításával megadható, hogy a kurzor statikus, vagy dinamikus legyen. Ez a tulajdonság befolyásolja, hogy a Recordset objektumban való mozgást, és a módosított rekordok láthatóságát. Alapértelmezésként a kurzor típusa csak olvasható és csak előre irányú.

A CursorLocation tulajdonsággal megadható, hogy kiszolgáló vagy ügyfél oldali cursort akarunk -e. Recordset objektum létrehozható a Connection vagy a Command objektum Execute metódusával.

A következő példa a Recordset objektum használatát mutatja be kapcsolat megnyitásához és eredményhalmaz visszakereséséhez:

Dim rs As New ADODB.Recordset
rs.Open "select * from titles", "DSN=pubs;UID=sa"
While (Not rs.EOF)
Debug.Print rs(0)
rs.MoveNext
Wend
rs.Close
A példa megnyit egy kapcsolatot, létrehoz egy rekordhalmazt, majd végighalad az eredményhalmazon és kinyomtatja minden sor első mezőjének tartalmát.

A Fields gyűjtemény és a Field objektum

A Fields gyűjtemény és a Field objektum segítségével elérhető az aktuális rekord minden adatoszlopa. A Fields gyűjtemény a Recordset objektumon, míg a Field objektum a Fields gyűjteményen keresztül, az alapértelmezett indexelési metódus használatával érhető el.

A Field objektummal új rekord állítható össze vagy módosíthatók a meglévő adatok, míg a Recordset objektum AddNew, Update, illetve UpdateBatch metódusával az új vagy módosított adatok érvényesíthetők.

Egy Field objektum frissítése az adat módosításakor megtörténik, nincs szükség külön frissítési metódusra.

A következő példában egy Recordset objektum mezőinek jellemző tulajdonságait íratja ki (név, típus, érték):

Dim rs As New ADODB.Recordset
Dim fld As ADODB.Field
rs.Open "select * from titles", "DSN=pubs;UID=sa"
For Each fld In Flds
Debug.Print fld.Name
Debug.Print fld.Type
Debug.Print fld.Value
Next
rs.Close
A példabeli rutin végighalad a Fields gyűjteményen és visszakeres minden Field objektumot. Kinyomtatja minden Field objektum Name, Type és Value tulajdonságát.

A Properties gyűjtemény és a Property objektum

A Properties gyűjtemény és a Property objektum információt szolgáltat a Connection, a Command, a Recordset, valamint a Field objektumok jellemzőiről.

A Properties gyűjtemény Property objektumokból áll. A Property objektum nemcsak a tulajdonságok értékét és típusát, hanem azok attribútumait is visszaadja. Az attribútumok megmondják például azt, hogy egy objektum megadott tulajdonsága használható-e, szükséges-e, illetve olvasható vagy írható. A ConnectionTimeout tulajdonság például megadja a kapcsolatkiépítés várakozási idejét másodpercekben, aminek leteltével a rendszer határidő-túllépési hibával tér vissza. Létezik CommandTimeout tulajdonság a Command objektumhoz, Updatability tulajdonság a Recordset objektumhoz és DEFAULTVALUE a Field objektumhoz.

A következő példa a ConnectionTimeout, a CommandTimeout és az Updatability tulajdonságok visszakeresésének módját mutatja:

Dim Cn As New ADODB.Connection
Dim Cmd As New ADODB.Command
Dim rs As New ADODB.Recordset
Cn.Open "pubs", "sa"
' A ConnectionTimeout tulajdonság kikeresése.
Debug.Print Cn.Properties("Connect Timeout")
Set Cmd.ActiveConnection = Cn
Cmd.CommandText = "titles"
Cmd.CommandType = adCmdTable
Set rs = Cmd.Execute()
' A CommandTimeout tulajdonság kikeresése.
Debug.Print Cmd.Properties("Command Timeout")
Debug.Print rs.Properties("Updatability")
 
A Properties gyűjteményt ebben a példában a Connection, a Command és a Recordset objektumok segítségével kerestük vissza. A rutin kinyomtatja a Connection objektum ConnectionTimeout tulajdonságát. A Command és a Recordset objektumokon ugyanezeket a lépéseket végezzük el.

Azt hiszem ennyi talán elég volt az ADO legfontosabb jellemzőinek megismeréséhez. Most nézzük meg hogyan is működik ez a gyakorlatba. Példaalkalmazásunkban egy videotéka kölcsönzési nyilvántartását szeretnénk megvalósítani. A felhasználói felületek már nagyrészt elkészültek, már csak az adatmegjelenítéseket, adatszerkesztéseket kellene valahogy megvalósítani. Az adatbázis adott, egy Access adatbázis (video.mdb). Legelső lépésként a kapcsolatot kellene megteremteni alkalmazásunk és az adatforrás között. Mint azt a fentiekben már említettem, ennek megvalósítására van az ADO-nak egy speciális objektuma, a connection objektum. Ahhoz hogy elérhessük az adatbázist, ezt az objektumot kell megfelelően felparamétereznünk és megnyitnunk a program indulásakor. A példaprogramban erre találtok egy OpenJetConnection eljárást, amely paraméterként vár egy Connection objektumot, valamint a megnyitandó Access adatbázis nevét útvonallal együtt:

Public Sub OpenJetConnection(conn As ADODB.Connection, db As String) conn.Provider = "Microsoft.Jet.OLEDB.3.51" conn.Open db End Sub

A connection Provider tulajdonságával állíthatjuk be, hogy milyen kiszolgálót szeretnénk alkalmazni, vagyis milyen adatbázisra szeretnénk kapcsolódni. Esetünkben ez a 3.51-es Jet.

Azonban nem csak egy kapcsolat megnyitásakor kell körültekintőnek lennünk, hanem figyelnünk kell, hogy a program bezárása előtt minden aktív kapcsolatot megfelelően le is zárjunk. Ugyanis előfordulhat, hogy egy kapcsolat le nem zárása után, programunk nem lesz képes újonnan csatlakozni, hiszen a kiszolgáló érzékeli, hogy 'valaki' már csatlakozik az adatforrásra. A példaalkalmazásban egy általános eljárást találtok a kapcsolatok lezárásához. Ez a Close metódussal nem csak lezárja a kapcsolatot, de fel is szabadítja az adott objektumot.

Public Sub CloseConnection(conn As ADODB.Connection) conn.Close Set conn = Nothing End Sub
 
 

Most, hogy a kapcsolatot sikeresen kiépítettük nézzük meg miként tölthetnénk fel listáinkat a megfelelő adatokkal. Elsőként is nézzük a kölcsönzői tagok listáját (első fül).


Tagok adatai

A listát feltöltő rutin a Form_Load esemény bekövetkezésekor hívódik meg (FeltoltTagLista eljárás). Vizsgáljuk meg mit is csinál ez az eljárás. Legelső lépésként egy formszinten deklarált Recordset (TagRecordset) objektum inicializálását hajtja végre. Itt kerül beállításra az ActiveConnection értéke, amely meghatározza, hogy a recordset mely connection objektumon keresztül kapcsolódjon az adatforrásra, valamit itt kerül beállításra a recordset LockType és CursorLocation tulajdonsága is, de erről majd később.

Rekordset inicializálása:

Public Sub SetRs(rs As ADODB.Recordset, conn As ADODB.Connection)
    'Az ActiveConnection egy connection objektumot reprezentál ezért értékadást a Set 'kulcsszóval hajthatunk végre.
Set rs.ActiveConnection = conn rs.LockType = adLockBatchOptimistic rs.CursorLocation = adUseClientEnd Sub

Második lépés a listák adatainak adatbázisból való kinyerése, és az adatfeltöltés. Mint már említettem a recordset nem más, mint egy lekérdezés eredményhalmaza, amin keresztül az adott adatbázis megfelelő adatait manipulálhatjuk. Tehát ahhoz, hogy a számunkra szükséges adatokat megkaphassuk, meg kell nyitnunk a már inicializált recordsetünket a megfelelő SQL lekérdezéssel. Ezt a megnyitást az Open metódussal tehetjük meg, aminek a következő a szintaxisa:

recordset.Open [Source],[ ActiveConnection],[ CursorType],[ LockType],[Options]

A Source paraméter igen sokféle adatot reprezentálhat. Lehet pl. egy Létező Command objektum neve, egy SQL utasítás, egy táblanév, egy tárolt eljárás hívása vagy egy fájl név, amely fájl egy korábban mentett recordset adatait tartalmazza (lehetőség van egy recordset adatainak fájlba mentésére).

Az ActiveConnection lehet egy meglévő Connection objektum neve, vagy egy String, ami egy ConnectionString-et reprezentál.

A CursorType paraméterrel adhatjuk meg, hogy a megnyitott recordsetünk milyen típusú kurzolt (ez egy rekordmutató) használjon. Értékei a következők lehetnek:
 

  • adOpenForwardOnly (Alapértelmezett) Egy ún. csak előre haladó kurzort nyit meg.
  • adOpenKeyset Egy KeySet típusú kurzort használ.
  • adOpenDynamic Dinamikus kurzort használ.
  • adOpenStatic Statikus kurzort használ.

A LockType paraméter határozza meg a megnyitott recordset rekord szintű lockolását. Értékei lehetnek:
 

  • adLockReadOnly (Alapértelmezett) Csak olvasható adatok.
  • adLockPessimistic Pessimistic lockolás. Az adott rekord editálása alatt lockolja azt. adLockOptimistic Optimistic lockolás. Csak az Update metódus hívása alatt lockolja a rekordot.
  • adLockBatchOptimistic Optimistic kötegelt módosítás. UpdateBatch esetén használatos. Az Option paraméter a végrehajtani kívánt lekérdezés típusát, vagyis a Source paraméter típusát határozza meg. Értékei pl.:

  • adCmdText Pl. ha a forrás egy SQL string.
    adCmdTable A forrás egy adattábla neve.
    adCmdStoredProc A forrás egy tárolt eljárás hívása.

Esetünkben most egy adott SQL parancsal szeretnénk megnyitni a recordsetet. Ez a parancs pedig a következő:

select * from Tagok where Torolt = 0

Ezzel a lekérdezéssel a Tagok tábla törlésre nem jelölt rekordjainak minden mezőértékét szeretnénk megkapni. A lekérdezés után megvizsgáljuk, hogy az eredményül kapott recodsetünk tartalmaz-e egyáltalán adatokat, és ettől függően végrehajtjuk a megfelelő ListView vezérlők inicializálását (tartalom törlés, fejléc beállítás). Azt, hogy a recordset tartalmaz-e rekordokat legegyszerűbben a RecordCount tulajdonsággal határozhatjuk meg. Ez az eredményhalmazban található rekordok számát mutatja meg. Tehát ha értéke nulla, akkor a lekérdezésünk eredménye egy üres halmaz.

Ha a rekordok száma nem nulla, eltároljuk a recordset teljes adattartalmát egy variant típusú mátrixban. (Később ezt a mátrixot használjuk az egyes rekordok adatainak szűrésére, keresésekre.) Erre a tárolásra a recordsetnek létezik egy speciális metódusa a GetRows.

array = recordset.GetRows( Rows, Start, Fields )

A Rows paraméterben adhatjuk meg a tárolni kívánt sorok számát. Ha nem adjuk, meg akkor alapértelmezésként a recordset teljes tartalmát tárolja.
A Start paraméter a letárolás kezdő rekordját mutatja meg. Értékei lehetnek:

  • adBookmarkCurrent Aktuális rekordtól kezdi.
  • adBookmarkFirst Az első rekordtól kezdi.
  • adBookmarkLast Az utolsó rekordtól kezdi.

A Fields paraméterben a letárolni kívánt mezők neveit vagy azok sorszámát adhatjuk meg. Ha több mezőt szeretnénk megadni, akkor azok neveit vagy sorszámait egy Variant tömb paraméterben kell átadnunk.

A letárolás után a recordset minden egyes rekordján végighaladva beolvassuk annak értékeit, a megfelelő ListView vezérlőbe. A rekordokon való navigálást a következő tulajdonságok és metódusok felhasználásával tehetjük meg.

  • Recordset.Bof: A recodset végét jelzi. True vagy False értéke lehet.
  • Recordset.Eof: A recodset végét jelzi. True vagy False értéke lehet.
  • Recordset.MoveFirst A recordset legelejére ugrás.
  • Recordset.MoveLast A recordset végére ugrás.
  • Recordset.MoveNext A következő rekord.
  • Recordset.MovePrevious A előző rekord.
  • Recordset.Move Az adott sorszámú rekordra ugrik.

Nézzük meg, hogyan is érhetjük el egy recordsetben lévő rekordok mező értékeit. Erre több szintaxist is alkalmazhatunk.

Mint már említettem a recordsetnek van egy Fields objektum gyűjteménye, amely a recordsetben tárolt rekordok mező szerkezetét reprezentálja, vagyis ezen keresztül tudjuk lekérdezni az egyes mezők jellemező adatait, és azok tartalmát. A Fields gyűjtemény minden egyes elemét a megfelelő index megadásával érhetjük el. Pl. a recordset 4. mezőjének értékét a következő keppen határozhatjuk meg:

recordset.Fields(3).Value (Az indexelés itt is 0-tól kezdődik)

Lehetőség van arra, hogy a mezők adatait ne csak a mező indexével, hanem az index helyett a nevét használva érjük el. Vagyis ha a 4. mező neve IrSzam akkor arra így is hivatkozhatunk:

recordset.Fields("IrSzam").Value

A mező értékére történő hivatkozást tovább egyszerűsíthetjük úgy, hogy a mezőhivatkozás után a Value kulcsszót nem kötelező megadnunk:

recordset.Fields("IrSzam")

Sőt még egyszerűbben a következőképpen hivatkozhatunk egy mező értékére:

Recordset("IrSzam") vagy recordset(3) vagyis még a Fields objektumgyűjtemény megadását is elhagyhatjuk.

Most már le is zárhatjuk a recordsetünket, hiszen minden számunkra szükséges adatot eltároltunk. A lezárást megint egy külön rutin végzi, ami egy recordsetet vár paraméterül, és ez a Close metódussal nem csak lezárja az eredményhalmazt, de fel is szabadítja azt.

Ezek után itt van maga a feltöltést végző eljárás.

'Tagok adatainak feltöltését végző eljárás:

Public Sub FeltoltTagLista() Dim itmx As ListItem Call SetRs(TagRecordset, VideoConnection) lsvTagok.ColumnHeaders.Clear lsvTagok.ListItems.Clear lsvAKolcs.ColumnHeaders.Clear lsvKolcsF.ColumnHeaders.Clear With TagRecordset     .Open "select * from Tagok where Torolt = 0"     If .RecordCount > 0 Then         mxTagok = TagRecordset.GetRows         TagRecordset.MoveFirst         lsvTagok.ColumnHeaders.Add , , "Azonosító", lsvTagok.Width / 6         lsvTagok.ColumnHeaders.Add , , "Tag neve", lsvTagok.Width / 4         lsvTagok.ColumnHeaders.Add , , "Kölcsönzések száma", lsvTagok.Width / 5         lsvTagok.ColumnHeaders.Add , , "Aktív kölcsönzés", lsvTagok.Width / 5         lsvAKolcs.ColumnHeaders.Add , , "Azonosító", lsvAKolcs.Width / 8         lsvAKolcs.ColumnHeaders.Add , , "Cím", lsvAKolcs.Width / 4         lsvAKolcs.ColumnHeaders.Add , , "Típus", lsvAKolcs.Width / 4         lsvAKolcs.ColumnHeaders.Add , , "K. dátuma", lsvAKolcs.Width / 4         lsvAKolcs.ColumnHeaders.Add , , "L. dátuma", lsvAKolcs.Width / 4         lsvKolcsF.ColumnHeaders.Add , , "Azonosító", lsvKolcsF.Width / 8         lsvKolcsF.ColumnHeaders.Add , , "Cím", lsvKolcsF.Width / 4         lsvKolcsF.ColumnHeaders.Add , , "K. dátuma", lsvKolcsF.Width / 4         Do While Not .EOF             Set itmx = lsvTagok.ListItems.Add(, , .Fields(0).Value)             itmx.SubItems(1) = .Fields(1).Value             itmx.SubItems(2) = .Fields(4).Value             If .Fields(6).Value = True Then                 itmx.SubItems(3) = "+"             Else                 itmx.SubItems(3) = ""             End If             .MoveNext         Loop     Else         ret = MsgBox("Üres a 'Tagok' adattábla!", vbInformation + vbOKOnly)     End If End With Call CloseRecordset(TagRecordset) End Sub
 

Szintén a Form_Load eseményben hajtódik végre a filmek adatait tartalmazó listát feltöltő eljárás (második fül), aminek értelmezése a fentiek alapján már pofon egyszerű.

Public Sub FeltoltFilmAdatok() lstFilmek.Clear Call SetRs(FilmRecordset, VideoConnection) With FilmRecordset     .Open "select * from filmek where torolt = 0"     mxFilmek = FilmRecordset.GetRows     .MoveFirst     If .RecordCount > 0 Then         Do While Not .EOF             lstFilmek.AddItem .Fields(1)             lstFilmek.ItemData(lstFilmek.NewIndex) = .Fields(0)             .MoveNext         Loop     Else     End If End With Call CloseRecordset(FilmRecordset) End Sub

Most pedig nézzünk egy igen sokszor használatos módszert egy lista (ListBox vagy ComboBox) feltöltésére, amikor a lista minden egyes eleméhez az ItemData tulajdonság felhasználásával egy speciális azonosítót vagy egyéb szám jellegű tulajdonságot rendelünk.

Esetünkben egy ComboBox-ban szeretnénk megjeleníteni a videotékában lévő filmek lehetséges típusait, és ezek mellett szeretnénk tárolni az egyes típusok azonosítóit is. Ezt a következő módszerrel tehetjük meg:

'elem hozzáadás cmbTipus.AddItem .Fields(1) 'ItemData hozzárendelés - az azonosító tárolása cmbTipus.ItemData(cmbTipus.NewIndex) = .Fields(0)

Ugyanez egy eljárásban:

Private Sub FeltoltTipusAdatok() Call SetRs(TipusRecordset, VideoConnection) With TipusRecordset     .Open "select * from ftipusok"     mxTipus = TipusRecordset.GetRows     .MoveFirst     If .RecordCount > 0 Then         Do Wile Not .EOF             cmbTipus.AddItem .Fields(1)             cmbTipus.ItemData(cmbTipus.NewIndex) = .Fields(0)             .MoveNext         Loop     Else     End If End With Call CloseRecordset(TipusRecordset) End Sub

Végezetül még egy fontos dolog. Jópár helyen történik az alkalmazásban adatfelvitel, vagy módosítás. Nézzük meg milyen módszerekkel valósíthatunk meg ilyen műveleteket.

A legegyszerűbb és a legkézenfekvőbb megoldás a recordseten keresztül történő adatmanipuláció. Ugyanis ha adatmódosítást szeretnénk végrehajtani nem kell mást tennünk mint a kívánt rekordra állni, majd a megfelelő mezőértékeket módosítani majd végezetül kiadni az Update parancsot.

Pl.

Recordset.Move(6) Recordset.Fields(0).Value = ertek1 Recordset.Fields(1).Value = ertek2 Recordset.Fields(2).Value = ertek3 Recordset.Update

Még ennél is egyszerűbb módszer, ha a következő formában adjuk ki az Update parancsot.

recordset.Update Fields, Values

Ahol a Fields paraméternek megadhatunk egy Variant tömböt amiben a módosítani kívánt mezők nevei szerepelnek, Values paraméternek pedig szintén egy Variant tömböt a módosított értékek számára.

Új rekord hozzáadása egy recordsethez a következő módszerrel történik.

recordset.AddNew FieldList, Values

Ahol a Fields paraméternek megadhatunk egy Variant tömböt amiben a kívánt mezők nevei szerepelnek, Values paraméternek pedig szintén egy Variant tömböt az új értékek számára.

Minden AddNew hívás után a módosítások elmentéséhez meg kell hívni az Update parancsot is.

Még egy lehetséges módszer új rekord felvitelére:

recordset.AddNew recordset(0) = ID recordset(1) = FName recordset(2) = LName
recordset.Update

Legvégül mutatok még egy módszert, amivel kikerülhetjük a recordsetek használatát. A connection objektum rendelkezik egy Execute metódussal, aminek segítségével különböző SQL parancsokat hajthatunk végre az adott adatforráson.

Meghívás recordset visszaadása nélkül:

connection.Execute CommandText, RecordsAffected, Options

Meghívás recordset visszaadással:

Set recordset = connection.Execute (CommandText, RecordsAffected, Options)

A CommandText paraméter lehet SQL lekérdezés, táblanév vagy tárolt eljárás hívása. Az Option paraméter pedig megegyezik a recodset Option paraméterével.
Két példa az execute metódusra. Az első egy rekord beszúrást, a második egy rekord módosítást mutat be SQL parancs segítségével:

VideoConnection.Execute "INSERT INTO Kolcsonzes (KID,TagID,FilmID,KDatum,KFlag,LDatum) VALUES (120,234,2,#10/31/99#,1,#11/02/99#)"
 
VideoConnection.Execute "UPDATE Tagok SET Kszam = Kszam + 3, KFlag = 1, UKolcs = #10/31/99#" WHERE TagID = 234"

Mivel a program által használt eljárások mindegyike az itt leírt módszereket alkalmazzák, ezért nem mutatom be mindegyik működését. A fent leírtak alapján már igen könnyen értelmezhetitek a program egyes részeit. Az program TabStript-jének utolsó fülét direkt hagytam szabadon, hogy aki akarja kedve szerint készíthessen lekérdezéseket a nyilvántartott adatokról.

És amíg el nem felejtem! Az 5-ös VB alapban nem tartalmazza az ADO objektumkönyvtárat, ezért ahhoz hogy a mintaprogramot használni tudjátok, egy mdac_typ programot kellene feltelepítenetek, amit több helyen is megtalálhattok: