Sunteți pe pagina 1din 85

Cap III. Utilizarea obiectelor in programare.

III.1 Obiecte.
III.1.1 Clase de obiecte, obiecte si colectii de obiecte.
Din cele prezentate pana acum, referitor la notiunea de obiect, putem sintetiza astfel:  Obiectul este o entitate bine definita(adica exista), care are o anumita structura, anumite caracteristici si anumite functii (realizeaza una sau mai multe actiuni). Un obiect se caracterizeaza prin: Proprietati - structura si atributele sale; Metode - actiunile pe care poate sa le efectueze; Evenimente - conditiile care determina momentul cand se lanseaza o anumita actiune(de exemplu Click pe un obiect). Exemplu. In aplicatia DAO.Mdb, in formularul F_CDialogContainer, exista un obiect cu numele Cmd. Acesta este un control buton de comanda, cu anumite proprietati(culoare, dimensiuni, pozitia in formular, textul afisat, etc.), care la evenimentul Click produs asupra sa executa o actiune(metoda) prin care se acceseaza o baza de date.  Clasa de obiecte contine toate definitiile unui obiect, adica tipurile de proprietati, metode si evenimente care vor determina structura unui obiect. Prin setarea caracteristicilor unei clase de obiecte(de exemplu atribuirea de valori proprietatilor) se obtine un obiect nou. Prin definirea unei clase de obiecte se creeaza practic un format, o structura pe care o vor avea toate obiectele ce se vor crea din aceasta. Relatia dintre o clasa de obiecte si obiectele care provin din ea este asemanatoare cu aceea dintre tipurile de date si variabile de tipul respectiv. Asa cum tipul de date este un concept, iar o variabila este materializarea(in memoria calculatorului) acestuia, tot asa clasa de obiecte este un concept, iar obiectele ce provin din ea reprezinta materializarea acesteia. Crearea unui nou obiect al unei clase, se numeste instanta a clasei respective. Exemplu. In Access, exista definite diferite clase de obiecte. De exemplu clasa Form, stabileste care este structura unui obiect formular, adica proprietatile(nume, culoare, dimensiuni, caption, etc.), evenimentele(open, close, click, etc.) si metode(refresh, requery, etc.). Formularul F_CDialogContainer, este o materializare(o instanta) a clasei Form, avand setate proprietatile

cu anumite valori, si atasate la anumite evenimente metode specifice prin scrierea unui cod de program.  Colectie de obiecte este constituita din totalitatea obiectelor care provin din aceeasi clasa de obiecte si care au din aceasta cauza aceleasi tipuri de proprietati si metode. Ele constituie deci instante ale aceleasi clase de obiecte. Obiectele dintr-o colectie pot fi privite si folosite ca un tablou de obiecte. Ele vor crea o structura de tip tablou, la care este posibila referirea la un anumit obiect prin indexul acestuia, deci printrun numar care reprezinta pozitia acestuia in tablou. Astfel la crearea primului obiect, acesta va primi indexul 0, la crearea celui de-al doilea indexul va fi 1, etc. O colectie de obiecte, deoarece, la randul ei reprezinta o entitate, cu propriile sale proprietati, constituie un obiect. Astfel o colectie de obiecte va avea printre altele proprietatile: Count - care contine numarul de obiecte din colectie; Parent . care contine obiectul superior din ierarhie de care apartine colectia; Numele obiectului colectie, este format din numele clasei de unde provin obiectele la care se adauga sufixul 's'. Exemplu. In aplicatia DAO.Mdb, in formularul F_CDialogContainer, colectia de obiecte Controls, contine toate obiectele control din formular. Procedura urmatoare, lansata de evenimentul DblClick, al sectiunii, trateaza colectia Controls, ca pe un tablou, afisand elementele componente ale acesteia(numarul acestora se gaseste in proprietatea Count) cat si obiectul de care apartine(proprietatea Parent). Private Sub FormHeader_DblClick(Cancel As Integer) ' Afiseaza obiectele ce se afla in colectia de controale a formularului Dim ST As String Dim i As Integer Dim N As Integer ST = '' ' Proprietatea Count a colectiei contine numarul de obiecte din colectie N = Me.Controls.Count - 1

For i = 0 To N 'Primul element dintr-o colectie are indexul 0 ST = ST & i & ': ' & Me.Controls(i).NAME & vbCr Next i ' Propritatea Parent a colectiei contine obiectul _ de care apartine colectia MsgBox ' Controalele din formularul parinte:' _

& vbCr & ''' ' & Me.Controls.Parent.NAME & _ ' '', sunt in ordine:' & vbCr & vbCr & ST ' vbCr este o constanta care determina saltul de rand _ la afisare vbCr = Chr(10) & Chr(13) End Sub

III.1.2 Provenienta obiectelor utilizate intr-o aplicatie.


Un obiect, asa cum am aratat este format atat din date(proprietati) cat si din cod de program(metode). Realizarea unei aplicatii prin crearea si utilizarea unor obiecte reprezinta o metoda moderna de programare, denumita programarea la nivel de obiect. Cel mai important avantaj al acestei metode este acela al utilizarii obiectelor create in mai multe aplicatii, ceea ce duc 434h71e e in afara de o crestere semnificativa a productivitatii la standardizarea aplicatiilor realizate. In Access obiectele din care se realizeaza o aplicatie pot proveni din mai multe surse: y Instante ale claselor de obiecte aflate in bibliotecile standard ale pachetului Access: DAO, Access Application si VBA. y Instante ale claselor de obiecte proprii(utilizator), create special de proiectant(prin modulele de clase de obiecte) y Instante ale unor clase de obiecte externe, realizate de aplicatii server sub forma unor controale sau biblioteci ActiveX realizate cu tehnologia(standardul industrial) Automation.

Utilizarea acestor clase de obiecte externe implica in prealabil, asa cum se va arata, crearea in aplicatia client(care foloseste obiectele produse de clasa respectiva) a unei referinte catre acestea.

III.1.3 Ierarhia obiectelor dintr-o aplicatie.


Obiectele folosite intr-o aplicatie se gasesc intr-o structura ierarhic-arborescenta. Fiecare element al acestei structuri apartine unei structuri superioare si la randul sau contine unul sau mai multe elemente de nivel inferior. De asemenea un element al acestei structuri poate fi constituit dintr-un obiect individual sau dintr-o colectie de obiecte. O aplicatie Access este realizata practic din doua categorii de obiecte, care provin din clasele celor doua modele de baza, respectand ierarhiile create in acestea: DAO - privind structurile de date; Access Application - privind interfata utilizator; Obiectele au de asemenea un nume, care poate fi implicit(adica stabilit de sistem) sau dat de utilizator. Deoarece exista posibilitatea ca mai multe obiecte sa aiba acelasi nume, atunci cand se face referire la un obiect este necesara calificarea numelui cu intreaga structura ascendenta a obiectelor de care acesta este dependent.(asemanator cu descrierea caii unui fisier sau folder de pe un disc). Acest lucru nu este obligatoriu daca nu se creeaza ambiguitati. Semnele de calificare sunt punctul (.) - care se foloseste in general pentru obiecte ale caror nume sunt date de sistem, sau semnul exclamarii(bang) (!), folosit la obiectele cu numele stabilit de utilizator. Referirea unei colectii se face folosind acelasi sistem, deoarece colectia este asa cum am vazut la randul ei un obiect. Referirea la un obiect dintr-o colectie se poate face in 3 feluri: y Fie folosind tot metoda prezentata, utilizand calificarea obiectului cu colectia din care face parte: <referirea la colectie> <semn de calificare> <numele obiectului> Exemplu: Me.Controls!CForm y Fie folosind indexarea colectiei cu un numar care reprezinta pozitia in colectie a obiectului respectiv(asemanator cu referirea unui element dintr-un tabel).

Numerotarea elementelor unei colectii de obiecte se porneste de la 0(zero). <referirea la colectie> <(> <numar in cadrul colectiei> <)> Exemplu: Me.Controls(0) y Fie la fel ca mai sus dar folosind - ca pe un sir de caractere - numele obiectului in loc de index <referirea la colectie> <(> <'nume obiect'> <)> Exemplu: Me.Controls('CForm') Obs erv atia 1. Daca se doreste sa se faca referire in codul VBA la formularul sau raportul 'parinte', fara a se mai face descrierea structurii ierarhice superioare, se poate folosi cuvantul cheie ME. Obs erv atia 2. Semnele care se pot folosi pentru a se specifica un obiect sunt parantezele drepte <[nume_obiect]>. Ele sunt folosite obligatoriu atunci cand in numele obiectului se gasesc spatii.

III.1.4 Utilizarea in cod VBA a proprietatilor si metodelor unui obiect.


Referirea la proprietatile sau metodele unui obiect, se face prin: metoda descrisa la punctul precedent pentru referirea obiectului; urmat de numele proprietatii sau metodei, folosind semnul de calificare 'punct'. y Utilizarea proprietatii unui obiect, in codul VBA, se face la fel ca si cum s-ar lucra cu o variabila obisnuita, in citire sau scriere. Daca se doreste atribuirea unei valori proprietatii unui obiect, atunci aceasta se introduce in partea din dreapta a unei instructiuni de atribuire; Exemplu de scriere a proprietatii Caption a unui formular: Me.Caption='Nume Nou Form' sau a proprietatii Index, a unui Recordset: Rs.Index='PrimaryKay' Daca se doreste citirea proprietatii unui obiect, atunci aceasta va face parte dintr-o expresie obisnuita. Exemplu de citire a proprietatii Caption a unui formular : MsgBox 'Numele formularului este: ' & Me.Caption. La utilizarea proprietatilor unui obiect trebuie sa se tina cont de urmatoarele doua restrictii: Nu toate proprietatile au posibilitatea sa li se schimbe valoarea. Aceste proprietati se numesc Read Only, si se folosesc numai in citire. Ca si o variabila, o proprietate este de un anumit tip de date, de care trebuie tinut cont in utilizarea ei. y Utilizarea metodelor unui obiect, in codul VBA, se face la fel ca si cum s-ar lucra cu o procedura, folosindu-se metoda de apelare fara Call, prin scrierea sub forma unei instructiuni a

metodei, urmata, daca este cazul, de parametrii acesteia(fara a fi introdusi intre paranteze) separati prin virgula. Exemplu de apelare a unei metode cu doi parametrii de tip string: Rs.Seek '=', 'unu'

III.1.5 Exemple de referire a obiectelor din modelul - Application Access


Modelul ierarhic Application, prin care se realizeaza instantele obiectelor si colectiilor care constituie interfata utilizator a unei aplicatii, este aratat succint in figura de mai jos. y Forms!Date - se face referire la formularul deschis cu numele ' Date'. y Forms![date de bilant] - se refera formularul deschis 'date de bilant'. Observati parantezele drepte folosite pentru ca numele formularului contine spatii. y Forms![vinzari].RecordSource - se face referire la proprietatea Record Source al formularului deschis 'vinzari'. Parantezele drepte pot fi scoase. Observati punctul, semnul de calificare pentru o proprietate sau metoda. y Forms![vinzari]!valoare - se refera controlul 'valoare' a formularul deschis 'vinzari'.

y Forms!('vinzari')!valoare - identic cu mai sus, dar se foloseste alta posibilitate de precizare a unui obiect dintr-o colectie si anume printr-un string care reprezinta numele obiectului. y Forms!(0)!valoare - identic cu mai sus, dar se foloseste precizarea unui obiect dintr-o colectie prin folosirea numarului de ordine al obiectului in cadrul colectiei.(am presupus ca formularul 'vinzari' a fost primul deschis, primind indexul 0 in cadrul colectiei Forms) y Me.FilterOn - se refera proprietatea FilterOn a formularului in care se gaseste codul VBA.

y Me!Altul.Visible - se refera proprietatea Visible a controlului 'Altul' a formularului in care se gaseste codul VBA Exemplu. Exemplul prezentat anterior, este reluat, dar executia lui nu se mai face chiar din formular, ci extern, din modulul de cod al aplicatiei. Din el se observa in special cum functioneaza colectia Forms, a formularelor deschise. Public Sub Col_Form_Controale()

' Afiseaza obiectele ce se afla in colectia de controale a primului formular deschis Dim ST As String Dim i As Integer Dim N As Integer ST = '' ' Proprietatea Count a colectiei contine numarul de obiecte din colectie On Error GoTo Fis ' Daca nu este nici un formular deschis se produce eroare N = Forms(0).Controls.Count - 1 On Error GoTo 0 For i = 0 To N 'Primul element dintr-o colectie are indexul 0 ST = ST & i & ': ' & Forms(0).Controls(i).NAME & vbCr Next i ' Propritatea Parent a colectiei contine obiectul de care apartine colectia MsgBox ' Controalele din formularul parinte:' & vbCr & _

''' ' & Forms(0).Controls.Parent.NAME & _ ' '', sunt in ordine:' & vbCr & vbCr & ST Sfirsit: Exit Sub Fis: MsgBox 'Nu exista nici un formular deschis', vbCritical Resume Sfirsit End Sub ------------------

N ota: Modelul DAO va fi tratat intr-un capitol separat.

III.1.6 Variabile obiect.


In programare variabilele sunt elementele prin care se fac referiri la date. Deoarece in programarea la nivel de obiect, entitatea care ia locul datelor este obiectul, este necesara definirea unor variabile specifice, variabile obiect, prin care sa se poata manipula mai eficient obiectele. O variabila obiect este asemanatoare unei variabile ce contine un anumit tip de date. Declararea ei se face cu aceleasi instructiuni(Dim, Public, Private sau Static) ca si la celelalte variabile. Variabilele obiect ocupa o zona de memorie de 32-bit(4-byte). Desi lucrul cu variabile obiect nu este deosebit de cel cu variabilele obisnuite, totusi ele au o caracteristica specifica si anume, intr-o variabila obiect nu se va gasi efectiv obiectul respectiv, ci o referire(adresa) la acesta. Astfel, daca avem o variabila de tip integer, AI, si executam AI=3, atunci efectiv in AI, vom avea pe 16 biti data(informatia) numerica 3. Daca mai declaram una BI si o facem egala cu AI, vom avea si in aceasta numarul 3. Acum, executand AI=5, se va schimba valoarea din AI, dar cea din BI va ramane neschimbata. AI si BI au deci existente independente. Nu acelasi lucru se intampla si in cazul variabilelor obiect. Daca (vezi urmatorul exemplu care se va da) avem o variabila obiect FM1, si introducem in ea un obiect, formularul F_CDialogContainer, atunci in FM1, vom avea nu formularul respectiv ci o referire(adresa) la aceasta. Tot asa daca mai declaram o variabila obiect, FM2, si introducem in ea ce se gaseste in FM1. Vom avea acum doua variabile obiect care vor referi acelasi obiect. Sa modificam acum o proprietate a lui FM1. Daca vom citi aceiasi proprietate din FM2, vom observa ca modificarea este efectuata si in acesta. Deci, cele doua variabile obiect nu au existente independente, ele referind practic acelasi obiect. Evident, in anumite prelucrari, acest lucru are importanta(ca in exemplul). Totusi in majoritatea prelucrarilor manifestarea variabilelor obiect este similara cu a celor clasice. III.1.6.1 Tipuri de variabile obiect. O variabila obiect se poate declara in mai multe feluri si anume ca:  Variabila obiect generica Dim nume_var As Object Variabila declarata in acest fel, este o variabila obiect generica, deoarece in ea se poate introduce orice obiect.

 Variabila obiect specifica Pentru fiecare obiect care se obtine dintr-o clasa vizibila in aplicatie, indiferent ca aceasta provine din bibliotecile standard, prin referinte la obiecte externe sau creata de utilizator, exista tipuri specifice de variabile obiect, cu acelasi nume ca al clasei respective. De asemenea, acelasi lucru se intampla si pentru colectiile de obiecte, existand tipuri specifice de variabile obiect cu numele acestora. Astfel pentru obiectele provenite din biblioteca Application Access, exista tipuri de variabile obiect: y y y y y y y Forms - colectia formularelor deschise; Form - pentru un obiect formular; Reports - colectia rapoartelor deschise; Form - pentru un obiect raport; Controls - pentru colectia tuturor controalelor dintr-un formular sau raport; Control - pentru un control dintr-un formular sau raport; etc.

