Objekt Recordset

Doc. Dr. Vladimír Homola, Ph.D.

Úvod

Objekt třídy Recordset je jediným objektem umožňujícím přístup k datům. Jde vlastně o řádky ("datový obsah") tabulky relační databáze nebo výsledek dotazu - příkazu Select z SQL. Databáze v Microsoft Jet obsahují obecně tabulek a dotazů více; otevřené objekty Recordset jsou obsahem kolekce Recordsets objektu Database.

Použití objektu Recordset je podmíněno dostupností knihovny DLL, ve které je definován. V prostředí Visual Basic se tak učiní pomocí menu položky References... - ta je umístěna v hlavním menu Project v případě samostatného překladače Basicu, nebo v hlavním menu Tools v případě volání Visual Basicu z aplikace (Excelu, Accessu, Wordu atd.). Z nabídek knihoven se volí ta, která začíná DAO. Připojená čísla označují verzi, volí se podle potřeby (většinou ta nejvyšší). Verze znamenají "stupeň vývoje" struktury databáze Microsoftu (MDB): např. program Access dodávaný s Office 97 používá DAO350.DLL, Access dodávaný s Office 2000 používá DAO360.DLL.

Tyto knihovny obsahují DAO příslušné verze objektových modelů. DAO (Data Access Objects - objekty pro přístup k datům) je množina objektů, které umožňují klientům automatizace OLE programově přistupovat k datům a modifikovat zdroje dat. Jsou použity v programech Access, Visual Basic - obecně ve všech aplikacích, které zpracovávají data uložená jako Microsoft Jet databáze. Dále je možno zpracovávat všechny formáty, které Microsoft Jet podporují (jako např. zdroje dat v ODBC včetně SQL serveru, FoxPro, Paradoxu aj.).

Protože článek je zaměřen k poskytnutí základních informací pro tvorbu jednoduchých aplikací, jsou uvedeny jen nejpoužívanější metody a vlastnosti.

Přístup k hodnotám datových polí

Objekt Recordset zpřístupňuje datové zdroje ve tvaru tabulky relační databáze - množiny řádků, sestávajících z datových polí. V každém okamžiku má aplikace k disposici jeden jediný konkrétní řádek, s jehož daty může pracovat - tzv. aktuální řádek (záznam). Pro účely označení aktuálního řádku zavádí databázové systémy pojem pointer (ukazatel, "ukazovátko") na aktuální řádek ve zřejmém významu.

Nechť rs je identifikátorem konkrétního otevřeného objektu Recordset, např. tabulky VYDAJE databáze DOMACOST:

Dim db As Database, rs As Recordset
Set db = DBEngine.OpenDatabase("C:\KURS\DOMACNOST.MDB")
Set rs = db.OpenRecordset("VYDAJE")

Pro pohyb v tabulce slouží metody MoveXY (viz níže) - umožní nastavit kterýkoliv řádek jako aktuální. Nechť tedy je nyní nějaký řádek aktuálním řádkem, nechť tabulka VYDAJE má sloupec např. CENA. Přístup k hodnotě ceny aktuálního řádku zajistí zápis tvaru

rs ! CENA

(operátorem výběru pole je vykřičník, nikoliv tečka!). Zápis lze použít především ve výraze, kde znamená skutečně hodnotu typu odpovídající typu pole CENA. Zápis lze použít i na levé straně přiřazovacího příkazu, např.

rs ! CENA  =  12.60

kde znamená odkaz na pole. O změnách dat v tabulce však viz metody Edit a AddNew.

Kolekce objektu Recordset

Fields

Kolekce obsahuje jednotlivé objekty třídy Field (datové pole), z nichž sestává tabulka dat reprezentovaná daným objektem Recordset. Blíže jsou datová pole popsána zde.

Metody objektu Recordset

MoveFirst, MoveLast, MoveNext, MovePrevious, Move

Metody MoveFirst, MoveLast, MoveNext, MovePrevious posunou ukazatelem aktuálního řádku na první (MoveFirst), poslední (MoveLast), následující (MoveNext) a předchozí (MovePrevious) záznam v tabulce; tento záznam se stává aktuálním záznamem. Metody mají syntaxi

rs.MoveFirst
rs.MoveLast
rs.MoveNext
rs.MovePrevious

