'Limbaje de programare folosite in informatice de gestiune'
C U P R I N S
Cap III. Utilizarea obiectelor in programare. III-3
III.1 Obiecte. III-3
III.1.1 Clase de obiecte, obiecte si colectii de obiecte. III-3
III.1.2 Provenienta obiectelor utilizate intr-o aplicatie. III-4
III.1.3 Ierarhia obiectelor dintr-o aplicatie. III-4
III.1.4 Utilizarea in cod VBA a proprietatilor si metodelor unui obiect. III-5
III.1.5 Exemple de referire a obiectelor din modelul - Application Access III-6
III.1.6 Variabile obiect. III-7
III.1.6.1 Tipuri de variabile obiect. III-7
III.1.6.2 SET - Instructiunea de atribuire pentru variabile obiect. III-8
III.1.6.3 Eliberarea resurselor folosite de o variabile obiect. Cuvantul cheie NOTHING. III-9
III.1.6.4 Crearea unei instante noi pentru o clasa de obiecte. Cuvantul cheie NEW. III-9
III.1.7 Parcurgerea unei colectii de obiecte. Instructiunea For Each III-10
III.2 Utilizarea in Access a obiectelor provenite din clase externe. Folosirea controalelor standard Windows. III-11
III.2.1 Utilizarea intr-o aplicatie a obiectelor create in alte aplicatii. III-11
III.2.1.1 Metoda OLE. III-11
III.2.1.2 Metoda Automation. Obiecte ActiveX. III-11
III.2.2 Crearea referintei catre un obiect extern III-12
III.2.2.1 Plasarea unui control ActiveX, intr-un formular(raport) III-13
III.2.3 Controlul Progress Bar III-13
III.2.4 Controlul Common Dialog III-15
III.3 Obiecte pentru acces la date - Data Access Objects DAO. III-18
III.3.1 Structura DAO. III-18
III.3.2 Obiectul DBEngine. III-19
III.3.3 Workspaces - spatiul(mediul) de lucru. III-19
III.3.4 Colectia Errors. Tratarea erorilor de executie in VBA. III-21
III.3.4.1 Tratarea standard a unei erori de executie produsa in VBA. III-21
III.3.4.2 Tratarea erorilor de executie prin module special create de proiectant. III-22
III.3.4.2.1 Instructiunea: On Error. III-22
III.3.4.2.2 Instructiunea: Resume. III-23
III.3.4.2.3 Obiectul: Err. III-23
III.3.4.2.4 Structura unei rutine care are modul de Error-handling. III-23
III.3.4.2.5 Colectia Errors si obiecte Error. III-25
III.3.5 Colectia Databases III-26
III.3.6 Colectia Containers III-27
III.3.7 Colectia TableDefs III-31
III.3.8 Colectia QueryDefs. III-34
III.3.9 Colectia Relations III-37
III.3.10 Colectia Recordsets - Set de inregistrari. III-37
III.3.10.1 Functionarea unui set de inregistrari. III-37
III.3.10.2 Tipuri de seturi de inregistrari. III-39
III.3.10.3 Deschiderea unui set de inregistrari. Metoda OpenRecordset. III-39
III.3.10.4 Proprietatile unui set de inregistrari. III-40
III.3.10.5 Accesarea secventiala a unui set de inregistrari. III-41
III.3.10.6 Accesul direct intr-un set de inregistrari. III-41
III.3.10.6.1 Metoda Seek. III-41
III.3.10.6.2 Metodele FindFirst, FindLast, FindNext, FindPrevious. III-43
III.3.10.7 Prelucrarea datelor dintr-un set de inregistrari. III-45
III.3.10.7.1 Citirea campurilor dintr-un set de inregistrari. III-45
III.3.10.7.2 Actualizarea unui set de inregistrari. III-45
III.10.3.7.2_1 Modificarea datelor dintr-un camp al unui set de inregistrari. III-46
III.10.3.7.2_2 Adaugarea unei inregistrari intr-un set de inregistrari. III-47
III.10.3.7.2_3 Stergerea unei inregistrari dintr-un set de inregistrari. III-48
III.3.11 Seturi de inregistrari definite pe cereri. III-50
III.3.12 Seturi de inregistrari definite pe alte seturi de inregistrari. III-50
III.3.13 Accesul la obiecte externe de date. III-51
Bibliografie
Bazele Access 95, Allen Browne, Alison Balter, Editura Teora 1996
Visual Basic 5.0 - Manualul programatorului, John Clark Craig, Jeff Webb, Editura Teora 1998
Microsoft Visual Basic 6.0 - Ghidul Programatorului, Microsoft Press, Ed. Teora 1997
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 printr-un 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'.
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
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
Instante ale claselor de obiecte aflate in bibliotecile standard ale pachetului Access: DAO, Access Application si VBA.
Instante ale claselor de obiecte proprii(utilizator), create special de proiectant(prin modulele de clase de obiecte)
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.
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
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
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)
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')
Observatia 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.
Observatia 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.
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'.
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.
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'
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.
Forms!Date - se face referire la formularul deschis cu numele ' Date'.
Forms![date de bilant] - se refera formularul deschis 'date de bilant'. Observati parantezele drepte folosite pentru ca numele formularului contine spatii.
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.
Forms![vinzari]!valoare - se refera controlul 'valoare' a formularul deschis 'vinzari'.
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.
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)
Me.FilterOn - se refera proprietatea FilterOn a formularului in care se gaseste codul VBA.
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
Nota: Modelul DAO va fi tratat intr-un capitol separat.
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 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 , 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.
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
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:
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.
Nota: 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.
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
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).
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) ' Var. obiect FM2, va contine aceaiasi referinta ca variabila FM1
ST = FM1.Caption ' Proprietatea Caption a var obiect FM1 este salvata in ST
FM1.Caption = 'TEST Variabile Obiect' ' Se schimba proprietatea Caption in FM1
MsgBox FM2.Caption ' Schimbarea se face practic in obiectul referit. Deci si in FM2
FM1.Caption = ST ' Se reface proprietatea Caption.
MsgBox FM2.Caption ' Aceasta schimbare se produce si in FM2
Set FM1 = Nothing ' Se elibereaza spatiul ocupat de FM1
Sfirsit:
Exit Sub
' 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
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)
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 For Each
For Each var obiect In colectie_obiecte
[instructiuni]
[Exit For]
[instructiuni]
Next var obiect
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 For Each 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
Nota: Instructiunea For Each se poate folosi si pentru variabile de tip tablou (Array
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)
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 memorandu-se 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).
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.
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.
Dupa actionarea butonului: Register, sistemul solicita utilizatorului sa introduca numele complet al fisierului care contine un ActiveX, pentru a-l inregistra.
Operatia inversa, de anulare a inregistrarii unui ActiveX, se face prin selectia unui control dupa care se apasa pe butonul Unregister
Nota: 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.
Nota: 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.
Dupa inregistrare, introducerea intr-un formular(raport) a unui control ActiveX, se poate face in doua feluri:
Prin comanda Insert ActiveX Controls', lansata ori de pe bara cu instrumente ori din meniul Access.
Prin plasarea controlului direct pe bara de instrumente(in cazul utilizarii frecvente a unui control ActiveX). Pentru aceasta se va proceda astfel:
Se lanseaza comanda Customize prin meniul contextual al oricarui taskbar.
Se pozitioneaza comanda Customize in pagina a doua, Commands
In fereastra stanga, Categories se selecteaza ActiveX Controls'
Din fereastra din dreapta, Commands se trage(Drag and Drop) cu mouse-ul controlul respectiv, pe bara de instrumente.
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:
Intervalul, denumit rangul controlului, care stabileste valorile extreme, minima si maxima, ale evolutiei procesului respectiv. Deci el defineste intreaga durata a operatiei.
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 ' Controlul ProgressBar initial nu va fi vizibil.
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
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 ' Se face vizibil controlul
Me.TimerInterval = 1000 ' Se porneste intreruperea de timp cu o durata de 1 sec.
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
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 ' Clepsidra s-a golit / timpul in sec. a expirat
Me.TimerInterval = 0 ' se opreste intreruperea de timp
Me!PBar.Visible = False ' se face invizibil controlul Progress Bar
End If
End Sub
Nota: 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.
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:
Title - se introduce un text care se va afisa in partea de sus a controlului(zona albastra de titlu a ferestrei);
InitDir - reprezinta calea care va indica directorul al carui continut se vizualizeaza. Aceasta va fi afisata in zona Look in
DefaultExt - este o extensie care va fi intoarsa daca nu se specifica in mod explicit tipul fisierului.
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'.
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
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
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.
Explicatie. * 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.
Explicatie. ** 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
Nota: Controlul Common Dialog, se gaseste in fisierul COMDLG32.OCX care face parte din pachetul de distributie al pachetului Visual Basic.
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.
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.
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
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
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.
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).
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.
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
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.
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.
Observatia 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 ' Reface sistemul de erori standard
End If
Next WS
End Sub
Nota: 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.
Colectia Errors, functioneaza in contextul sistemului general de erori implementat in VBA, care va fi prezentat in cele ce urmeaza.
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:
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.
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.
Nota: 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
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
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:
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, Error-handling care se va gasi dupa aceasta eticheta.
Nota: 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.
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.
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.
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.
Resume eticheta - prelucrarea va continua cu instructiunile care se gasesc dupa eticheta
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.
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 s-a putut executa.
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.
Explicatie. * Numarul tuturor erorilor posibile se gaseste in Help, si se pastreaza in cazul trecerii la noi versiuni.
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
Nota: 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).
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
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.
TableDefs Structura tabelelor bazei de date.
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.
Nota: 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
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 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
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
On Error GoTo 0 ' Reface sistemul standard de tratare a erorilor
End Sub
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.
Explicatie. * In colectia Tables, se va observa existenta unor tabele, care incep cu prefixul 'MSyS'. Acestea reprezinta tabelele sistem ale MS Access.
Nota: 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 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
End If
'----- ----- --------- ----- ----
For Each CT In DB.Containers ' 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) 'Baza de date din alta aplicatie selectionata prin CD
Me.Caption = 'BD:' & NF
End If
On Error GoTo 0 ' din nou sistemul standard de erori
'===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
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
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.
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
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]
A, care la randul lui contine:
à Colectia Fields cu un obiect - [A]
Explicatie. 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 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
End If
'----- ----- --------- ----- ----
For Each TD In DB.TableDefs ' Parcurge colectia de Tabele
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.
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
Colectia Fields formata din obiecte Field, fiecare din acestea reprezentand un camp al cererii.
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
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 'Cimpurile cererii
Dim PT As Parameter 'Parametrii cererii
'Daca parametrul 'BazaDate' lipseste atunci se lucreaza cu baza de date interna
If IsMissing(BazaDate) Then
Set DB = CurrentDb 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
End If
'----- ----- --------- ----- ----
For Each Qry In DB.QueryDefs ' Parcurge colectia de Cereri
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
Observatia 1. Parametrii unei cereri pot fi introdu-si direct prin cod VBA, ca in exemplul de mai sus.
Observatia 2. Cererile de selectie(cu eventuali parametrii), care evident nu se pot executa, pot sa constituie suportul pentru crearea unor Recordseturi.
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 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
End If
'----- ----- --------- ----- ----
For Each REL In DB.Relations ' Parcurge colectia de Relatii
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
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.
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:
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.
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.
Nota: 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
Citirea datelor din campurile inregistrarii. Se foloseste proprietatea Value, implicita, in citire, a obiectelor campuri(Field) *.
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
Un obiect Recordset, poate proveni din urmatoarele surse
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.
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:
Nume - este un string care reprezinta numele tabelei sau cererii de selectie din care se creeaza setul de inregistrari.
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.
Nota: Pentru tabelele legate din alte baze de date nu se poate folosi tipul Table.
Nota: Tipurile Dynaset, Snapshot, ForwardOnly se creeaza in memoria temporara Access, daca este loc. Din aceasta cauza ele sunt mult mai rapide.
Nota: 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.
Nota: La deschidere, Recordsetul se pozitioneaza automat pe prima inregistrare.
Cateva din cele mai utilizate proprietati ale unui obiect Recordset sunt:
RecordCount se poate numai citi, si reprezinta numarul de inregistrari ale Recordsetului.
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).
Nota: Pentru Recordsetul care nu are nici o inregistrare RecordCount si atat EOF cat si BOF sunt True.
Nota: 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 'Baza de date din aplicatia curenta
Else
Set DB = OpenDatabase(BazaDate) 'Baza de date din alta aplicatie
End If
'----- ----- --------- ----- ----
' Tipuri de seturi de inregistrari
Tip(1) = dbOpenTable ' Constanta 1 - pentru exemplul dat numai acest tip nu va fi admis
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
Exista 5 metode pentru deplasarea in mod secvential intr-un Recordset:
MoveFirst pointerul de inregistrari se muta pe prima inregistrare;
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 - pointerul de inregistrari nu se modifica.
Nota: Cand se parcurge secvential un Recordset, trebuie testate proprietatile BOF si EOF, pentru a nu se depasi limitele acestuia, la fiecare noua pozitionare.
Nota: Pentru tipul de inregistrari ForwardOnly, singura metoda acceptata este MoveNext.
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:
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
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
Nota: 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.
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
Nota: 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)
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:
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
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.
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
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:
Se aplica una din metodele Find.
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
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
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
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
Modificarea datelor dintr-un camp al unei inregistrari dintr-un Recordset se efectueaza folosind metodele Recordset Edit si Update, si proprietatea Field, Value, astfel:
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;
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.
Nota: 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
Adaugarea unei inregistrari noi intr-un set de inregistrari se efectueaza folosind metodele Recordset AddNew si Update, si proprietatea Field, Value, astfel:
Se pozitioneaza pointerul pe o inregistrare noua, prin metoda Recordset AddNew.
Se introduc in campurile inregistrarii valorile dorite prin folosirea in scriere a proprietatii Value a acestora.
Se scrie in Recordset inregistrarea noua prin metoda Update.
Nota: 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
Stergerea unei inregistrari dintr-un set de inregistrari se efectueaza folosind metoda Recordset Delete, astfel:
Se pozitioneaza pointerul pe inregistrare care se va sterge.
Se executa metoda Recordset Delete.
Nota: 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
O cerere de selectie, poate sa fie obiectul de intrare a unui set de inregistrari in doua moduri
Direct, definind ca obiect al setului de inregistrari cererea(ca in exemplele de pana acum)
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
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.
Nota: 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.
Nota: 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
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:
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).
Nota: Si operatia inversa, de export din Access a obiectelor acestuia, in diferite tipuri de baze de date este posibila.
|