Deoarece controalele, la randul lor provin din clase diferite de obiecte, exista pentru fiecare tip din acestea, variabile obiect specifice. Astfel mai sunt pentru controale urmatoarele tipuri specifice de variabile obiect: y y y y y y y y TextBox - pentru control caseta de text; ComboBox - pentru control lista ascunsa; ListBox - pentru control lista derulanta; CheckBox - pentru control boolean caseta de validare; Button - pentru control boolean buton radio; ToggleButton - pentru control boolean de tip tasta; CommandButton - pentru control buton de comanda; Label - pentru control eticheta;

etc.

-----------------Declararea unei variabile obiect specifice se face folosind numele clasei sau colectiei care va fi referita de variabila respectiva. Dim nume_var As tip_obiect Diferenta dintre utilizarea unei variabile obiect specifice sau generice, se refera la urmatorul aspect: La declararea unei variabile obiect generice, sistemul nu stie ce fel de obiect va fi in aceasta. Acest lucru se va cunoaste la prima incarcare cu un obiect al variabilei. In acest moment, se va configura variabila obiect cu proprietatile si metodele specifice tipului de obiect respectiv. Deci aceasta configurare este realizata in partea de executie a aplicatiei La declararea unei variabile obiect specifice, sistemul stie de la inceput care sunt proprietatile si metodele tipului de obiect respectiv. Deci configurarea variabilei este realizata in partea de compilare a aplicatiei si nu in cea de executie. Din aceasta cauza, executia cu acest tip de variabile este mai rapida Din cele prezentate se deduce ca este indicata utilizarea variabilelor obiect specifice. N ota: Desi nu s-a folosit in prezentare decat forma instructiunii Dim, pentru declararea variabilelor obiect si celelalte declaratii si anume Public, Private sau Static sunt valabile si functioneaza la fel ca la variabilele clasice. III.1.6.2 SET - Instructiunea de atribuire pentru variabile obiect. Instructiunea de atribuire pentru variabilele clasice este var = expresie. Totusi forma completa a acesteia este Let var = expresie, cuvantul Let, implicit introducandu-se pentru a arata ca este atribuita o valoare unei variabile clasice. Pentru variabilele obiect, la care atribuirea consta practic in crearea unei referinte catre un obiect, este obligatorie folosirea la instructiunea respectiva a cuvantului cheie SET. Deci pentru variabilele obiect instructiunea de atribuire este: Set var_obiect = expresie_obiect y in care expresie obiect este o expresie al carui rezultat este un obiect.

Efectul instructiunii de atribuire este introducerea in variabila obiect a adresei obiectului(referirea la acesta) care rezulta din expresia din dreapta si nu realizarea unei copii a obiectului respectiv.

Din aceasta cauza daca mai multe variabile refera acelasi obiect, orice modificare a acestuia(cauzata eventual prin una din variabile) va fi reflectata imediat de toate aceste variabile care refera obiectul respectiv (vezi exemplul care va urma). III.1.6.3 Eliberarea resurselor folosite de o variabile obiect. Cuvantul cheie NOTHING. O variabila obiect are nevoie de un spatiu(memorie) de lucru pentru a functiona. Acesta este eliberat automat, ca la orice variabila, la terminarea modulului in care a fost declarata variabila obiect. Daca totusi se doreste eliberarea imediata a spatiului ocupat de o variabila obiect se foloseste instructiunea: Set var_obiect = Nothing Exemplu. Public Sub Var_Obiect() ' Demonstraza ca o variabila obiect reprezinta referinta catre un obiect Dim ST As String Dim FM1 As Form Dim FM2 As Form On Error GoTo Fis ' Daca nu este nici un formular deschis se produce eroare Set FM1 = Forms(0) ' Var. obiect FM1, va contine referinta catre primul formular deschis MsgBox 'Primul formular deschis este: ' & FM1.NAME On Error GoTo 0 Set FM2 = Forms(0) ST = FM1.Caption ' Var. obiect FM2, va contine aceaiasi referinta ca variabila FM1 ' Proprietatea Caption a var obiect FM1 este salvata in ST

FM1.Caption = 'TEST Variabile Obiect' ' Se schimba proprietatea Caption in FM1 MsgBox FM2.Caption FM1.Caption = ST MsgBox FM2.Caption ' Schimbarea se face practic in obiectul referit. Deci si in FM2 ' Se reface proprietatea Caption. ' Aceasta schimbare se produce si in FM2

Set FM1 = Nothing Sfirsit: Exit Sub

' Se elibereaza spatiul ocupat de FM1

' La terminarea rutinei, se elibereaza spatiul ocupat de toate variabilele obiect _ declarate in el. Deci spatiul ocupat de FM2 se elibereaza si el Fis: MsgBox 'Nu exista nici un formular deschis', vbCritical Resume Sfirsit End Sub III.1.6.4 Crearea unei instante noi pentru o clasa de obiecte. Cuvantul cheie NEW. Cuvantul cheie New, se poate folosi atat la declararea unei variabile obiect cat si la instructiunea de atribuire Set. Dim nume_var As New tip_obiect Set var_obiect = New expresie_obiect Efectul acestuia se manifesta numai la clasele de obiecte create prin modulele de cod ale aplicatiei. El produce crearea unei noi instante pentru clasa respectiva, adica practic al unui spatiu separat de existenta pentru variabila respectiva. Nu trebuie confundat folosirea acestui cuvant cheie cu aceia de creare a unor obiecte noi in modelele standard ale Access(de exemplu nu se poate crea prin New, un control nou intr-un formular)

III.1.7 Parcurgerea unei colectii de obiecte. Instructiunea ForEach


In primul exemplu din acest capitol, s-a aratat cum pot fi parcurse cu o instructiune FOR obisnuita obiectele unei colectii, folosindu-se proprietatea Count a colectiei pentru stabilirea numarului de cicluri necesar. Acelasi lucru se poate face mai eficient cu forma speciala a instructiunii ForEach: For Each var_obiect In colectie_obiecte [instructiuni]

[Exit For] [instructiuni] Next var_obiect -----------------y Variabila obiect folosita, trebuie sa fie compatibila cu tipul colectiei specificate dupa cuvantul cheie IN. Functionarea buclei For consta in faptul ca la fiecare iteratie, variabilei obiect, var_obiect, i se va atribui pe rand cate un element al colectiei specificate. Deci instructiunea ForEach, va avea atatea cicluri cate obiecte contine colectia specificata in instructiune. Exemplu. Public Sub Afis_Forms() 'Afiseaza toate formularele deschise Dim FM As Form Dim ST As String ST = '' For Each FM In Forms ' FM va referi la fiecare ciclu un formular deschis ST = ST & ' ' & FM.NAME & vbCr Next If Len(ST) > 0 Then MsgBox 'Formulare deschise: ' & vbCr & vbCr & ST Else MsgBox 'Nici un formular nu este deschis' ' Nu s-a executat nici un ciclu din ForEach End If End Sub

-----------------N ota: Instructiunea For Each se poate folosi si pentru variabile de tip tablou (Array).

III.2 Utilizarea in Access a obiectelor provenite din clase externe. Folosirea controalelor standard Windows.
III.2.1 Utilizarea intr-o aplicatie a obiectelor create in alte aplicatii.
Platforma Windows, permite utilizarea intr-o aplicatie(numita client) a obiectelor provenite din alte aplicatii(numite server). Exista doua metode(standarde industriale) care permit acest lucru si anume: Metoda OLE(Object Linked and Embedded) Metoda Automation OLE(sau pe scurt Automation) III.2.1.1 Metoda OLE. Metoda OLE, permite ca intr-o aplicatie client sa se foloseasca obiecte provenite dintr-o aplicatie server, prin lansarea acesteia chiar in aplicatia client, in scopul manipularii obiectului respectiv. Lansarea aplicatiei server prin care a fost creat obiectul, se face de obicei prin dublu click pe acesta(sau din meniul contextual al obiectului). Evident, in cazul metodei OLE, este necesar ca aplicatia server sa fie instalata pe sistemul de calcul in care se utilizeaza aplicatia client. Exista doua forme de implementare a acestei metode, functie de locul unde va fi memorat obiectul respectiv, si anume: Embedded(incapsulare) - obiectul este memorat in aplicatia clint, avand o existenta independenta. Deci, obiectul respectiv va exista efectiv in ambele aplicatii si eventuala modificare a obiectului din aplicatia server, nu se va produce si in aplicatia client sau invers. In aplicatia DAO.mdb, in formularul F_OLE, este prezent un astfel de obiect creat in Word, si plasat in controlul ObiectOLE. Linked(legare) - obiectul va exista numai in aplicatia server, in aplicatia client memoranduse numai adresa acestuia pentru a putea fi folosit si din aceasta. Deci, obiectul respectiv daca va fi eventual modificat, ori in aplicatia server ori in aplicatia client, aceasta modificare se va realiza automat si in cealalta aplicatie(exista un singur obiect folosit de ambele aplicatii). III.2.1.2 Metoda Automation. Obiecte ActiveX. Automation este un standard industrial, care permite crearea de catre aplicatiile server a unor obiecte independente(acestea nu mai au nevoie de aplicatia server pentru a fi manipulate). Deci

un obiect creat prin aceasta metoda va putea fi utilizat intr-o aplicatie client, indiferent daca este sau nu instalata aplicatia server. Obiectele create prin metoda Automation, se numesc ActiveX. Ele pot fi controale sau biblioteci de obiecte, si sunt definite de clasele de obiecte aflate sau create de aplicatiile server. In Access exista doua functii prin care se pot folosi in VBA, obiecte ActiveX si anume: CreateObject, prin care se pot crea noi instante ale unui ActiveX. GetObject, prin care se poate utiliza un obiect ActiveX, creat deja si aflat intr-un fisier. Majoritatea produselor create de firma Microsoft, au implementat standardul Automation(ca si standardul OLE). Aplicatiile MS Office: Access, Excel, Word etc., ofera sub forma de ActiveX obiectele din bibliotecile standard. Deci o aplicatie Excel poate fi considerata ca un obiect ActiveX, si utilizata intr-o aplicatie Access. Evident pentru utilizarea unui obiect extern, este necesara cunoasterea structurii acestuia, a proprietatilor, metodelor si evenimentelor sale. In Access, structura unei biblioteci de obiecte se poate afla prin comanda View | Object Browser. Totusi aplicatiile MS Office nu pot crea clase noi de obiecte care sa furnizeze in exterior obiectele sub forma unor ActiveX. De exemplu in Access, se pot crea clase noi de obiecte, dar utilizarea obiectelor provenite din acestea este numai interna aplicatiei. Exemplu. In aplicatia DAO.mdb, in formularul F_OLE, la actionarea evenimentului click al butonului de comanda, este lansata procedura eveniment de mai jos, prin care se creeaza o instanta noua a unei aplicatii Excel, in care se deschide o foaie de calcul ce se gaseste intr-un fisier aflat in acelasi director cu aplicatia Access. Private Sub ButonExcel_Click() Dim DirectorAplicatie As String Dim AplicatiaMdb As String Dim BD As Database Dim i As Integer, j As Integer Dim App As Object Set BD = CurrentDb

AplicatiaMdb = BD.NAME ' Se preia numele complet al fisierului cu aplicatia curenta Do ' Se stabileste pozitia ultimului '', care delimiteaza directorul unde este fisierul i = InStr(j + 1, AplicatiaMdb, '') If i = 0 Then Exit Do j=i Loop DirectorAplicatie = Left(AplicatiaMdb, j) 'Directorul unde este fisierul cu aplicatia curenta Set App = CreateObject('Excel.Application') 'Se creaza un obiect ActiveX, Excel App.Visible = True 'Se face vizibil obiectul ActiveX, Aplicatia Excel 'Se deschide aplicatia Excel 'Foaie.xls' _ ce se gaseste in acelasi director cu aplicatia curenta App.Workbooks.Open DirectorAplicatie & 'Foaie.xls' End Sub -----------------Microsoft Visual Basic, este un produs care permite si crearea de clase noi de obiecte, care sa-si ofere obiectele sub forma unor ActiveX(controale, biblioteci) aplicatiilor client. In cele ce urmeaza ne vom referi la utilizarea in aplicatiile client(Access) a obiectelor create din clase de obiecte externe, prin folosirea standardului Automation.

III.2.2 Crearea referintei catre un obiect extern


La proiectarea unui formular(sau raport) Access, implicit, pe bara cu instrumente sunt plasate cele mai utilizate controale folosite, Text Box, Combo Box, Label, Option Button, Command Button, etc, care sunt livrate in pachetul Access. Totusi, realizarea standardizata a acestor controale de tipul unor ActiveX, prin tehnologia Automation, permite utilizarea intr-o aplicatie client, a tuturor controalelor provenite din clase de obiecte, indiferent de firma producatoare sau de aplicatia server in care au fost realizate.