kde rs je identifikátor daného objektu Recordset. Metoda Move má syntaxi

rs.Move n

kde rs je identifikátor daného objektu Recordset a n je výraz typu Long. Metoda Move posune ukazatel aktuálního řádku o n řádků dopředu (směrem ke konci tabulky) v případě kladného n, nebo o n pozic zpět (směrem k začátky tabulky) v případě záporného n.

Ukazatel aktuálního řádku má dvě specielní posice neukazující na žádný konkrétní řádek. Jejich existenci si vynutily metody MoveNext a MovePrevious:

Volání metody Move s takovým počtem, který přesahuje počet zbývajících řádků (ale ukazatel ještě není na EOF), umístí ukazatel na EOF. Volání metody Move s takovým počtem, který přesahuje počet předcházejících řádků (ale ukazatel ještě není na BOF), umístí ukazatel na BOF.

Volání metody MoveNext nebo Move s kladným počtem v posici EOF, a metody MovePrevious nebo Move se záporným počtem v pozici BOF vede k chybě.

Jestliže je množina řádků prázdná (tabulka neobsahuje žádná data), je vlastnost EOF i BOF nastavena na True a pokud ukazatelem metodami Move vede k chybě.

Metody Edit, AddNew, Update a CancelUpdate

Metody slouží pro změnu údajů (Edit) aktuálního řádku a pro přidání (AddNew) nového řádku.

Pro provádění změn v tabulce relační databáze vytváří databázový stroj při otevření objektu Recordset v operační paměti dočasný paměťový prostor (tzv. buffer) o velikosti jednoho řádku dané tabulky. Paměťový buffer si lze představit jako jednorozměrné pole typu Variant obsahující po řadě jednotlivá pole řádku tabulky - to je důležité z hlediska typu údajů.

Metoda Edit má syntaxi

rs.Edit

a zapíše hodnoty aktuálního řádku do paměťového bufferu. Paměťový buffer a aktuální řádek budou tedy obsahovat stejné hodnoty.

Metoda AddNew má syntaxi

rs.AddNew

a pracuje takto: nejprve přidá na konec tabulky dat representované objektem Recordset nový řádek a učiní tento řádek aktuálním řádkem. Současně naplní všechna jeho pole hodnotami Null. Potom zapíše hodnoty aktuálního řádku (tohoto nově přidaného) do paměťového bufferu. Paměťový buffer a aktuální řádek budou tedy obsahovat stejné hodnoty - samé Null.

Po provedení metody Edit nebo AddNew se dočasně mění význam zápisu pro přístup k datovému poli. Nechť má otevřená tabulka pole CENA . Pak zápis

rs ! CENA

neznamená přímo pole tabulky, ale pole paměťového bufferu. Přiřazení

rs ! CENA  =  12.60

tedy přiřazuje dvanáct šedesát nikoliv do tabulky, ale do paměťového bufferu.

Zápis obsahu paměťového bufferu zpět do tabulky dat provede metoda Update. Její syntax je

rs.Update

Jestliže po změnách provedených po volání metod Edit nebo AddNew nenásleduje volání metody Update, změny se v tabulce neprojeví. Zvláště volání jakékoliv metody mající za následek změnu aktuálního řádku (např. Move) maže obsah paměťového bufferu - pokud tedy nebyl dříve zapsán metodou Update do tabulky, zůstává řádek tabulky beze změny.

Metoda CancelUpdate má syntaxi

rs.CancelUpdate

a zruší všechny změny započaté metodou Edit a ještě neprovedené metodou Update. Má tedy stejný účinek jako např. posunutí ukazatele na jiný řádek (až na to, že se aktuální řádek nemění). Analogicky to platí i o AddNew, ale nově přidaný řádek se neodstraní, jen zůstane prázdný.

Příklad na změnu ceny podle předchozího výkladu:

Dim db As Database, rs As Recordset
Set db = DBEngine.OpenDatabase("C:\KURS\DOMACNOST.MDB")
Set rs = db.OpenRecordset("VYDAJE")
rs.Edit
rs ! CENA = 12.60
rs.Update

Metoda Delete

Metoda vypustí aktuální řádek. Má syntaxi

rs.Delete