Controalele ActiveX, se gasesc de obicei intr-un fisier cu extensia .OCX, in directorul C:WindowsSystem. Simpla plasare a acestora pe discul calculatorului, nu permite insa folosirea lor de catre aplicatia client. Pentru utilizarea unui control ActiveX, este necesar ca pentru acesta sa se creeze o referinta in aplicatia Access(sau alta aplicatie client). Operatia de creare intr-o aplicatie client a unei referinte catre un obiect extern, in vederea utilizarii acestuia se mai numeste inregistrarea obiectului. In Access, inregistrarea unui ActiveX, se face prin comanda: Tools | ActiveX Controls, prezentata in figura alaturata. Cele doua butoane ale comenzii, Register si Unregister, permit atat crearea cat si anularea referintelor la controale ActiveX. y Dupa actionarea butonului: Register, sistemul solicita utilizatorului sa introduca numele complet al fisierului care contine un ActiveX, pentru a-l inregistra. y Operatia inversa, de anulare a inregistrarii unui ActiveX, se face prin selectia unui control dupa care se apasa pe butonul Unregister. N ota: Asa cum am mai aratat, Access foloseste in principal 3 biblioteci, DAO, ACCESS, VBA. Totusi se pot folosi(cu aceiasi tehnologie, Automation, ca si la controalele ActiveX) si alte biblioteci create de aplicatii server. Pentru utilizarea acestora, dupa copierea fisierului cu biblioteca (de obicei cu extensia .OLB sau .DLL) in acelasi director, C:WindowsSystem, trebuie creata referinta printr-o comanda similara, Tools | References. N ota: Atat controalele cat si bibliotecile ActiveX, sunt considerate niste aplicatii independente. Utilizarea lor impune aceleasi restrictii privind drepturile de folosire(licenta) ca si la orice alt produs. III.2.2.1 Plasarea unui control ActiveX, intr-un formular(raport) Dupa inregistrare, introducerea intr-un formular(raport) a unui control ActiveX, se poate face in doua feluri:

1- Prin comanda 'Insert ActiveX Controls', lansata ori de pe bara cu instrumente ori din

meniul Access.
2- Prin plasarea controlului direct pe bara de instrumente(in cazul utilizarii frecvente a unui control ActiveX). Pentru aceasta se va proceda astfel:

y Se lanseaza comanda Customize, prin meniul contextual al oricarui taskbar. y Se pozitioneaza comanda Customize in pagina a doua, Commands. y In fereastra stanga, Categories, se selecteaza 'ActiveX Controls'. y Din fereastra din dreapta, Commands, se trage(Drag and Drop) cu mouse-ul controlul respectiv, pe bara de instrumente.

III.2.3 Controlul ProgressBar


Controlul ProgressBar, este folosit pentru a prezenta vizual cum evolueaza in timp executia unei operatii al carei nivel de realizare poate fi cuantificat numeric in codul de program, printr-o valoare care apartine unui anumit interval. ProgressBar, este deci definit prin: y Intervalul, denumit rangul controlului, care stabileste valorile extreme, minima si maxima, ale evolutiei procesului respectiv. Deci el defineste intreaga durata a operatiei. y Pozitia curenta a controlului, reprezentata printr-o valoare numerica aflata in intervalul definit de rangul controlului, care stabileste pozitia relativa pe care o are 'clepsidra' in control, adica cat din suprafata acestuia este umpluta(zona albastra din figura). ----------------- Aceste valori sunt introduse prin proprietatile cele mai semnificative ale controlului ProgressBar: Min - defineste valoarea minima a rangului(intervalului) controlului ProgressBar.

Max - defineste valoarea maxima a rangului(intervalului) controlului ProgressBar. Value - defineste valoarea pozitiei curente a controlului ProgressBar. Daca valoarea introdusa depaseste rangul, atunci se va produce o eroare de executie.  Restul proprietatilor controlului ProgressBar, sunt cele obisnuite de configurare a marginilor, de vizibilitate, etc. Doua proprietati specifice se refera la forma de afisare a controlului si anume: Orientation - pentru directia controlului, orizontal sau vertical; Scrolling - pentru felul in care se deplaseaza clepsidra, in scroll(continuu ca in exemplu) sau in trepte(standard). Exemplu. Mai jos se prezinta codul aflat in formularul F_ ProgressBar, din fisierul DAO.Mdb. Acesta simuleaza printr-un control ProgressBar, PBar, functionarea unui cronometru, care va fi initializat cu o valoare introdusa in caseta de text, CTimp si va porni automat dupa introducerea acesteia. Figura prezentata la inceputul acestui modul este cea a formularului in timpul executiei sale. Option Compare Database Option Explicit Private Sub Form_Open(Cancel As Integer) Me!PBar.Visible = False End Sub -----------------Private Sub CTimp_AfterUpdate() ' Dupa introducerea unei valori in TextBox Dim Timp As Variant Timp = Me!CTimp If IsNumeric(Timp) And Timp >= 1 Then ' Se stabileste domeniul de valori pentru controlul Progress Bar. Me!PBar.Max = Timp ' Valoarea maxima - pentru clepsidra controlului plina ' Controlul ProgressBar initial nu va fi vizibil.

Me!PBar.Min = 0

' Valoarea minima - pentru clepsidra controlului goala

Me!PBar.Value = Me!PBar.Max ' Valoarea initiala a clepsidrei controlului - umplut Me!PBar.Visible = True Me.TimerInterval = 1000 Else MsgBox 'Este necesar introducerea unui numar de secunde!!', vbCritical End If End Sub -----------------Private Sub Form_Timer() ' Se executa o data la fiecare secunda ' Se face vizibil controlul ' Se porneste intreruperea de timp cu o durata de 1 sec.

Me!CTimp = Me!CTimp - 1 ' Se decrementeaza contorul de secunde cu o unitate Me!PBar.Value = Me!CTimp ' se stabileste valoarea clepsidrei la nivelul actual al timpului ramas If Me!PBar.Value = 0 Then Me.TimerInterval = 0 Me!PBar.Visible = False End If End Sub -----------------N ota: Controlul ProgressBar, face parte din grupul de controale ActiveX, care se gasesc in fisierul COMCTL32.OCX, care face parte din pachetul de distributie al pachetului Visual Basic. ' Clepsidra s-a golit / timpul in sec. a expirat ' se opreste intreruperea de timp ' se face invizibil controlul Progress Bar

III.2.4 Controlul Common Dialog

Controlul Common Dialog este utilizat foarte des in aplicatiile Windows in special pentru introducerea unui nume complet de fisier(cu extensie si cale) in modulele de salvare sau deschidere de fisiere. Controlul este invizibil, fereastra specifica acestuia(vezi figura alaturata) devenind activa numai din momentul lansarii metodei Action* si pana cand se inchide fereastra acestuia prin 'apasarea' pe butoanele Open sau Cancel (echivalent cu butonul X al ferestrei). Configurarea controlului se face prin setarea unor proprietati ale acestuia, dar evident inainte de lansarea metodei Action.  Proprietatile cele mai utilizate in folosirea controlului in operatiile de salvare /deschidere de fisiere sunt: y Title - se introduce un text care se va afisa in partea de sus a controlului(zona albastra de titlu a ferestrei); y InitDir - reprezinta calea care va indica directorul al carui continut se vizualizeaza. Aceasta va fi afisata in zona Look in y DefaultExt - este o extensie care va fi intoarsa daca nu se specifica in mod explicit tipul fisierului. y Filter - prin acesta se configureaza caseta Files of Type, care va controla ce fisiere vor fi afisate din directorul selectat. Ea reprezinta un string, in care se introduc mai multe informatii(multiplu de 2) separate prin caracterul ( | ). O pereche de 2 informatii reprezinta: 1-Textul afisat in casuta(in exemplu Fisier Access) 2-Un nume de fisier(cu extensie) in care sunt permise caracterele generice (*,?) si care va genera o multime de nume care vor constitui un filtru pentru fisierele care se afiseaza. De exemplu perechea :

' Toate tipurile Access | *.md? ', va determina afisarea tuturor fisierelor care au extensia din 3 caractere dintre care primele doua sunt 'MD'. y FileName - corespunde numelui introdus in caseta File Name a controlului. Este folosit atat ca parametru de intrare(daca se doreste o initializare a casetei) dar in special ca parametru de iesire, deoarece aceasta proprietate va contine la iesire numele complet(cu cale si extensie) ales de utilizator prin folosirea controlului.  Asa cum am mai aratat metoda controlului este Action*. Exista 5 forme ale controlului specific pentru anumite operatii si anume: Action = 1; Open - se foloseste de obicei pentru preluarea din fereastra Windows Explorer, a unui nume complet de obiect, de obicei fisier, asupra caruia se vor efectua anumite prelucrari in citire; Action = 2; Save - se foloseste de obicei pentru introducerea unui nume complet de fisier (nou sau existent) care va fi creat(sau eventual rescris daca exista deja); Action = 3; Color - se foloseste pentru aflarea codului unei anumite culori selectionate dintr-o lista(de exemplu cu care se pot configura dinamic culorile unui control); Action = 4; Font - se foloseste pentru selectionarea dintr-o lista a unei fonte(de exemplu cu care se poate configura dinamic fonta folosita intr-un control Text Box); Action = 5; Print Iesirea din metoda se face prin apasarea butonului: y Open (Save) - care face ca proprietatea FileName, sa se configureze corespunzator, adica calea afisata + numele introdus + extensia implicita (daca numele nu o contine explicit) sau y Cancel** - care face ca proprietatea FileName, sa nu se modifice. Acelasi lucru se produce daca se inchide fereastra prin comanda Close de inchidere a ferestrei - butonul (X) din coltul dreapta sus. Ex plicati e . * Action, asa cum se vede si din utilizarea ei, este o proprietate. Totusi ea avand o actiune in momentul setarii ei(vizualizarea controlului in una din cele 5 forme specificate), practic se comporta ca o metoda. Versiunile mai noi ale controlului au introdus 5 metode, care se pot folosi in locul lui Action. Aceste metode sunt: ShowOpen, ShowSave, ShowColor, ShowFont, ShowPrinter. Ex plicati e . ** Daca se iese din controlul Common Dialog, prin butonul Cancel, se poate provoca aparitia unei erori de executie specifice, cu codul 32755, daca in prealabil se seteaza proprietatea acestuia CancelError cu True.

-----------------Exemplu. Functia CitireCD, se gaseste in formularul F_CdialogContainer al aplicatiei DAO.Mdb Private Function CitireCD() As Variant ' Intoarce numele complet introdus prin controlul Common Dialog _ Daca functia intoarce NULL atunci s-a iesit prin butonul Cancel din Common Dialog '-------------------------------------------------------------------------------------------------------------------' Parametrii de initializare pentru configurarea controlului Common Dialog 'Intrare - Titlul pus in caseta Common Dialog Me!CD.DialogTitle = 'Selectati fisierul cu Baza de date' 'Intrare - Extensia implicita a numelui de fisier introdus _ Se foloseste de obicel la Comanda de salvare Me!CD.DefaultExt = 'Mdb' 'Intrare - Directorul implicit pentru pozitionarea initiala a casetei Common Dialog Me!CD.InitDir = '' 'Intrare - Filtrul de selectie pentru fisierele afisate _ Se introduc cate doua informatii(separatorul este caracterul (|) _ pentru fiecare rand afisat in caseta de selectie: _ 1- Numele afisat pentru precizarea selectiei ce se efectueaza _ 2- Multimea numelor care se vor selectiona prin folosirea caracterelor generice (*) si (?) Me!CD.Filter = 'Fisier Access|*.Mdb|All|*.*' ' Comenzile posibile ce se pot efectua : _ Action = 1 - Open _ Action = 2 - Save _

Action = 3 - Color _ Action = 4 - Font _ Action = 5 - Print Me!CD.FileName = '' 'Initializare Me!CD.Action = 1 'Open - Se da controlul casetei Common Dialog 'Iesire - Numele complet(cu cale si extensie) a fisierului selectionat _ Daca se intoarce un string gol('') atunci s-a iesit prin apasarea pe Cancel If Me!CD.FileName = '' Then CitireCD = Null ' iesire prin Cancel Else CitireCD = Me!CD.FileName End If End Function -----------------N ota: Controlul Common Dialog, se gaseste in fisierul COMDLG32.OCX, care face parte din pachetul de distributie al pachetului Visual Basic.

III.3 Obiecte pentru acces la date - Data Access Objects DAO.


III.3.1 Structura DAO.
Data Access Objects(DAO) permite ca printr-un limbaj de programare sa se acceseze o baza de date - locala(din aplicatia curenta) sau din alta aplicatie(fisier). Ea permite gestionarea structurii(schema) si a informatiilor acesteia. Modelul DAO contine toate colectiile de obiecte si obiectele bazei de date, precum si o serie de rutine, constante, tipuri de date, help-uri, etc., necesare manipularii acestora.

Structura acesteia este data in figura de mai jos. Ea se refera la baza de date din fisierul DAO.mdb

Cateva din caracteristicile modelului DAO sunt prezentate in continuare. y In primul rand modelul DAO are o structura ierarhic arborescenta, al carui nivel superior il constituie obiectul DBEngine. Acesta este deosebit fata de celelalte obiecte din modelul DAO. El este singular si nu apartine nici unei colectii, fiind tratat ca o exceptie. Fiecare obiect din structura DAO face parte dintr-o colectie de obiecte. De asemenea el contine la randul sau una sau mai multe colectii de obiecte. Exemplu. Obiectul Tabela_A, este un obiect de tip TableDef, care face parte din colectia TableDefs, a bazei de date locale a aplicatiei DAO.mdb. El contine doua colectii de obiecte, Fields si Indexes. -----------------y Obiectele(cu exceptia celor din colectia Errors) au proprietatiProperty care sunt constituite in colectia de proprietati a obiectului respectiv - Properties. Fiecare obiect are o proprietate implicita. De obicei aceasta este proprietatea Value. Toate obiectele isi pastreaza numele in proprietatea Name. y Obiectele(exceptie obiectele Error) au posibilitatea ca prin metode de tip Create si Append sa creeze si adauge obiecte la colectiile de obiecte din structura lor. De asemenea cu metoda Delete se pot sterge obiecte din colectii y Unele obiecte sunt create deja (TableDef de exemplu) si se folosesc ca atare indicandu-se numele lor(cu regulile obisnuite de calificare), pe cand altele(Database sau Recordset), ca sa fie folosite, mai intai trebuie deschise cu metode de tip Open. Obiectele care se deschid au metode de inchidere Close. Totusi acestea se pot inchide si automat, atunci cand se termina modulul in care au fost declarate. y DAO contine 17 tipuri diferite de obiecte.

VBA va contine pentru toate tipurile de colectii, tipuri de date care au chiar numele colectiei. (De exemplu se pot crea pentru colectia care contine structura tuturor tabelelor din baza de date, variabile de tip TableDefs.) De asemenea, pentru obiectele care apartin unei colectii, VBA are alte tipuri de date care au tot numele colectiei, dar la singular. (De exemplu se poate folosi o variabila de tip TableDef, pentru a se introduce structura unei tabele).

III.3.2 Obiectul DBEngine.


DBEngine, asa cum am aratat este obiectul din varful modelului ierarhic arborescent DAO.

Folosirea lui intr-o aplicatie Access pentru referirea obiectelor din DAO, este optionala, el fiind considerat implicit. DBEngine contine intreaga structura DAO. Din alte aplicatii care au implementata tehnologia de transfer de date Automation (de exemplu: MS Excel, MS Word, Visual Basic etc.) daca se doreste folosirea unei baza de date Access, este obiectul catre care trebuie facuta aceasta operatie. DAO nu ofera posibilitatea crearii altor obiecte DBEngine. DBEngine contine doua colectii de obiecte: Workspaces si Errors.

III.3.3 Workspaces - spatiul(mediul) de lucru.


Workspace reprezinta suportul in care o baza de date poate fi utilizata, impreuna cu sistemul de securitate folosit. DAO poate functiona in doua medii specifice unor anumite tipuri de baze de date, si anume: y Microsoft Jet Workspace, care permite folosirea motorului Microsoft Jet, in care se pot utiliza baze de date Access(fisiere .mdb) sau surse ISAM : FoxPro, DBase, Paradox, Lotus. In felul acesta se pot crea aplicatii care pot 'lega' mai multe tipuri de baze de date. y ODBCDirect Workspace, prin care se pot accesa servere specializate de baze de date(de exemplu Microsoft SQL) prin metoda ODBC(Open Data Base Connectivity).

Aplicatii server/client. Metoda de realizare a unei aplicatii, in care cereri sau proceduri sunt
formulate de aplicatia client, urmand ca executia lor sa se faca pe serverul de aplicatie, care va contine baza de date(back-end server). Trebuie sa se faca distinctie intre un server de aplicatie si un server de fisiere. Urmatorul exemplu va lamuri acest lucru. Exemplu. Presupunem ca avem o baza de date(o colectie de date, specifice unei anumite activitati) si niste programe(aplicatii) care gestioneaza datele respective, adica le actualizeaza(adaugari, stergeri sau modificari) sau extrag informatiile necesare derularii activitatii respective. Aceasta aplicatie va trebui accesata de mai multi utilizatori. Astfel putem avea o companie de aviatie si pentru rezervarea locurilor la un zbor, mai multe agentii ale acesteia, raspandite geografic, trebuie sa stie precis care este starea ocuparii locurilor, iar in cazul unei noi rezervari, sa informeze imediat acest lucru. Evident trebuie sa avem o retea de calculatoare, cu baza de date a zborurilor plasata pe un anumit calculator, de unde sa fie accesata 'on line', de clienti(in special agentiile de turism).

Exista in continuare doua posibilitati de realizarea a acestui lucru si anume cu un server de fisiere sau un server de aplicatii. In primul caz, al serverului de fisiere, vom plasa pe un server baza de date, iar pe toate statiile de lucru de la agentii, programele aplicatiei. O cerere de prelucrare se va desfasura in felul urmator: se vor aduce prin retea, de la serverul cu datele la statia de lucru, toate informatiile de la toate zborurile companiei, aici se vor extrage datele de la zborul care intereseaza, dupa care, daca s-a facut o rezervare, va fi trimis acest lucru imediat la serverul de date. Observam ca pe retea se vor transmite atat informatii utile cat si cele care nu sunt necesare la un moment dat. O astfel de aplicatie, se numeste aplicatie client. In al doilea caz, al serverului de aplicatii, in afara bazei de date, pe server, vom avea si o parte din programele aplicatie si anume cele care acceseaza direct baza de date. La o statie de lucru - unde exista cealalta parte a programelor aplicatiei si anume interfata cu utilizatorul - o cerere de prelucrare(datele despre un zbor) va fi trimisa serverului de aplicatii. Acesta va efectua extragerea din baza de date numai a informatilor necesare, pe care le va trimite pe retea inapoi utilizatorului. Observam in acest caz, reducerea substantiala a informatiei transmise prin retea, ceea ce face aplicatia mult mai performanta, chiar daca este mult mai complexa. O astfel de aplicatie se numeste server/client. -----------------In cadrul acestui capitol, se va prezenta numai Microsoft Jet Workspace. Implicit, DAO are un spatiu de lucru, #Default Workspace# de tip Microsoft Jet, in care este plasata si baza de date locala. Obs erv atia 3. Cand se face referire la baza de date locala, referirea obiectelor poate sa nu contina nici DBEngine nici spatiul de lucru - Workspaces(0), deoarece amandoua sunt implicite. Prin metoda DBEngine, CreateWorkspace, se pot crea si alte obiecte Workspace, ce pot fi atasate in memorie colectiei Workspaces prin metoda Append. Exemplu. De creare a doua obiecte Workspace, unul de tip Microsoft Jet, celalalt ODBCDirect si de vizualizare a proprietatilor acestora. Sub Prop_Workspace() Dim WS1 As Workspace Dim WS2 As Workspace Dim WS As Workspace Dim PR As Property ' obiect din colectia Properties

' Se creaza doua spatii de lucru cu metoda CreateWorkspace _ - Microsoft Jet _ -ODBCDirect ' Parametrii sunt in ordine: _ 1.Numele spatiului de lucru _ 2.Numele utilizatorului care are acces la el _ 3.Parola _ 4.Tipul mediului de lucru, si anume se foloseste constanta: _ - dbUseODBC - Mediu ODBCDirect _ - dbUseJet - Mediu ODBCDirect Set WS1 = DBEngine.CreateWorkspace('WorkspaceODBC', 'admin', '', dbUseODBC) Set WS2 = DBEngine.CreateWorkspace('WorkspaceJet', 'admin', '', dbUseJet) ' Dupa crearea unui spatiu de lucru ODBC acesta se ataseaza _ in memorie colectiei Workspaces cu metoda Append Workspaces.Append WS1 ' Nu s-a folosit DBEngine, deoarece e implicit Workspaces.Append WS2 ' Colectia Workspace si proprietatile obiectelor din aceasta For Each WS In Workspaces If MsgBox('Spatiul :' & WS.NAME, vbOKCancel + vbCritical) = vbOk Then On Error Resume Next ' ignora erorile care pot aparea. Vezi colectia Errors For Each PR In WS.Properties MsgBox ' Proprietatea :' & PR.NAME & ' = ' & PR.Value Next PR

On Error GoTo 0 End If Next WS End Sub

' Reface sistemul de erori standard

N ota: Acest exemplu ca si celelalte din cadrul acestui modul se gasesc in fisierul DAO.mdb -----------------Un obiect Workspace, contine 3 colectii de obiecte, si anume: Databases - care va contine unul sau mai multe obiecte Database, in fiecare putandu-se deschide cate o baza de date, locala sau din afara. Users si Groups, prin care se implementeaza sistemul de protectie al spatiului de lucru. Aceste obiecte nu vor fi prezentate in acest modul.

III.3.4 Colectia Errors. Tratarea erorilor de executie in VBA.


Colectia Errors, functioneaza in contextul sistemului general de erori implementat in VBA, care va fi prezentat in cele ce urmeaza. III.3.4.1 Tratarea standard a unei erori de executie produsa in VBA. In momentul producerii unei erori de executie intr-o rutina, sistemul va intrerupe executia si va afisa mesajul din casuta alaturata, in care se poate vedea numarul erorii si o descriere sumara a acesteia(daca se lucreaza intr-un mediu Run Time, nu se va mai afisa nici aceasta descriere). In continuare utilizatorul poate apasa pe: y Butonul End - se opreste executia codului si se re initializeaza toate variabilele aplicatiei. Este evident ca sunt sanse mici ca aplicatia sa poata fi reluata de utilizator in conditii corecte. y Butonul Debug - se va afisa codul de program care a generat eroarea, cursorul de instructiuni(linia galbena) pozitionandu-se pe instructiunea care a produs eroarea si permitand utilizatorului sa depaneze eventual programul prin modificarea instructiunilor. Acest sistem se poate folosi numai in perioada de testare de catre proiectant a aplicatiei, pastrarea lui in exploatarea aplicatiei fiind extrem de periculoasa.

N ota: Butonul Debug este activ numai daca se lucreaza pe un fisier MDB, care are codul de program si in limbajul sursa(daca aplicatia este intr-un fisier de tip MDE, butonul este inactiv). Exemplu. Daca se introduce in variabila A2, de tip numeric, un caracter atunci se va afisa mesajul prezentat mai sus. De asemenea daca se va introduce 0 in A2 se va afisa mesajul de eroare datorita impartirii la 0. Public Function Eroare_Standard() As Variant ' Functie care va trata o eventuala eroare prin _ sistemul standard VBA de control al erorilor Dim A1 As Double Dim A2 As Double Dim R As Double A1 = 1000 A2 = InputBox('A2=') R = A1 / A2 'Daca o eroare se va produce pana aici, _ instructiunile ce urmeaza nu se vor mai executa!! MsgBox 'Rezultatul lui ' & A1 & '/' & A2 & '=' & R Eroare_Standard = R End Function III.3.4.2 Tratarea erorilor de executie prin module special create de proiectant. VBA, ofera posibilitatea ca la producerea unei erori de executie, sistemul sa dea controlul la un modul special creat de proiectant prin care sa se trateze in mod corespunzator eroarea. Un astfel de modul se numeste rutina de tratare a erorilor(Error-handling). De asemenea proiectantii de aplicatii pot folosi producerea unor erori previzibile, in vederea rezolvarii mai 'elegante' a unor cazuri normale de prelucrare. Controlul erorilor de executie se realizeaza prin doua instructiuni si doua obiecte create special in acest scop:

III.3.4.2.1 Instructiunea: On Error.

On Error, este o instructiune, care atunci cand este intalnita si executata, produce asupra codului VBA care urmeaza dupa aceasta, doua actiuni(indirecte):  Dezactivarea sistemului standard de tratare a erorilor de executie. Deci, daca dupa executia instructiunii On Error, in rutina respectiva se produce o eroare de executie, atunci nu mai este afisat mesajul de eroare pe care l-am prezentat inainte. De asemenea inversa acestei afirmatii este si ea valabila, adica daca intr-o rutina se produce o eroare de executie inainte de a se executa instructiunea On Error, se va continua prelucrarea prin sistemul standard de tratare a erorilor prin afisarea mesajului respectiv.  Pozitia pe care se va plasa cursorul de instructiuni, in cazul aparitiei unei erori de executie. Deci, daca dupa executia instructiunii On Error, in rutina respectiva se produce la un moment dat o eroare de executie, atunci aceasta va preciza si care este urmatoarea instructiune care se va executa in cazul producerii unui asemenea eveniment. Exista trei forme ale instructiunii On Error, functie de locul de unde se va continua executia in cazul aparitiei erorii de executie: 1. On Error GoTo eticheta - la producerea unei erori, prelucrarea va continua cu instructiunile care se gasesc dupa eticheta. Aceasta forma este folosita atunci cand se va folosi o rutina speciala pentru tratarea erorii, Errorhandling, care se va gasi dupa aceasta eticheta. N ota: O eticheta se declara printr-un nume scris la inceputul unei linii urmat de semnul doua puncte(:). O eticheta este vizibila numai in rutina in care a fost declarata. 2. On Error Resume Next - la producerea unei erori, prelucrarea va continua cu urmatoarea instructiune care se gasesc dupa aceea care a produs eroarea. Deci practic prin aceasta forma prelucrarea va continua fara a se mai executa instructiunea care a produs eroarea. 3. On Error GoTo 0 - reinstaleaza sistemul standard de tratare a erorilor. Exemplu. In procedura prezentata mai inainte, Prop_Workspace, deoarece exista anumite proprietati care nu au valoare si care ar provoca o eroare la executia instructiunii(MsgBox) care afiseaza mesajul cu valoarea proprietatii, prin incadrarea ei intre instructiunile On Error Resume Next si On Error GoTo 0, aceasta va fi practic ignorata in cazul producerii unui asemenea eveniment.
III.3.4.2.2 Instructiunea: Resume.

Resume, este instructiunea prin care se iese din rutina de tratare a erorilor(Error-handling).

Exista trei forme ale instructiunii Resume, functie de locul de unde se va continua executia dupa ce se termina executia rutinei de tratare a erorilor. 1. Resume eticheta - prelucrarea va continua cu instructiunile care se gasesc dupa eticheta. 2. Resume Next - prelucrarea va continua cu urmatoarea instructiune care se gasesc dupa aceea care a produs eroarea. Deci practic prin aceasta forma prelucrarea va continua dupa tratarea erorii, fara a se mai executa instructiunea care a produs eroarea. 3. Resume 0 sau Resume - prelucrarea va continua chiar cu instructiunea care a produs eroarea. Deci, dupa executia rutinei de tratare a erorii, se va relua executia instructiunii care nu sa putut executa.
III.3.4.2.3 Obiectul: Err.

Err, este un obiect care se gaseste in VBA, si care in momentul producerii unei erori, i se vor
seta automat de sistem proprietatile functie de eroarea produsa. Cele mai importante proprietati ale acestui obiect sunt: Number - care va contine numarul* erorii produse. Aceasta proprietate este implicita. Description - care va contine un text care expliciteaza aceasta eroare. Pentru ca sistemul sa incarce proprietatile la producerea unei erori, este necesar ca obiectul Err, sa fie initializat(golit). Acest lucru se face numai la: executia instructiunilor: On Error sau Resume; la terminarea rutinei care a produs ultima eroare, prin instructiunile: Exit Sub, Exit Function sau Exit Property; la comanda prin executia metodei Clear, a obiectului Err. Ex plicati e . * Numarul tuturor erorilor posibile se gaseste in Help, si se pastreaza in cazul trecerii la noi versiuni.
III.3.4.2.4 Structura unei rutine care are modul de Error-handling.

Function XYZ() On Error GoTo Fis ' activarea rutinei Error-handling ' Codul care poate genera eroarea. Sfirsit:

Exit Function ' Iesirea in cazul in care nu se produce nici o eroare se va face pe aici Fis: ' Modulul de tratare a erorii Resume . ' Instructiunea care urmeaza dupa executia modulului de tratare a erorii End Function Exemplu. In continuare se prezinta aceiasi functie de la inceput dar in care se prelucreaza eventuala eroare printr-un modul specializat. Public Function Eroare_Handling() As Variant ' Exemplu de control al erorilor printr-un modul specializat. Const Er_Div0 = 11 ' codul erorii de impartire la 0 Const Er_Tip = 13 ' codul erorii de data de alt tip Dim A1 As Double Dim A2 As Double Dim R As Double A1 = 1000 On Error GoTo Fis 'Producerea unei erori in continuare se va trata prin _ modulul care se afla dupa eticheta FIS Reia: A2 = InputBox('A2=') R = A1 / A2 MsgBox 'Rezultatul lui ' & A1 & '/' & A2 & '=' & R Eroare_Handling = R Sfirsit:

Exit Function ' Iesirea din functie se face numai pe aici Fis: If err.Number = 11 Or err.Number = 13 Then If MsgBox(' - S-a produs o eroare datorita datei introduse' & vbCr & _ 'Reintroduce-ti data?', vbExclamation + vbYesNo) = vbYes Then Resume Reia ' Se reia de la introducerea valorii pentru A2 _ se reseteaza ERR, pentru a fi functional in cazul producerii unei alte erori Else Eroare_Handling = Null Resume Sfirsit ' Se termina functia fara a se reintroduce data _ functia va intoarce NULL in acest caz End If Else ' Se produce o alta eroare care va fi afisata, _ dupa care se opreste executia functiei MsgBox 'Eroare Nr=' & err & ' - ' & err.Description Resume Sfirsit End If End Function ------------------