kde rs je identifikátor daného objektu Recordset. Objekt Recordset musí být aktualizovatelný objekt, např. tabulka relační databáze. Před voláním musí být nějaký řádek aktuálním řádkem (ukazatel nesmí být na BOF nebo EOF). Po volání metody Delete zůstává vypuštěný řádek aktuálním, ale je označen jako vypuštěný a nelze jej editovat. Po přemístění ukazatele (např. metodou Move) se vypuštěný řádek opustí a už nikdy nelze učinit aktuálním - tváří se to, jako kdyby tam nebyl.

Metoda Seek

Metoda vyhledá v indexované tabulce (otevřený Recordset typu tabulka) záznam, jehož index splňuje jistá kriteria, a tento záznam učiní aktuálním záznamem.

Metoda má syntaxi

rs.Seek cmp, k1, k2, ..., k13

Značí přitom

Příklad vyhledání prvního řádku s cenou větší než 12.60, je-li tabulka VYDAJE databáze DOMACNOST indexována podle sloupce CENA a index se jmenuje XCENA:

Dim db As Database, rs As Recordset
Set db = DBEngine.OpenDatabase("C:\KURS\DOMACNOST.MDB")
Set rs = db.OpenRecordset("VYDAJE")
rs.Index = "XCENA"
rs.Seek ">", 12.60

Jestliže v tabulce existuje řádek, jehož cena je větší než 12.60, stává se aktuálním řádkem. Je-li takových řádků více, aktuálním řádkem se stává první takový řádek (počítáno "seshora").

Řádek vyhovující dané podmínce nemusí existovat. Proto má objekt Recordset vlastnost NoMatch (nevyhovuje) typu Boolean (logická hodnota), která obsahuje indikaci výsledku předchozí metody Seek. Jestliže žádný záznam vyhovující podmínce nebyl nalezen, je hodnota vlastnosti NoMatch rovna True (pravda) a poloha ukazatele na aktuální řádek není definována. Jestliže řádek vyhovující podmínce byl nalezen, je hodnota NoMatch rovna False a ukazatel aktuálního řádku obsahuje nalezený řádek.

Jestliže je operátor porovnání  ">", ">=" nebo "=", pak metoda Seek prohledává index od začátku. Je-li operátor porovnání    "<" nebo "<=", pak metoda Seek  prohledává index od konce.

Metoda Requery

Metodou se vynutí aktualizace množiny dat, která tvoří zdroj dat objektu Recordset. Jestliže např. Recordset je výsledkem dotazu - příkazu Select z SQL čerpajícího ze zdrojové tabulky, v níž došlo ke změně, neodpovídají data objektu Recordset aktuálnímu stavu. Musí se tedy použít metoda, jejíž syntaxe je

rs.Requery

kde rs je daný objekt Recordset. Po jejím volání se aktuálním řádkem stává první řádek, nebo je BOF i EOF nastaveno na True, jestliže obnovená data neobsahují ani jeden řádek

Metoda Close

Metoda zavře otevřený objekt Recordset. Má syntaxi

rs.Close

kde rs je identifikátor otevřeného objektu třídy Recordset.

Jestliže před použitím metody Close byla metodou Edit započata aktualizace dat v aktuálním řádku, ale nebula metodou Update dokončena, změny se v tabulce dat neprovedou.

Vlastnosti objektu Recordset

Vlastnosti BOF, EOF

Viz metody Move.

Vlastnost EditMode

Hodnota typu Long, která lze pouze číst. Je rovna jedné z pojmenovaných konstant:

Vlastnost Index

Vlastnost je typu String a obsahuje buď prázdnou hodnotu nebo jméno indexu, který řídí zpracování. Lze použít jen u objektů Recordset typu tabulka relační databáze (tedy nikoliv u výsledku dotazu).

Vlastnost RecordCount

Vlastnost typu Long obsahující počet řádků (=záznamů) zpřístupněných daným objektem Recordset typu tabulka relační databáze, nebo již zpracovaných u objektu Recordset.

U objektů Recordset  typu výsledek dotazu se celkový počet řádků objeví, až když se řádky projdou všechny - přesněji až se ukazatel dostane nakonec. o lze nejjednodušeji zajistit posloupností volání metod

rs.MoveLast
rs.MoveFirst

 

 

Orig. 4 / 1999

Rev. 07 / 2002