N ota: In cazul in care se produce o eroare intr-o rutina(A) care nu are modul de tratare a erorii, dar ea este apelata de o alta rutina(B) care are un astfel de modul, eroarea va fi tratata de modulul de eroare al acesteia din urma(B).
III.3.4.2.5 Colectia Errors si obiecte Error.

In cazul in care un obiect DAO va provoca o eroare de executie, exista posibilitatea generarii mai multe erori in cascada. Dupa producerea unei asemenea erori, in colectia Errors, se va crea un obiect Error - similar obiectului prezentat anterior Err din VBA - pentru fiecare eroare generata. In acelasi timp, prima eroare produsa va seta si obiectul VBA - Err. Deoarece Err reprezinta un singur obiect, acesta nu va putea prelua decat datele despre o singura eroare, si anume prima produsa. Colectia Errors, pentru a functiona corect, trebuie sa aiba sterse toate obiectele Error componente. Aceasta actiune sistemul o efectueaza in momentul executiei unei noi operatii DAO. In cazul in care se doreste o prezentare detaliata a erorilor de executie produse de un obiect DAO, se pot folosi obiectele Error ale colectiei Errors ca in exemplul urmator: Exemplu. Sub Eroare_DAO() Dim WS0 As Workspace Dim WS1 As Workspace Dim DB1 As Database Dim DB2 As Database Dim RS As Recordset Dim A As Integer Dim EROARE As String Dim ER As Error ' Obiect al colectiei Errors On Error GoTo Fis ' Producerea unei eventuale erori va da controlul la instructiunile de la eticheta FIS

Set WS0 = Workspaces(0) ' DAO - corect Set WS1 = Workspaces(1) ' eroare DAO - nu este creat obiectul Set DB1 = CurrentDb ' DAO - corect

Set RS = DB1.OpenRecordset('NoTable') ' eroare DAO Set DB2 = OpenDatabase('NuExistaBaza') ' eroare DAO Set RS = DB1.OpenRecordset('Tabela_A') ' DAO - corect A = 10 / 0 ' eroare dar nu din DAO Sfirsit: Exit Sub Fis: EROARE = '' ' Introduce in variabila Eroare, pentru fiecare obiect din colectia Errors, _ cite un rand For Each ER In Errors EROARE = 'Eroare DAO nr=' & ER.Number & ' - ' & ER.Description & vbCr Next If Errors(0).Number = err.Number Then ' Eroare ce provine din DAO, deoarece si primul obiect din colectia Errors si _ obiectul Err au acelasi numar de eroare MsgBox EROARE, vbCritical Else ' Eroare ce nu se produce in DAO MsgBox 'Eroare VBA nr=' & err.Number & ' - ' & err.Description, vbExclamation

End If Resume Next ' trece la executia urmatoarei instructiuni End Sub

III.3.5 Colectia Databases


Colectia Databases, contine obiecte Database, care contin descrierea completa a structurii si informatiile dintr-o baza de date. Pentru ca o baza de date(sau un obiect component) sa fie accesata, aceasta trebuie mai intai deschisa, operatie care produce crearea unui obiect Database, care se va adauga automat la colectia Databases. VBA, contine tipurile de date Databases si Database care permit declararea de variabile specifice. Deschiderea unei baze de date se poate face in urmatoarele doua moduri:  Cu functia CurrentDb, care intoarce un obiect de tip Database, care contine baza de date locala, adica aceea definita in aplicatie. Dim Db As Database Set Db = CurrentDb  Prin metoda Workspace, OpenDatabase, care permite descrierea unei baze de date externe ( care poate sa fie chiar in format ISAM - FoxPro, Dbase, Paradox). Dim Db As Database Set Db = [workspace].OpenDatabase (dbnume [, options] [, read-only] [, connect]) Asa cum se observa, singurul parametru obligatoriu este: Dbnume - numele complet(cu extensie si cale) al fisierului care contine baza de date. Daca nu se precizeaza, spatiul de lucru este cel implicit(Default Workspace) -----------------Obiectul Database, contine urmatoarele colectii in care sunt incluse toate informatiile referitoare la baza de date respectiva. y TableDefs Structura tabelelor bazei de date.

y y y y

QueryDefs Cererile din baza de date. Relations Relatiile din baza de date. Recordsets Inregistrarile(datele) din tabelele bazei de date. Containers Informatii de securitate despre obiectele din baza de date.

N ota: Referirea colectiilor si a obiectelor din baza de date se face prin calificarea acestora, de jos in sus, trecand prin toate colectiile si obiectele ascendente pana la, obligatoriu, cel putin nivelul bazei de date. Exemplu. In baza de date DAO.Mdb, pentru a se referi obiectul campul 'N' al tabelei 'Tabela_A' in vederea afisarii proprietatilor Name si Type, se face: Dim Db As Database Dim Fd as Field Set Db = CurrentDb Set Fd = Db.TableDefs!Tabela_A.Fields!N ' In variabila Fd se introduce obiectul campul N Msgbox 'Campul cu numele :' & Fd.Name & ' este de tip :' & Fd.Type -----------------Obiectul Database, contine metode prin care: y se pot crea obiecte noi si atasa colectiilor din structura sa:

CreateTableDef - pentru crearea unui obiect cu structura unei tabele noi si adaugarea acestuia la colectia TableDefs; p.Properties.Append ; CreateRelation - pentru crearea unei relatii noi si adaugarea acesteia la colectia Relations; CreateQueryDef - pentru crearea unei cereri noi si adaugarea acesteia la colectia QueryDefs; CreateProperty - pentru definirea unei noi proprietati a bazei de date sau a altui obiect DAO(adaugarea acesteia la colectia de proprietati a bazei de date se face prin metoda Append, a colectiei Properties);.

se pot defini si deschide obiecte Recordset prin metoda OpenRecordset

Exemplu. Public Sub Prop_Database(Optional BazaDate as Variant) 'Afiseaza proprietatile bazei de date locale - daca lipseste parametrul 'BazaDate' _ sau a unei baze de date externe - cu numele fisierului in parametrul 'BazaDate' Dim DB As Database Dim PR As Property 'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else Set DB = OpenDatabase(BazaDate) End If '---------------------------MsgBox 'Proprietatile bazei de date :' & DB.NAME, vbCritical ' Proprietatea Name a bazei de date contine _ numele complet(cu extensie si path) al fisierului care o contine On Error Resume Next ' Pentru a nu se opri prelucrarea daca apare o eroare _ datorata faptului ca unele proprietati nu au valoare For Each PR In DB.Properties MsgBox ' Proprietatea :' & PR.NAME & ' = ' & PR.Value, vbInformation Next PR 'Baza de date din alta aplicatie 'Baza de date din aplicatia curenta

On Error GoTo 0 ' Reface sistemul standard de tratare a erorilor End Sub

III.3.6 Colectia Containers


Colectia Containers a unei baze de date, contine informatii despre toate obiectele existente(salvate) intr-o baza de date Access, fie ca provin din structura DAO fie din alte aplicatii. Ea este constituita din 8 obiecte Container. Fiecare din acestea contine descrierea tuturor obiectelor de un anumit tip din baza de date(de exemplu formulare). Aceasta descriere se face printr-o noua colectie, Documents, in care fiecare obiect Document, va contine prin proprietatile sale, informatiile(nume, permisiuni, etc.) despre un obiect de tipul respectiv existent(salvat) in baza de date. Din cele 8 obiecte Container, 3 provin din structura DAO: Databases - Baza de date curenta(deschisa) Tables* - Toate tabelele si cererile din baza de date Relationships - Toate relatiile permanente 4 din MS Access: Forms - Formularele salvate in baza de date. Modules - Modulele de cod Reports - Rapoartele salvate in baza de date. Scripts - Macro instructiunile 1 din sistemul de administrare(protectie) SYSrel -----------------Deoarece colectiile Containers si Documents, reflecta structura unei baze de date, este evident ca nu este permisa crearea sau stergerea de obiecte din aceste colectii. Ex plicati e . * In colectia Tables, se va observa existenta unor tabele, care incep cu prefixul 'MSyS'. Acestea reprezinta tabelele sistem ale MS Access.

N ota: Desi au acelasi nume nu trebuie confundat obiectul Container Forms sau Reports(care contine informatii despre toate formularele /rapoartele din baza de date) si colectia Access(Application) Forms sau Reports(care contine chiar formularele /rapoartele, dar numai pe cele care sunt deschise in momentul respectiv) Exemplu. Prin procedura de mai jos se pot cunoaste care sunt toate obiectele existente intr-o baza de date(locala sau externa). Acest lucru se obtine prin proprietatea Name a obiectelor Document din fiecare obiect Container a colectiei Containers. Public Sub Structua_Containers(Optional BazaDate) 'Structura colectiei - Containers 'Obiectele colectiei Containers sunt: ' 0=Databases ' 1=Forms ' 2=Modules ' 3=Relationships ' 4=Reports ' 5=Scripts - macro ' 6=SYSrel ' 7=Tables - tabele si query '----------------------------------------------Dim DB As Database Dim CT As Container Dim DC As Document 'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else 'Baza de date din aplicatia curenta

Set DB = OpenDatabase(BazaDate) End If '---------------------------For Each CT In DB.Containers

'Baza de date din alta aplicatie

' Parcurge colectia de Containers

If MsgBox('Container : ' & CT.NAME, vbOKCancel + vbCritical) = vbOk Then For Each DC In CT.Documents ' Parcurge colectia de Documente ale containerului If MsgBox('Documentul ' & CT.NAME & ' /' & DC.NAME, vbOKCancel + vbExclamation) = vbOk Then Else Exit For End If Next DC End If Next CT '----------------DB.Close ' Nu e necesara deoarece la sfirsitul procedurii toate obiectele declarate _ in aceasta se inchid si elibereaza automat variabilele obiect folosite End Sub Exemplu. Formularul F_CDialogContainer are doua controale Combo Box, CForm si CRap, si un buton de comanda Cmd. La actionarea butonului Cmd, printr-un control Common Dialog CD, se poate alege o baza de date externa sau baza de date locala(daca se iese din CD cu Cancel).

In urma acestei actiuni cele doua controale, CForm si CRap, vor avea ca lista de valori numele formularelor respectiv rapoartelor din baza de date specificata, al carui nume se va afisa in titlul formularului. Codul de program al acestui formular este: Private Sub Cmd_Click() Dim NF As Variant Dim DB As Database Dim DOC As Document Dim Formulare As Variant Dim Rapoarte As Variant Reia: NF = CitireCD ' foloseste controlul Common Dialog pentru preluarea unui nume complet de fisier On Error GoTo Fis 'Deschide Baza de date precizata prin controlul Common Dialog _ - daca nu se introduce un nume valid se va produce _ o eroare tratata prin modulul specializat 'FIS' If IsNull(NF) Then Set DB = CurrentDb 'Baza de date locala

Me.Caption = 'Baza de date locala' Else Set DB = OpenDatabase(NF) Me.Caption = 'BD:' & NF End If On Error GoTo 0 ' din nou sistemul standard de erori 'Baza de date din alta aplicatie selectionata prin CD

'===Se configureaza un string cu formularele existente(separate cu ;) in BD deschisa _ cu care se configureaza proprietatea RowSource a controlului Combo CForm Formulare = Empty For Each DOC In DB.Containers('Forms').Documents 'Se pargurg toate form. salvate Formulare = Formulare & DOC.NAME & ';' Next DOC If IsEmpty(Formulare) Then ' Nu exista nici un formular in Baza de date deschisa Me!CForm.RowSource = 'Nici un Formular!!' Else ' Se configureaza cu numele formularelor lista de valori a controlului Combo Me!CForm.RowSource = Left(Formulare, Len(Formulare) - 1) End If '===Se configureaza un string cu rapoartele existente(separate cu ;) in BD deschisa _ cu care se configureaza proprietatea RowSource a controlului Combo CRap Rapoarte = Empty For Each DOC In DB.Containers('Reports').Documents 'Se pargurg toate rap. salvate Rapoarte = Rapoarte & DOC.NAME & ';' Next DOC If IsEmpty(Rapoarte) Then ' Nu exista nici un raport in Baza de date deschisa Me!CRap.RowSource = 'Nici un Raport!!' Else ' Se configureaza cu numele rapoartelor lista de valori a controlului Combo Me!CRap.RowSource = Left(Rapoarte, Len(Rapoarte) - 1) End If Sfirsit:

Exit Sub Fis: If MsgBox(' - Fisierul introdus nu este o Baza de date Access!!' & vbCr & _ 'Il reintroduce-ti ?', vbExclamation + vbYesNo) = vbYes Then Resume Reia ' Se reia introducerea prin controlul Common Dialog Else Me.Caption = ' ???? ' Resume Sfirsit ' Se renunta End If End Sub '========Functii interne========= Private Function CitireCD() As Variant ' Intoarce numele complet introdus prin controlul Common Dialog _ Daca functia intoarce NULL atunci s-a iesut prin butonul Cancel din Common Dialog '-------------------------------------------------------------------------------------------------------------------' Parametrii de initializare pentru configurarea controlului Common Dialog 'Intrare - Titlul pus in caseta Common Dialog Me!CD.DialogTitle = 'Selectati fisierul cu Baza de date' 'Intrare - Extensia implicita a numelui de fisier introdus _ Se foloseste de obicel la Comanda de salvare Me!CD.DefaultExt = 'Mdb'

'Intrare - Directorul implicit pentru pozitionarea initiala a casetei Common Dialog Me!CD.InitDir = '' 'Intrare - Filtrul de selectie pentru fisierele afisate _ Se introduc cate doua informatii(separatorul este caracterul (|) _ pentru fiecare rand afisat in caseta de selectie: _ 1- Numele afisat pentru precizarea selectiei ce se efectueaza _ 2- Multimea numelor care se vor selectiona prin folosirea caracterelor generice (*) si (?) Me!CD.Filter = 'Fisier Access|*.Mdb|All|*.*' ' Comenzile posibile ce se pot efectua : _ Action = 1 - Open _ Action = 2 - Save _ Action = 3 - Color _ Action = 4 - Font _ Action = 5 - Print Me!CD.FileName = '' 'Initializare Me!CD.Action = 1 'Open - Se da controlul casetei Common Dialog 'Iesire - Numele complet(cu cale si extensie) a fisierului selectionat _ Daca se intoarce un string gol('') atunci s-a iesit prin apasarea pe Cancel If Me!CD.FileName = '' Then CitireCD = Null ' iesire prin Cancel Else CitireCD = Me!CD.FileName End If

End Function

III.3.7 Colectia TableDefs


Colectia TableDefs, contine obiecte de tip TableDef, fiecare din acestea reprezentand structura(nu datele introduse) unei tabele din baza de date deschisa. Numele obiectului TableDef, este chiar acela al tabelei respective. Fiecare obiect TableDef, contine proprietatile specifice tabelei(Validation Rule, Validation Text, sirul de conectare pentru tabelele legate, etc.) Exemplu. Procedura urmatoare afiseaza numele(Name) si valoarea(Value) proprietatilor tuturor tabelelor dintr-o baza de date deschisa Sub Prop_TableDef() ' Proprietatile tabelelor _ -Name : numele proprietatii respective _ -Value(implicita) : Valoarea pe care o are o proprietate Dim DB As Database Dim TD As TableDef Dim PR As Property Set DB = CurrentDb For Each TD In DB.TableDefs If MsgBox('Tabela : ' & TD.NAME, vbOKCancel + vbCritical) = vbOk Then On Error Resume Next For Each PR In TD.Properties MsgBox ' Proprietatea :' & PR.NAME & ' = ' & PR Next PR On Error GoTo 0 End If

Next TD DB.Close End Sub -----------------Fiecare obiect TableDef, contine la randul sau alte doua colectii, si anume: y Colectia Fields - formata din obiecte Field, fiecare din acestea descriind prin proprietatile sale(Nume, Tip de data, Regula de validare pentru camp, Caption, Size, etc.) un camp al tabelei. y Colectia Indexes - formata din obiecte Index, care la randul lor contin fiecare o colectie de campuri, Fields. Exemplu. Tabela_A din fisierul DAO.Mdb, prezentata schematic in figura de la inceputul modulului, contine: y y y Colectia Fields cu 2 obiecte Field, [N] si [A]. Colectia Indexes cu 2 obiecte, si anume: PrimaryKey, care la randul lui contine: Colectia Fields cu un obiect - [N] y A, care la randul lui contine: Colectia Fields cu un obiect - [A] Ex plicati e . Fiecare index reprezinta un obiect cu un nume(care e deobicei numele campului sau pentru cheia primara PrimaryKey), urmand ca prin colectia Fields al indexului sa se specifice care este efectiv numele campului din tabela. Deci se poate ca numele indexului si al campului sa nu fie acelasi, sau chiar ca un index sa fie definit pe mai multe campuri. Exemplu. Public Sub Structua_TableDefs(Optional BazaDate) 'Structura colectiei de tabele - TableDefs Dim DB As Database Dim TD As TableDef

Dim FD As Field 'Cimpurile tabelei Dim ID As Index Dim FID As Field 'Cimpurile indexului 'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else Set DB = OpenDatabase(BazaDate) End If '---------------------------For Each TD In DB.TableDefs ' Parcurge colectia de Tabele 'Baza de date din alta aplicatie 'Baza de date din aplicatia curenta

If MsgBox('Tabela : ' & TD.NAME, vbOKCancel + vbCritical) = vbOk Then For Each FD In TD.Fields ' Parcurge colectia de Cimpuri ale tabelei

If MsgBox('Cimpul: ' & TD.NAME & ' /' & FD.NAME, vbOKCancel + _ vbExclamation) = vbOk Then Else Exit For End If Next FD '------------------------For Each ID In TD.Indexes ' Parcurge colectia de Indexi ale tabelei

If MsgBox('Indexul: ' & TD.NAME & ' /' & ID.NAME, vbOKCancel + _ vbInformation) = vbOk Then

For Each FID In ID.Fields ' Parcurge colectia de Cimpuri ai indexului If MsgBox('Cimpul indexului: ' & TD.NAME & ' /' & ID.NAME & ' /' & _ FID.NAME, vbOKCancel + vbExclamation) = vbOk Then Else Exit For End If Next FID End If Next ID End If Next TD '--------------DB.Close ' Nu e necesara deoarece la sfirsitul procedurii toate obiectele _ declarate in aceasta se inchid si elibereaza automat variabilele obiect folosite End Sub Exemplu. Formularul F_TableDef are doua controale Combo Box, CTabel si CCimp. La deschiderea formularului(evenimentul Open), CTabel va avea completata lista de valori cu numele tabelelor din baza de date locala. La introducerea unei nume de tabel in CTabel(evenimentul After Update), se completeaza lista de valori a controlului CCimp cu numele campurilor tabelei respective. Codul de program al acestui formular este: Private Sub Form_Open(Cancel As Integer) Dim DB As Database

Dim TB As TableDef Dim sTabele As Variant Set DB = CurrentDb 'Baza de date locala '===Se configureaza un string cu tabelele existente(separate cu ;) in BD deschisa _ cu care se configureaza proprietatea RowSource a controlului Combo CTabel sTabele = Empty For Each TB In DB.TableDefs 'Se pargurg toate tabelele sTabele = sTabele & TB.NAME & ';' Next TB If IsEmpty(sTabele) Then ' Nu exista nici un tabel Me!CTabel.RowSource = 'Nici un tabel??!!' Else ' Se configureaza cu numele tabelelor lista de valori a controlului Combo Me!CTabel.RowSource = Left(sTabele, Len(sTabele) - 1) End If End Sub Private Sub CTabel_AfterUpdate() Dim DB As Database Dim FD As Field Dim sCimpuri As Variant Set DB = CurrentDb 'Baza de date locala '===Se configureaza un string cu cimpurile existente (separate cu ;) in tabela Me!CTabel _ cu care se configureaza proprietatea RowSource a controlului Combo CCimp sCimpuri = Empty

For Each FD In DB(Me!CTabel).Fields 'Se pargurg toate cimpurile tabelei sCimpuri = sCimpuri & FD.NAME & ';' Next FD If IsEmpty(sCimpuri) Then ' Nu exista nici un cimp Me!CCimp.RowSource = 'Nici un Cimp??!!' Else ' Se configureaza cu numele cimpurilor lista de valori a controlului Combo Me!CCimp.RowSource = Left(sCimpuri, Len(sCimpuri) - 1) End If End Sub -----------------Asa cum la nivelul obiectului bazei de date exista metoda CreateTableDef, pentru crearea structurii unei tabele, tot asa la nivelul unui obiect TableDef, exista metoda CreateField, prin care se pot defini campuri, care dupa aceea se pot adauga prin metoda Append, la colectia de campuri a obiectului TableDef.

III.3.8 Colectia QueryDefs.


Colectia QueryDefs, este foarte asemanatoare colectiei TableDefs, cu specificarea faptului ca obiectele QueryDef componente, adica structura cererilor din baza de date curenta, in locul colectiei de indecsi vor avea o colectie de parametrii. Colectia QueryDefs, contine obiecte de tip QueryDef, fiecare din acestea reprezentand structura(nu datele introduse) unei cereri salvate din baza de date deschisa, numele acestora fiind acelasi cu al cererii respective. Fiecare obiect QueryDef, contine proprietatile specifice ale cererii. Exemplu. Sub Prop_QueryDef() ' Proprietatile cererilor _ -Name : numele proprietatii respective _ -Value(implicita) : Valoarea pe care o are o proprietate

Dim DB As Database Dim Qry As QueryDef Dim PR As Property Set DB = CurrentDb For Each Qry In DB.QueryDefs If MsgBox('Cererea :' & Qry.NAME, vbOKCancel + vbCritical) = vbOk Then On Error Resume Next For Each PR In Qry.Properties MsgBox ' Proprietatea :' & PR.NAME & ' = ' & PR Next PR On Error GoTo 0 End If Next Qry DB.Close End Sub -----------------Fiecare obiect QueryDef, contine la randul sau alte doua colectii, si anume: y Colectia Fields - formata din obiecte Field, fiecare din acestea reprezentand un camp al cererii. y Colectia Parameters - formata din obiecte Parameter, daca cererea a fost creata cu parametrii. Exemplu. Cerere_A din fisierul DAO.Mdb, prezentata schematic in figura de la inceputul modulului, contine: y y Colectia Fields cu 3 obiecte Field: [N] , [A] si [A1] Colectia Parameters cu 1 obiect Parameter : [Numar]

Exemplu. Public Sub Structua_QueryDefs(Optional BazaDate) 'Structura colectiei de cereri - QueryDefs Dim DB As Database Dim Qry As QueryDef Dim FD As Field Dim PT As Parameter 'Cimpurile cererii 'Parametrii cererii

'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else Set DB = OpenDatabase(BazaDate) End If '---------------------------For Each Qry In DB.QueryDefs ' Parcurge colectia de Cereri 'Baza de date din alta aplicatie 'Baza de date din aplicatia curenta

If MsgBox('Cererea : ' & Qry.NAME, vbOKCancel + vbCritical) = vbOk Then For Each FD In Qry.Fields ' Parcurge colectia de Cimpuri ale cererii

If MsgBox('Cimpul: ' & Qry.NAME & ' /' & FD.NAME, vbOKCancel + _ vbExclamation) = vbOk Then Else Exit For End If Next FD

'------------------------For Each PT In Qry.Parameters ' Parcurge colectia de Parametri ai cererii

If MsgBox('Parametrul: ' & Qry.NAME & ' /' & PT.NAME, vbOKCancel + _ vbInformation) = vbOk Then Else Exit For End If Next PT End If Next Qry DB.Close End Sub -----------------La nivelul obiectului bazei de date exista metoda CreateQueryDef, pentru crearea unei cereri permanente prin cod VBA, descrierea cererii facandu-se direct in SQL. Exemplu. Cererea, Cerere_B este creata daca se executa urmatoarea secventa de instructiuni. Public Sub Fac_Query() ' Creaza o cerere Dim DB As Database Const NumeCerere = 'Cerere_B' ' Numele cu care va fi salvata cererea 'Instructiunea SQL de descriere a cererii Const SQL = 'SELECT Tabela_B.* FROM Tabela_B;' Set DB = CurrentDb 'Baza de date din aplicatia curenta ' Se creaza cererea si se salveaza in BD deschisa

DB.CreateQueryDef NumeCerere, SQL End Sub -----------------Metoda Execute. Aceasta metoda se aplicata numai cererilor actiune, si are ca efect executia efectiva a cererii. Exemplu. Public Sub Executa_Query() ' Executa o cerere actiune cu parametrii / Update Query Dim DB As Database Dim QRY As QueryDef Const NumeCerere = 'Cerere_C' ' Numele cererii Set DB = CurrentDb 'Baza de date din aplicatia curenta ' Se introduce cererea in variabila obiect QRY Set QRY = DB.QueryDefs(NumeCerere) ' se dau valori parametrilor cererii QRY.Parameters('Text1') = 'unu' QRY.Parameters('Text2') = 'XXX' ' Executia cererii actiune Update face ca toate inregistrarile _ care au cimpul [A] = 'unu' (parametrul: Text1) sa si-l modifice _ in 'XXX' (parametrul: Text2) QRY.Execute End Sub ------------------

Obs erv atia 1. Parametrii unei cereri pot fi introdu-si direct prin cod VBA, ca in exemplul de mai sus. Obs erv atia 2. Cererile de selectie(cu eventuali parametrii), care evident nu se pot executa, pot sa constituie suportul pentru crearea unor Recordseturi.

III.3.9 Colectia Relations


Colectia Relations, contine obiecte de tip Relation, fiecare din acestia reprezentand o relatie permanenta a bazei de date. Numele relatiei va fi constituit din concatenarea numelor obiectelor intre care se creeaza relatia. Fiecare obiect Relation, contine o colectie Fields, ale carui obiecte definesc campul de relatie. Exemplu. Public Sub Structua_Relations(Optional BazaDate) 'Structura colectiei de relatii - Relations Dim DB As Database Dim REL As Relation Dim FD As Field 'Cimpurile relatiei

'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else Set DB = OpenDatabase(BazaDate) End If '---------------------------For Each REL In DB.Relations ' Parcurge colectia de Relatii 'Baza de date din alta aplicatie 'Baza de date din aplicatia curenta

If MsgBox('Relatia : ' & REL.NAME, vbOKCancel + vbCritical) = vbOk Then For Each FD In REL.Fields ' Parcurge colectia de Cimpuri ale relatiilor

If MsgBox('Cimpul: ' & REL.NAME & ' /' & FD.NAME, vbOKCancel + _ vbExclamation) = vbOk Then Else Exit For End If Next FD End If Next REL End Sub

III.3.10 Colectia Recordsets - Set de inregistrari.


Colectia Recordsets, este formata din obiecte Recordset(set de inregistrari). Un obiect Recordset, contine inregistrarile care se gasesc intr-o tabela, sau cele care rezulta in urma executarii unei cereri de selectie.(Cererile de selectie sunt considerate asa cum am mai aratat tabele virtuale). La randul sau, un obiect Recordset, contine colectia Fields, formata din obiecte Field, fiecare din acestea reprezentand un camp al inregistrarii respective, si avand de asemenea acelasi nume cu al campului. III.3.10.1 Functionarea unui set de inregistrari. Deci daca obiectele TableDef(sau QueryDef) definesc structura tabelelor(cererilor, ca tabele virtuale), obiectele Recordset sunt formate din datele(informatiile) care se gasesc in acestea. Asa cum cererile, sunt utilizate pentru a manipula datele dintr-o baza de date la nivel de multime(prin implementarea operatiilor de algebra relationala), obiectele Recordset, sunt folosite in acelasi scop dar la nivelul elementar, al inregistrarii. Obiectul Recordset permite accesul la datele din baza de date, prin parcurgerea unui tabel sau a unei cereri de selectie, in modalitatea in care se procedeaza cu un fisier clasic. Un Recordset este asemanator deci cu un fisier clasic. El este constituit din campuri(coloane) si inregistrari(randuri).

Pentru a manevra un Recordset(sau un fisier clasic) trebuie sa se parcurga niste etape, prin lansarea unor metode ale obiectului Recordset(o singura exceptie - metoda OpenRecorset este a obiectului Database) :  Sa fie deschis(obligatoriu primul pas), adica sa fie definit din punct de vedere fizic si sa i se atribuie un nume logic, prin care se va face in continuare referire la el. Metoda folosita este OpenRecorset(a obiectului Database).  Sa fie inchis(obligatoriu ultimul pas). In urma acestei operatii se efectueaza operatiile fizice de sfarsit si se elibereaza toate resursele(variabile, memorii tampon etc.) folosite de Recordset. Metoda Recordset folosita este Close.  Sa fie accesata o anumita inregistrare. Un Recordset, este format ca un tabel(matrice), din randuri si coloane. Pentru a putea ajunge la datele dintr-o anumita celula(element), mai intai trebuie sa se faca pozitionarea pe inregistrarea(randul) respectiv. Cand se efectuau prelucrari prin cereri, se lucra cu multimi(multimea inregistrarilor dintr-o tabela) pe care se efectuau niste operatii de algebra relationala. Cand se lucreaza cu Recordsetul, operatiile se fac la nivel punctual('ma duc' mai intai pe inregistrarea respectiva pentru a face o prelucrare). Termenul de pointer(cursor) de inregistrari, se refera la acest aspect, al inregistrarii care la un moment dat poate fi accesata. Inregistrarea pe care se gaseste la un moment dat pointerul de inregistrari, se numeste inregistrarea curenta. Deci Recordsetul, are un anumit numar de inregistrari, asezate una dupa alta si pentru a efectua orice prelucrare trebuie mai intai sa se pozitioneze pointerul de inregistrari pe respectiva inregistrare. Pozitionarea pointerului de inregistrari, se poate face in mai multe feluri: y acces secvential la o inregistrare - prin parcurgerea inregistrarilor una dupa alta, in ordine pana la cea care intereseaza. Metodele Recordset folosite, denumite Move, permit marirea sau micsorarea pointerului de inregistrari, cu o valoare fixa, ceea ce se materializeaza de obicei prin citirea inainte sau inapoi a urmatoarei inregistrari. y acces direct la o inregistrare - plasarea directa pe o inregistrare in functie de un criteriu de cautare. Functie de mecanismul de efectuare a acestei operatii sunt doua categorii de metode, si anume:

Metoda Recordset Seek - pozitionare rapida folosind cheia de indexare. Metodele Recordset Find - pozitionare mai lenta, care nu foloseste cheia de indexare. N ota: Se poate sintetiza ceea ce s-a prezentat la acest punct prin urmatoarea observatie: Accesul nu este permis decat la campurile inregistrarii curente.  Prelucrarea inregistrarii. Accesarea unei inregistrari se face in doua scopuri: y Citirea datelor din campurile inregistrarii. Se foloseste proprietatea Value, implicita, in citire, a obiectelor campuri(Field) *. y Actualizarea, adica:

Modificarea datelor dintr-un camp. Se foloseste proprietatea Value, in citire, a obiectelor campuri(Field) si metodele Recordset: Edit si Update. Adaugarea unei inregistrari noi. Se foloseste proprietatea Value, in citire, a obiectelor campuri(Field) si metodele Recordset: AddNew si Update. Stergerea unei inregistrari. Metoda Recordset folosita: Delete. III.3.10.2 Tipuri de seturi de inregistrari. Un obiect Recordset, poate proveni din urmatoarele surse: y y datele unei singure tabele; printr-o cerere din datele mai multor tabele, care la randul ei poate fi:

actualizabila (updatable), adica in care se pot actualiza inregistrarile obtinute din executia cererii(campurilor din iesirea cererii li se poate stabili precis originea: tabela, inregistrarea, campul; de exemplu o cerere cu clauza Total sau in care este setata proprietatea Unique Value, nu este updatable); neactualizabila In momentul definirii(deschiderii) unui Recordset, trebuie precizat si tipul acestuia, conform provenientei sale, prezentate mai sus, ceea ce va permite efectuarea unor numai anumitor operatii asupra sa. Astfel exista 4 tipuri de seturi de inregistrari:

Table(dbOpenTable) - Set de inregistrari de tip tabel - Recordset ce provine din inregistrarile unei singure tabele, si care permite actualizari in acestea. Dynaset(dbDynasetTable) - Set de inregistrari de tip dinamic de date - Recordset ce provine printr-o cerere actualizabila din inregistrarile mai multor tabele, si care permite actualizari in acestea. Snapshot(dbSnapshotTable) - Set de inregistrari de tip instantaneu de date - Recordset ce provine printr-o cerere neactualizabila din inregistrarile mai multor tabele, si care nu permite actualizari in acestea. Este folosit numai in scopul cautarii sau al afisarii unor date. OpenForwardOnly(dbOpenForwardOnly) - Recordset de tip Snapshot, dar care nu poate fi parcurs decat o data si numai inainte. III.3.10.3 Deschiderea unui set de inregistrari. Metoda OpenRecordset. Obiectul Recordset, se creeaza numai la lansarea metodei OpenRecordset a obiectului Database. El este adaugat automat la colectia Recordsets, dar nu va fi salvat la inchiderea acestuia. Este un obiect temporar care dureaza pana la inchiderea sa prin metoda Recordset, Close. Obiectul Recordset, va reprezenta practic o structura de tip inregistrari /campuri, care va ocupa un anumit spatiu de memorare, si care va avea o existenta independenta. Din aceasta cauza se pot deschide mai multe obiecte Recordset, care provin din aceiasi sursa de date(tabela). In vederea prelucrarilor necesare, obiectul Recordset se introduce in variabile de tip Recordset. Deschiderea unui Recordset se face in felul urmator: Dim DB As Database Dim RS As Recordset Set DB = CurrentDb 'Baza de date locala Set RS = DB.OpenRecordset(Nume, ) in care: y Nume - este un string care reprezinta numele tabelei sau cererii de selectie din care se creeaza setul de inregistrari. y Tip - reprezinta o constanta care specifica tipul setului de inregistrari care se creeaza, si anume: dbOpenTable

dbOpenDynaset dbOpenSnapshot dbOpenForwardOnly Tipul este optional. Daca nu se foloseste, atunci setul de inregistrari se creeaza pentru primul tip(in ordinea prezentata mai sus) pentru care se poate defini. N ota: 1. Pentru tabelele legate din alte baze de date nu se poate folosi tipul Table. N ota: 2. Tipurile Dynaset, Snapshot, ForwardOnly se creeaza in memoria temporara Access, daca este loc. Din aceasta cauza ele sunt mult mai rapide. N ota: 3. In parametrul 'nume' se poate introduce direct o instructiune SQL. In acest caz obiectul(tabela sau cerere) creat din aceasta, va fi temporar, iar Recordsetul respectiv va functiona mai lent decat in cazul in care ar fi avut la baza un obiect(tabela sau cerere) salvat in baza de date. N ota: 4. La deschidere, Recordsetul se pozitioneaza automat pe prima inregistrare. III.3.10.4 Proprietatile unui set de inregistrari. Cateva din cele mai utilizate proprietati ale unui obiect Recordset sunt: y RecordCount - se poate numai citi, si reprezinta numarul de inregistrari ale Recordsetului. y EOF - se poate numai citi, si ia valoarea True, daca pointerul de inregistrari incearca sa depaseasca ultima inregistrare. BOF - se poate numai citi, si ia valoarea True, daca pointerul de inregistrari incearca sa se plaseze in fata primei inregistrari. Type - se poate numai citi, si arata care este tipul Recordsetului. Updatable - se poate numai citi, si arata daca Recordsetul este actualizabil. NoMatch - se poate numai citi, si se pozitioneaza dupa o metoda Seek sau Find. Aceasta proprietate va lua valoarea True, daca in urma metodei respective de cautare nu s-a putut pozitiona pointerul de inregistrari(nu s-a gasit nici o inregistrare care sa satisfaca conditia de cautare).

y y y

N ota: Pentru Recordsetul care nu are nici o inregistrare RecordCount=0 si atat EOF cat si BOF sunt True.

N ota: Pentru a citi valoarea corecta a numarului de inregistrari ale unui Recordset este bine ca sa se pozitioneze mai intai pointerul de inregistrari pe ultima inregistrare.(eventual cu metoda MoveLast) Exemplu. Public Sub Rst_TipRecordset(Optional BazaDate) 'Deschiderea unui Recordset in toate tipurile Dim DB As Database Dim RS As Recordset Dim Tip(4) As Integer Dim Eroare As String Dim i As Integer 'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna If IsMissing(BazaDate) Then Set DB = CurrentDb Else Set DB = OpenDatabase(BazaDate) End If '---------------------------' Tipuri de seturi de inregistrari Tip(1) = dbOpenTable ' Constanta 1 - pentru exemplul dat numai acest tip nu va fi admis 'Baza de date din alta aplicatie 'Baza de date din aplicatia curenta

Tip(2) = dbOpenDynaset ' Constanta 2 Tip(3) = dbOpenSnapshot ' Constanta 4

Tip(4) = dbOpenForwardOnly ' Constanta 8 For i = 1 To 4

' Daca nu se poate deschide in tipul respectiv se va produce o eroare On Error GoTo Fis Set RS = DB.OpenRecordset('Cerere_B', Tip(i)) On Error GoTo Fis1 RS.MoveLast ' Se pozitioneaza daca poate pe ultima inregistrare MsgBox RS.RecordCount ' Afiseaza numsrul de inregistrari al Recordsetului RS.Close Reia: Next i Sfirsit: Exit Sub Fis: Eroare = 'Nu se poate deschide tipul de recorset ' & Tip(i) & vbCr & _ '--Nr.eroare=' & err & ' - ' & err.Description MsgBox Eroare, vbCritical Resume Reia ' trece la incercarea deschiderii unui alt tip Fis1: MsgBox err & ' - ' & err.Description, vbCritical Resume Reia ' trece la incercarea deschiderii unui alt tip End Sub III.3.10.5 Accesarea secventiala a unui set de inregistrari. Exista 5 metode pentru deplasarea in mod secvential intr-un Recordset: y MoveFirst pointerul de inregistrari se muta pe prima inregistrare;

y y y y

MoveLast pointerul de inregistrari se muta pe ultima inregistrare din Recordset; MoveNext pointerul de inregistrari se muta pe urmatoarea inregistrare; MovePrevious pointerul de inregistrari se muta pe inregistrarea anterioara; Move(N) pointerul de inregistrari se muta functie de valoarea lui N. Astfel daca:

N este pozitiv pointerul de inregistrari se muta inainte cu N inregistrari fata de inregistrarea curenta; N este negativ pointerul de inregistrari se muta inapoi cu N inregistrari fata de inregistrarea curenta; N=0 - pointerul de inregistrari nu se modifica. N ota: Cand se parcurge secvential un Recordset, trebuie testate proprietatile BOF si EOF, pentru a nu se depasi limitele acestuia, la fiecare noua pozitionare. N ota: Pentru tipul de inregistrari ForwardOnly, singura metoda acceptata este MoveNext. III.3.10.6 Accesul direct intr-un set de inregistrari.
III.3.10.6.1 Metoda Seek.

Metoda Seek a unui Recordset, cauta o inregistrare care sa satisfaca un anumit criteriu si in cazul gasirii acesteia, pozitioneaza pe ea pointerul de inregistrari. Criteriul care se foloseste cu metoda Seek, trebuie sa se refere la un index al tabelei care sta la baza Recordsetului. Deoarece Seek functioneaza numai pe indecsi, este evident ca Recordsetul trebuie sa fie obligatoriu numai de tip 'table'. Aplicarea metodei se face in trei pasi: 1. Se seteaza proprietatea Index, a Recordsetului, de tip string, cu numele indexului dupa care se doreste efectuarea cautarii. In cazul in care acesta este cheie primara a tabelei numele lui este 'PrimaryKey'. NumeRecordset.Index='NumeIndex' 2. Se aplica metoda Seek. Prin aceasta se introduce si expresia de cautare, prin doi parametrii de tip string care reprezinta: Operatorul relational al expresiei ce se formeaza cu indexul precizat in etapa anterioara:

= > <

>= <=

Un literal care reprezinta valoarea pe care trebuie sa o aiba in inregistrare indexul respectiv. NumeRecordset.Seek 'operator_relational', 'valoare' N ota: O metoda este similara cu o procedura din punct de vedere al regulilor de sintaxa folosite. Ea se poate lansa si cu parametrii, caz in care acestia sunt plasati in continuarea numelui metodei, separati prin virgula si fara sa fie inclusi intre paranteze. 3. Se verifica prin proprietatea NoMatch daca operatia s-a efectuat cu succes(in caz de reusita proprietatea se seteaza pe False). Exemplu. Public Sub Rst_MetodaSeek() ' Cauta o inregistrare folosind metoda Seek, pe un camp indexat si pe un camp cheie primara Dim DB As Database Dim RS As Recordset On Error GoTo Fis Set DB = CurrentDb ' Se deschide in tipul Table Set RS = DB.OpenRecordset('Tabela_A', dbOpenTable) 'Se verifica ca recordsetul sa aiba inregistrari If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation Exit Sub End If ' Seteaza indexul pentru care se face cautarea pe cheia primara RS.Index = 'PrimaryKey' ' Cauta inregistrarea cu cheia primara = 2

RS.Seek '=', '2' If RS.NoMatch Then MsgBox 'Nu s-a gasit inregistrarea cautata' Else MsgBox 'Ok - ' & RS!N & ';' & RS!A End If '___________ ' Seteaza indexul pentru care se face urmatoarea cautare pe campul 'A' RS.Index = 'A' ' Cauta inregistrarea cu valoarea 'unu' RS.Seek '=', 'unu' If RS.NoMatch Then MsgBox 'Nu s-a gasit inregistrarea cautata' Else MsgBox 'Ok - ' & RS!N & ';' & RS!A End If RS.Close Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub

-----------------N ota: Un obiect index contine asa cum am mai aratat o colectie Fields. Deci un index poate fi format nu numai dintr-un singur camp. Metoda Seek, permite introducerea unui criteriu de cautare si in acest caz, prin folosirea mai multor parametrii valoare(cate unul pentru fiecare camp al indexului)
III.3.10.6.2 Metodele FindFirst, FindLast, FindNext, FindPrevious.

Aceste metode functioneaza asemanator ca metoda Seek, cautand o inregistrare care sa satisfaca un anumit criteriu pentru a se pozitiona pe ea, dar nu foloseste obligatoriu numai campurile indexate pentru efectuarea operatiei. Tipul Recordsetului pentru aceste metode trebuie sa fie obligatoriu Dynaset sau Snapshot. Este evident ca deoarece cautarea nu se va face folosind numai indecsii durata de executie a acestor metode este mult mai mare decat la metoda Seek. Deoarece exista posibilitatea ca sa existe mai multe inregistrari care sa satisfaca criteriul introdus, exista 4 metode de cautare care vor: y FindFirst - pozitioneaza pointerul pe prima inregistrare care indeplineste criteriul de cautare. La aceasta metoda cautarea porneste de la prima inregistrare a Recordsetului, spre sfarsitul lui y FindLast - pozitioneaza pointerul pe ultima inregistrare care indeplineste criteriul de cautare. La aceasta metoda cautarea porneste de la ultima inregistrare a Recordsetului, spre inceputul lui. y FindNext - se aplica de obicei dupa ce s-a efectuat o metoda Find. Ea pozitioneaza pointerul pe urmatoarea inregistrare care indeplineste criteriul de cautare. La aceasta metoda cautarea porneste de la inregistrarea curenta a Recordsetului, spre sfarsitul lui y FindPrevious - - se aplica de obicei dupa ce s-a efectuat o metoda Find. Ea pozitioneaza pointerul pe inregistrarea anterioara care indeplineste criteriul de cautare. La aceasta metoda cautarea porneste de la inregistrarea curenta a Recordsetului, spre inceputul lui -----------------Aplicarea metodei se face in doi pasi: 1. Se aplica una din metodele Find. y Toate metodele Find folosesc un parametru de tip string prin care se introduce o expresie care reprezinta criteriul de cautare.

Regulile de scriere ale expresiei sunt aceleasi care au fost prezentate la formarea expresiilor din functiile agregate de domeniu. Reamintim ca se pot folosi in aceste expresii orice fel de operatori acceptati in VBA(aritmetici, relationali sau logici) si ca termenii expresiei pot fi si numele de campuri din Recordsetul pe care se face cautarea. NumeRecordset.FindFirst | FindLast | FindNext | FindPrevious 'expresie' 2. Se verifica prin proprietatea NoMatch daca operatia s-a efectuat cu succes(in caz de reusita proprietatea se seteaza pe False). Exemplu. Public Sub Rst_MetodeFind() ' Cauta toate inregistrarile care indeplinesc un anumit criteriu _ folosind metode Find Dim DB As Database Dim RS As Recordset Dim I As Integer Dim Tp As String Dim Criteriu As String On Error GoTo Fis Set DB = CurrentDb ' Se deschide setul de inregistrari in tip Dynaset. Set RS = DB.OpenRecordset('Tabela_A', dbOpenDynaset) 'Se verifica ca recordsetul sa aiba inregistrari If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation Exit Sub

End If ' Cauta prima inregistrare care are campul 'A' la fel cu _ valoarea introdusa prin InputBox Tp = InputBox('Valoarea care se va cauta pentru Cimpul A') I=0 Criteriu = '[A]=''' & Tp & '''' RS.FindFirst Criteriu Do While RS.NoMatch = False 'a gasit o inregistrare cu criteriul introdus MsgBox 'Ok - ' & RS!N & ';' & RS!A I=I+1 RS.FindNext Criteriu ' cauta urmatoarea inregistrare care respecta acelasi criteriu Loop MsgBox 'Nr. de inregistrari gasite care au Cimpul A = ''' & Tp & ''' este: ' & I RS.Close Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub III.3.10.7 Prelucrarea datelor dintr-un set de inregistrari.
III.3.10.7.1 Citirea campurilor dintr-un set de inregistrari.

Un obiect Recordset contine o colectie de obiecte Fields. In aceasta colectie vor fi atatea obiecte cate campuri are Recordsetul respectiv.

Proprietatea implicita a unui obiect camp este Value care reprezinta valoarea care se gaseste in campul respectiv. Ea se poate folosi atat in citire cat si in scriere(pentru a fi modificata). Exemplu. Public Sub Rst_CitireSecveniala() 'Deschiderea unui Recordset si citirea secvensiala a acestuia Dim DB As Database Dim RS As Recordset Dim Eroare As String On Error GoTo Fis Set DB = CurrentDb ' Se deschide in tipul implicit, adica cel mai semnificativ care se poate - Table ' La deschidere automat Recordsetul se pozitioneaza pe prima inregistrare. Set RS = DB.OpenRecordset('Tabela_A') 'Se verifica ca recordsetul sa aiba inregistrari If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation Exit Sub End If 'Se parcurge recordsetul de la prima la ultima inregistrare. Do While Not RS.EOF ' Ciclul se executa cat timp nu se atinge sfarsitul recordsetului ' Se afiseaza valorile din campuri folosindu-se proprietatea implicita Value. _ Se observa folosirea semnului de calificare (!) pentru a se referi un obiect de tip camp MsgBox RS!N & ';' & RS!A RS.MoveNext ' Pozitionare pe urmatoarea inregistrare.

Loop ' Afiseaza numarul de inregistrari al Recordsetului MsgBox 'Numarul de inregistrari = ' & RS.RecordCount RS.Close ' Optionala Se face automat la inchiderea procedurii in care s-a declartat Recordsetul Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub
III.3.10.7.2 Actualizarea unui set de inregistrari.

Pentru fiecare tip de actualizare(modificare, adaugare, stergere) care se efectueaza asupra datelor dintr-un Recordset, exista metode specifice. Pentru ca o actualizare sa fie acceptata, in primul rand trebuie ca sa se respecte urmatoarele trei conditii: Recordsetul sa fie actualizabil. Pentru verificarea acestei conditii se poate folosi proprietatea Updatable(sa fie True). Recordsetul sa fie deschis in tip Table sau Dynaset, adica in tipurile care accepta efectuarea de actualizari. Actualizarea efectuata, sa respecte conditiile de integritate de domeniu, existentiala sau referentiala a tabelelor si relatiilor pe care setul de inregistrari este creat
III.10.3.7.2_1 Modificarea datelor dintr-un camp al unui set de inregistrari.

Modificarea datelor dintr-un camp al unei inregistrari dintr-un Recordset se efectueaza folosind metodele Recordset Edit si Update, si proprietatea Field, Value, astfel: y Modificarea efectiva a valorii dintr-un camp al unui Recordset, se efectueaza prin proprietatea Value(implicita) a campului, in scriere. Pentru ca acest lucru sa fie posibil trebuie ca sa se procedeze in prealabil in felul urmator:

pointerul de inregistrari se pozitioneaza pe inregistrarea ale carui campuri se vor modifica; se lanseaza metoda Recordset Edit; y Dupa efectuarea modificarii campurilor din inregistrare, aceasta trebuie efectiv rescrisa in Recordset, prin metoda Update. Deci modificarea unui camp dintr-o inregistrare, se face prin efectuarea acesteia intre metodele Recordset Edit si Update. N ota: Daca modificarea efectuata nu va respecta proprietatile de integritate setate, metoda Update nu se va executa si va provoca o eroare de executie. Exemplu. Public Sub Rst_Modificare() Dim DB As Database Dim RS As Recordset Dim I As Integer Dim Tp As String Dim TM As String Dim Criteriu As String On Error GoTo Fis Set DB = CurrentDb ' Se deschide setul de inregistrari in tip Dynaset, care permite efectuarea actualizarilor Set RS = DB.OpenRecordset('Tabela_A', dbOpenDynaset) 'Se verifica ca recordsetul sa aiba inregistrari If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation Exit Sub End If

'Se verifica ca recordsetul sa poata fi modificat If RS.Updatable = False Then MsgBox 'Nu se pot efectua modificari', vbInformation Exit Sub End If ' ______Modificarea unui cimp ' Se introduce un criteriu de selectie pentru inregistrarile ce se vor modifica Tp = InputBox('Valoarea care se va cauta pentru Cimpul A') ' Se introduce valoarea cu care se actualizeaza TM = InputBox('Valoarea care se va introduce in Cimpul A') I=0 Criteriu = '[A]=''' & Tp & '''' RS.FindFirst Criteriu Do While RS.NoMatch = False 'a gasit o inregistrare cu criteriul introdus MsgBox 'Inregistrare Veche :' & RS!N & ';' & RS!A RS.Edit RS!A = TM On Error GoTo Fis1 ' eroare daca nu se poate face modificarea RS.Update On Error GoTo Fis I=I+1 MsgBox 'Inregistrare Noua :' & RS!N & ';' & RS!A RS.FindNext Criteriu ' cauta urmatoarea inregistrare care respecta acelasi criteriu

Loop MsgBox 'Nr. de inregistrari modificate este: ' & I RS.Close Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit Fis1: MsgBox 'Eroare Actualizare: ' & vbCr & err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub
III.10.3.7.2_2 Adaugarea unei inregistrari intr-un set de inregistrari.

Adaugarea unei inregistrari noi intr-un set de inregistrari se efectueaza folosind metodele Recordset AddNew si Update, si proprietatea Field, Value, astfel: y Se pozitioneaza pointerul pe o inregistrare noua, prin metoda Recordset AddNew.

y Se introduc in campurile inregistrarii valorile dorite prin folosirea in scriere a proprietatii Value a acestora. y Se scrie in Recordset inregistrarea noua prin metoda Update.

N ota: Daca inregistrarea adaugata nu va respecta proprietatile de integritate setate, metoda Update nu se va executa si va provoca o eroare de executie. Exemplu. Public Sub Rst_Adaugare() Dim DB As Database Dim RS As Recordset

Dim TN As String Dim TA As String On Error GoTo Fis Set DB = CurrentDb ' Se deschide setul de inregistrari in tip Dynaset, care permite efectuarea actualizarilor Set RS = DB.OpenRecordset('Tabela_A', dbOpenDynaset) 'Se verifica ca recordsetul sa poata fi modificat If RS.Updatable = False Then MsgBox 'Nu se pot efectua modificari', vbInformation Exit Sub End If ' ______Adaugarea unei inregistrari ' Se introduc de la tastatura valorile pentru cimpurile inregistrarii TN = InputBox('Valoarea pentru Cimpul N') TA = InputBox('Valoarea pentru Cimpul A') RS.AddNew RS!N = Val(TN) RS!A = TA On Error GoTo Fis1 ' eroare daca nu se poate face adaugarea RS.Update On Error GoTo Fis MsgBox 'Adaugare efectuata' RS.Close

Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit Fis1: MsgBox 'Eroare Adaugare: ' & vbCr & err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub
III.10.3.7.2_3 Stergerea unei inregistrari dintr-un set de inregistrari.

Stergerea unei inregistrari dintr-un set de inregistrari se efectueaza folosind metoda Recordset Delete, astfel: y y Se pozitioneaza pointerul pe inregistrare care se va sterge. Se executa metoda Recordset Delete.

N ota: Daca inregistrarea stearsa va provoca o eroare de integritate referentiala(de exemplu se incearca stergerea unei inregistrari dintr-o tabela parinte, care are copii printr-o relatie cu integritatea referentiala setata dar nu si cu stergere in cascada) metoda Delete nu se va executa si va provoca o eroare de executie. Exemplu. Public Sub Rst_Stergere() Dim DB As Database Dim RS As Recordset Dim I As Integer Dim Tp As String Dim Criteriu As String

On Error GoTo Fis Set DB = CurrentDb ' Se deschide setul de inregistrari in tip Dynaset, care permite efectuarea actualizarilor Set RS = DB.OpenRecordset('Tabela_A', dbOpenDynaset) 'Se verifica ca recordsetul sa aiba inregistrari If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation Exit Sub End If 'Se verifica ca recordsetul sa poata fi modificat If RS.Updatable = False Then MsgBox 'Nu se pot efectua modificari', vbInformation Exit Sub End If ' ______Stergerea unor inregistrari ' Se introduce un criteriu de selectie pentru inregistrarile ce se vor sterge Tp = InputBox('Valoarea care se va cauta pentru Cimpul A') I=0 Criteriu = '[A]=''' & Tp & '''' RS.FindFirst Criteriu Do While RS.NoMatch = False 'a gasit o inregistrare cu criteriul introdus If MsgBox('Inregistrarea care se sterge:' & RS!N & ';' & RS!A, vbOKCancel) = vbOk _ Then

On Error GoTo Fis1 ' eroare daca nu se poate face stergerea RS.Delete On Error GoTo Fis I=I+1 End If RS.FindNext Criteriu ' cauta urmatoarea inregistrare care respecta acelasi criteriu Loop MsgBox 'Nr. de inregistrari sterse este: ' & I RS.Close Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit Fis1: MsgBox 'Eroare Stergere ' & vbCr & err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub

III.3.11 Seturi de inregistrari definite pe cereri.


O cerere de selectie, poate sa fie obiectul de intrare a unui set de inregistrari in doua moduri: y Direct, definind ca obiect al setului de inregistrari cererea(ca in exemplele de pana acum)

y Executand in prealabil anumite actiuni asupra cererii. De exemplu daca este necesar introducerea unor parametrii in cerere direct din cod.

Crearea Recordsetului in acest caz se face aplicand metoda OpenRecordset a cererii, ca in urmatorul exemplu. Exemplu. Public Sub Rst_Query() ' Creaza un recordset pe baza unei cereri de selectii cu parametrii Dim DB As Database Dim QRY As QueryDef Dim RS As Recordset Const NumeCerere = 'Cerere_A' ' Numele cererii Set DB = CurrentDb 'Baza de date din aplicatia curenta ' Se introduce cererea in variabila obiect QRY Set QRY = DB.QueryDefs(NumeCerere) ' se dau valori parametrilor cererii QRY.Parameters('Numar') = '2' Set RS = QRY.OpenRecordset ' Se defineste recordsetul pe cerere If RS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari selectate', vbInformation Exit Sub End If Do While Not RS.EOF ' se parcurge secvential RS MsgBox 'Inregistrare selectata:' & RS!N & ';' & RS!A RS.MoveNext Loop End Sub

III.3.12 Seturi de inregistrari definite pe alte seturi de inregistrari.


Un set de inregistrari poate fi definit pe un alt set de inregistrari, dupa ce asupra acestuia se efectueaza anumite prelucrari. Aceasta metoda se aplica de obicei daca se doreste sortarea sau filtrarea in prealabil a setului de inregistrari. Crearea Recordsetului in acest caz se face aplicand metoda OpenRecordset a primului Recordset, ca in urmatorul exemplu, folosit pentru sortarea unui Recordset. N ota: Pentru sortarea unui Recordset, se foloseste proprietatea Sort a Recordsetului, care are urmatoarea forma: recordset.Sort = 'cheia_sortare_1 [Asc] | Desc ' Asa cum se observa se permite sortarea dupa mai multe chei , in ordine ascendenta(implicit) sau descendenta. N ota: Recordsetul de tip Table, nu se poate sorta. Exemplu. Public Sub Rst_Sortare() 'Deschiderea unui Recordset si sortarea acestuia Dim DB As Database Dim RS As Recordset Dim RSS As Recordset On Error GoTo Fis Set DB = CurrentDb ' Se deschide in tipul Dynaset / Nu este permisa sortarea pe tipul Table Set RSS = DB.OpenRecordset('Tabela_A', dbOpenDynaset) 'Se verifica ca recordsetul sa aiba inregistrari If RSS.RecordCount = 0 Then MsgBox 'Nu exista inregistrari', vbInformation

Exit Sub End If RSS.Sort = 'N Desc' ' Se sorteaza recordsetul dupa cheia N in ordine descrescatoare Set RS = RSS.OpenRecordset ' Se deschide al doilea recordset, pe primul care e sortat 'Se parcurge recordsetul sortat de la prima la ultima inregistrare. Do While Not RS.EOF ' MsgBox RS!N & ';' & RS!A RS.MoveNext ' Pozitionare pe urmatoarea inregistrare. Loop ' Afiseaza numarul de inregistrari al Recordsetului MsgBox 'Numarul de inregistrari = ' & RS.RecordCount Sfirsit: Exit Sub Fis: MsgBox err & ' - ' & err.Description, vbCritical Resume Sfirsit End Sub

III.3.13 Accesul la obiecte externe de date.


In Access este posibil ca sa se foloseasca obiecte de date(de tip tabel) de o multitudine de tipuri create in alte aplicatii. Aceasta se poate face ori prin legare, ori prin incapsulare. Exista doua metode de realizarea a acestui lucru: y y Din meniu prin comanda File | Get External Data Prin metodele obiectului DoCmd: DoCmd.TransferDatabase - pentru obiecte din baze de date Access, Fox, DBase etc.

DoCmd.TransferSpreadsheet - pentru foi de calcul din MS. Excel. DoCmd.TransferText - pentru date introduse sub forma de inregistrari (cu separatori sau de latime fixa pentru stabilirea campurilor(coloanelor) in fisiere de tip text). N ota: Si operatia inversa, de export din Access a obiectelor acestuia, in diferite tipuri de baze de date este posibila.

S-ar putea să vă placă și