Curs Baze de Date

295
 CAP: 1. NOŢIUNI GENERALE DESPRE BAZE DE DATE 1.1 Bază de date. Baze de date relaţionale În sensul cel mai simplu o bază de date este o colecţie de înregistrări şi fişiere organizate pentru un scop anume [1]. Astfel o bază de date poate fi considerată: toate numerele de telefon ale diferitelor cunoştinţe păstrate pe un calculator personal, totalitatea datelor personale despre studenţii unei universităţi păstrate pe calculatorul acesteia etc. Documentele procesate care sunt organizate în ordine alfabetică pot constitui de asemenea într-un sens mai restrâns o bază de date. Un alt tip de baze de da te po t fi co ns iderate fi ş ierele de ti p foaie de calc ul or ga ni zate du pă ti pu l întrebuinţării. Bazele de date relaţionale se referă la o colecţie de date, structurate sub forma mai multor tabele ce poartă numele de relaţii [2]. Termenul de relaţional provine din faptul că fiecare înregistrare din baza de date conţine informaţii referitoare la un singur subiect şi numai la unul. De asemenea datele cuprinse în categorii de informaţii  pot fi manipulate de o singură entitate, bazată pe valori de date asociate. În legătură cu bazel e de date relaţionale sunt folosiţi mai mulţi termeni. Ast fel o relaţie (relation) –conţine informaţii despre un singur subiect, cum ar fi clienţii, comenzile, studenţii sau universităţile [1]. De obicei o relaţie este stocată ca un tabel dintr- un sistem de ge stio na re a ba zelor de da te re la ţ ionale. Te rm enul atri bu t desemnează o informaţie specifică unui subiect [2]. Astfel un atributele poate fi considerate capetele de tabel ă. Rândurile vor purta numele de tuple. O legătură reprezintă modul cum informaţiile dintr-o tabelă sunt legate cu cele din altă tabelă. Diferenţele dintre o relaţie şi un tabel sunt următoarele [2].: atr ibut ele şi tuplel e unei relaţi i nu sunt ordonate, în timp ce într-u n tabel există o ordonare atât a coloanelor cât şi a rândurilor două tuple ale unei relaţii nu pot avea valori identice, în timp ce într- un tabel două sau mai multe rânduri ce ocupă poziţii diferite în tabel  pot conţine valori identice Un domeniu reprezintă mulţimea valorilor pe care le pot lua atributele unei relaţii [5]. Astfel fiecare atribut dintr-o bază de date relaţională este definit pe un anumit domeniu, de unde acesta va lua valori. Mul ţime domeniilor pe care este definită o bază de date formează vocabularul bazei de date. 1.1.1 Chei primare, chei secundare O cheie este forma tă din număru l minim de atribute, astfel alese încât valorile acestor atribute să fie unice [2]. În consecinţă, fiecare tuplă a relaţiei este identificată în mod unic de valoarea cheii respective. Totuşi într-o relaţie pot fi mai multe grupuri Pag. 6

Transcript of Curs Baze de Date

Page 1: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 1/295

CAP: 1. NOŢIUNI GENERALE DESPRE BAZE DE DATE

1.1 Bază de date. Baze de date relaţionale

În sensul cel mai simplu o bază de date este o colecţie de înregistrări şi fişiereorganizate pentru un scop anume [1]. Astfel o bază de date poate fi considerată: toatenumerele de telefon ale diferitelor cunoştinţe păstrate pe un calculator personal,totalitatea datelor personale despre studenţii unei universităţi păstrate pe calculatorulacesteia etc. Documentele procesate care sunt organizate în ordine alfabetică potconstitui de asemenea într-un sens mai restrâns o bază de date. Un alt tip de baze dedate pot fi considerate fişierele de tip foaie de calcul organizate după tipulîntrebuinţării.

Bazele de date relaţionale se referă la o colecţie de date, structurate sub formamai multor tabele ce poartă numele de relaţii [2]. Termenul de relaţional provine dinfaptul că fiecare înregistrare din baza de date conţine informaţii referitoare la unsingur subiect şi numai la unul. De asemenea datele cuprinse în categorii de informaţii pot fi manipulate de o singură entitate, bazată pe valori de date asociate.

În legătură cu bazele de date relaţionale sunt folosiţi mai mulţi termeni. Astfelo relaţie (relation) –conţine informaţii despre un singur subiect, cum ar fi clienţii,comenzile, studenţii sau universităţile [1]. De obicei o relaţie este stocată ca un tabeldintr-un sistem de gestionare a bazelor de date relaţionale. Termenul atribut

desemnează o informaţie specifică unui subiect [2]. Astfel un atributele poate ficonsiderate capetele de tabelă. Rândurile vor purta numele de tuple. O legăturăreprezintă modul cum informaţiile dintr-o tabelă sunt legate cu cele din altă tabelă.

Diferenţele dintre o relaţie şi un tabel sunt următoarele [2].:• atributele şi tuplele unei relaţii nu sunt ordonate, în timp ce într-un

tabel există o ordonare atât a coloanelor cât şi a rândurilor • două tuple ale unei relaţii nu pot avea valori identice, în timp ce într-

un tabel două sau mai multe rânduri ce ocupă poziţii diferite în tabel pot conţine valori identice

Un domeniu reprezintă mulţimea valorilor pe care le pot lua atributele uneirelaţii [5]. Astfel fiecare atribut dintr-o bază de date relaţională este definit pe unanumit domeniu, de unde acesta va lua valori. Mulţime domeniilor pe care estedefinită o bază de date formează vocabularul bazei de date.

1.1.1 Chei primare, chei secundare

O cheie este formată din numărul minim de atribute, astfel alese încât valorile

acestor atribute să fie unice [2]. În consecinţă, fiecare tuplă a relaţiei este identificatăîn mod unic de valoarea cheii respective. Totuşi într-o relaţie pot fi mai multe grupuri

Pag. 6

Page 2: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 2/295

de atribute care identifică în mod unic tuplele relaţiei, deci acestea reprezintă chei alerelaţiei respective.

În modelul relaţional liniile unui tabel sunt unice. Unicitatea înregistrărilor 

 poate fi asigurată prin stabilirea unei chei primare, care este o coloană sau un grup decoloane ale tabelei care va conţine valori unice în tabelă [3]. Aceste tabele care conţinvalori unice se numesc chei candidat. Una din cheile candidat este considerată cheie primară, iar cele rămase se numesc chei alternative.

Valorile cheilor primare sunt utilizate pentru a face corelaţii între tuplele maimultor relaţii şi pentru a reprezenta legăturile dintre entităţile bazei de date. Astfel ocheie secundară a unei relaţii este formată din unul sau mai multe atribute ale căror valori sunt utilizate ca şi chei primare în alte relaţii [2]. Întotdeauna valorileatributului cheie secundară trebuie să aparţină aceluiaşi domeniu ce cel al atributului

cheie primară din cealaltă relaţie.1.1.2 Relaţii

O relaţie exprimă un raport sau o asociere între două sau mai multe tabele.Între două sau mai multe entităţi pot exista următoarele tipuri de relaţii:

• relaţii de tipul 1:1 (one-to-one) sunt acele tipuri de relaţii în carefiecărei linii din prima tabelă îi corespunde cel mult o linie în cea de-adoua tabelă. Acest tip de relaţii sunt utile atunci când se doreşte

împărţirea tabelei în două sau mai multe tabele pentru motive desecuritate, de performanţă, sau de exemplu, în cazul sistemului degestiune a bazelor de date Access datorită limitei de 255 de coloane pentru o tabelă;

• relaţii de tipul 1:m (one-to-many) sunt relaţiile în care pentru fiecarelinie din prima tabelă există zero, una sau mai multe linii în cea de-adoua tabelă, dar pentru fiecare linie din cea de-a doua tabelă existăexact o linie în prima tabelă;

• relaţii de tipul m:m (many-to-many) sunt acele tipuri de relaţii în care

 pentru fiecare linie din cea de-a doua tabelă pot exista mai multe liniiîn cea de-a doua şi, totodată pentru fiecare linie din cea de-a douatabelă pot exista mai multe linii în prima.

1.1.3 Teoria normalizării

Teoria normalizării se ocupă cu îmbunătăţirea succesivă a schemeiconceptuale, fiind satisfăcute în acelaşi timp următoarele condiţii [3]:

• conservarea datelor –în schema conceptuală finală trebuie să existe

toate datele din cadrul schemei iniţiale;• conservarea dependenţelor dintre date –trebuie să se păstreze tipurile

de relaţii dintre entităţi;

Pag. 7

Page 3: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 3/295

• descompunerea minimală a relaţiilor iniţiale –în schema conceptualăfinală nici o relaţie nu trebuie să fie conţinută într-alta.

 Normalizarea [3] constă astfel într-o serie de teste efectuate asupra datelor existente, în scopul de a elimina redundanţa şi de a garanta că datele sunt asociate cutabelele sau relaţiile corespunzătoare. În total există şase astfel de teste, dintre care

doar trei sunt mai des folosite în practică şi anume:

• Prima formă normală: - o tabelă este în prima formă normală dacăvalorile tuturor atributelor care o compun sunt indivizibile şi în plus nutrebuie să existe atribute sau grupuri de atribute repetitive [3];

• A doua formă normală: - o tabelă este în a doua formă normală dacăeste în prima formă normală şi fiecare atribut care nu face parte dincheia primară este dependent de întreaga cheie primară [3];

• A treia formă normală: -spunem că o tabelă este în a treia formănormală dacă este în forma normală doi şi toate coloanele care nu fac parte din cheia primară depind direct de cheia primară [3];

• A patra formă normală: -elimină redundanţele datorate relaţiilor detipul m:m;

• A cincea formă normală: -este mai mult „academică” şi apare foarte rar în practică;

• Forma normală Boyce-Codd: -o relaţie este în forma Boyce-Codd dacăfiecare determinant este o cheie candidat (Putem defini determinantul

ca pe un atribut sau o mulţime de atribute neredundante care constituieun identificator unic pentru un alt atribut sau o altă mulţime de atributeale unei relaţii.

1.2 Sisteme de gestiune a bazelor de date

În perioada actuală caracterizată printr-un progres continuu în toate domeniilevieţii sociale şi economice un rol deosebit de important îl deţine informaţia. O parte

importantă a resurselor fiecărei entităţi economice sau sociale este orientată astfel spreacumulare, prelucrarea şi stocarea datelor. Acest proces se identifică în mod normalcu crearea, întreţinerea şi utilizarea unei baze de date pe sistemele de calcul moderne.

O bază de date este formată dintr-o colecţie de date diverse şi un software caresă controleze accesul la acestea, software cunoscut sub numele de sistem de gestiune a bazelor de date (SGBD). Un SGBD reprezintă astfel [2] un program ce furnizează ointerfaţă între sistemul de operare de pe sistemul de calcul respectiv şi utilizator, cuscopul de a simplifica pe cât posibil accesul la date.

Un SGBD îndeplineşte următoarele funcţii importante [2]:

• stocarea, regăsirea şi actualizarea datelor (astfel se permiteutilizatorilor să creeze şi să manipuleze date fără a fi necesar săcunoască structura internă a datelor);

Pag. 8

Page 4: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 4/295

• crearea şi întreţinerea dicţionarului de date;• gestionarea facilităţilor legate de accesarea simultană a unor 

înregistrări ale bazei de date de către mai mulţi utilizatori;•  păstrarea unei copii de siguranţă („back-up”);•   probleme de securitate a datelor (parole de acces ale utilizatorilor,

verificări etc.)Gestionarea informaţiei sub forma unei baze de date prezintă o serie deavantaje dintre care amintim [2]:

• Independenţa datelor: Într-o bază de date, datele sunt păstrate astfelîncât schimbarea structurii acestora să nu afecteze nici unul dintre programele de aplicaţie ce utilizează baza de date respectivă.

• Consistenţa datelor: Modificarea articolelor din baza de date este

 percepută de fiecare dintre utilizatorii sistemului de baze de date.• Controlul redundanţei: În sistemele de gestiune neorientate spre

 baza de date, aceiaşi informaţie poate fi păstrată în mai multe fişierediferite şi în consecinţă creşte nejustificat spaţiul fizic ocupat pe disc, precum şi timpul consumat cu actualizarea datelor redundante.

• Integritatea datelor: Un SGBD furnizează utilizatorilor posibilitateaspecificării anumitor restricţii. Dacă de exemplu se adaugă un nou produs în baza de date impunem să fie adăugat şi preţul acestuia, astfelîncât acest câmp nu va putea niciodată fi omis.

• O mai mare securitate a datelor: Un SGBD va asigura faptul cădoar utilizatorii autorizaţi vor avea acces la date.• Un control centralizat al datelor prin intermediul unui administrator 

al bazei de date.• O mai mare cantitate de informaţii disponibilă utilizatorilor: Cu un

SGBD utilizatorii accesează informaţia ce a fost păstrată anterior însisteme de calcul diferite, chiar incompatibile între ele.

• Orice SGBD modern furnizează un limbaj de interogare a datelor, deobicei de tip SQL („Structured Data Language”), ce permit

utilizatorilor să obţină mult mai rapid şi mai simplu informaţiile dorite,decât dacă utiliza un program scris într-un limbaj prodedural.

1.2.1 Limbaje de interogare. SQL

Limbajele de interogare pot fi clasificate [2] în două categorii:a) limbaje algebrice, în care interogările asupra relaţiilor sunt exprimate

 prin intermediul unor operatori aplicaţi asupra lor. În această categorie

intră limbajul SQL. b) Limbaje bazate pe calcul relaţional, în care interogările asupra relaţiilor sunt exprimate prin intermediul unor condiţii pe care tuplele relaţiilor 

Pag. 9

Page 5: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 5/295

trebuie să le satisfacă. Această categorie de limbaje se clasifică larândul ei în două categorii în funcţie de obiectul asupra căruia se aplicăoperaţia şi anume:

b1) limbaje bazate pe calcul relaţional orientat pe tuple, în care predicatele se implică asupra tuplelor relaţiilor, reprezentativ fiind aici

QUEL, limbajul de interogare Ingres;b2) limbaje bazate pe calcul relaţional orientat pe domenii, în care  predicatele domeniului din care ia valori atributul relaţiei.Reprezentativ pentru aceste categorie este QBE, limbajul de interogaredezvoltat de IBM.

Pentru reprezentarea structurii logice a datelor dintr-o bază de date există treimodele şi anume: modelul ierarhizat , care presupune crearea unei structuriarborescente de reprezentarea a datelor, modelul reţea, în care elementele ce

reprezintă datele sunt legate între ele prin pointeri, formându-se astfel o reţea, şimodelul relaţional, acesta din urmă impunându-se net în faţa celorlalte două, fiind laora actuală la baza realizării majorităţii produselor.

În esenţă o bază de date relaţională poate fi gândită ca şi o colecţie de tabele bidimensionale ce se numesc relaţii, coloanele (atributele relaţiei) au nume distincte,iar rândurile (tuple) conţin elemente ale datelor ce poartă numele de entităţi.Organizarea datelor sub forma mai multor tabele poartă numele de schemareprezentării datelor. O schemă nu specifică doar care sunt coloanele ce intră încomponenţa fiecărui tabel, ci va stabili de asemenea legătura logică dintre entităţile

stocate în baza de date.Limbajul standard care a fost conceput ca un limbaj de descriere a datelor şiacces la informaţiile din bazele de date relaţionale este SQL. El a fost iniţial utilizat decătre firma IBM pentru produsul DB2, devenind la mijlocul deceniului trecut unstandard de facto în domeniu. De atunci şi până în prezent au fost dezvoltate un număr de şapte versiuni ale standardului SQL, trei dintre acestea aparţinând InstitutuluiAmerican de Standarde (ANSI), celelalte fiind concepute de firme de prestigiu caIBM, Microsoft şi Borland, sau de către consorţiile industriale SAG („The SQLAccess Group”) şi X/Open, primul format din sute de firme ce comercializeazăsoftware pentru baze de date, iar cel din orientat spre activităţi de promovare astandardelor în domeniul sistemelor deschise.

1.3 Modelul relaţional

1.3.1. Scurtă descriere a modelului relaţional

Modelul relaţional a fost formulat şi publicat pentru prima oară la începutulanilor ’70 de către dr. Edgar F. Codd, cercetător la laboratoarele IBM din San Jose(California), care a publicat între anii 1970-1974 lucrările sale referitoare la modelulrelaţional pentru bazele de date. Acest model relaţional, are avantajul că permite

Pag. 10

Page 6: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 6/295

 proiectantului bazei de date să studieze proprietăţile sistemului de gestiune a bazelor de date fără a fi necesar să-l implementeze.

Una din caracteristicile de bază ale modelului relaţional este simplitatea sa şirigurozitatea sa din punct de vedere matematic, fapt care l-a impus în faţa celorlaltemodele, fiind adoptat în ultimul deceniu de majoritatea cercetătorilor şi

 programatorilor din domeniu. Datele şi relaţiile sunt reprezentate sunt reprezentareexplicit, utilizând o structură logică ce poartă numele de relaţie. Pe de altă parte,modelul relaţional a fost definit cu o deosebită rigoare matematică, furnizând unmijloc performant de studiu al proprietăţilor logice ale unui sistem de baze de date.

Spre deosebire de modelul relaţional, celelalte modele impuse anterior,modelul ierarhizat şi modelul reţea, nu au beneficiat de un fundament teoretic atât desolid. O altă deosebire esenţială între modelul relaţional şi celelalte două modele esteaceea că în timp ce primul este orientat spre mulţimi, celelalte două sunt orientate sprefişiere; aceasta rezidă din faptul că, dacă pentru modelul ierarhizat şi modelul reţea,

 programatorul trebuie să proiecteze programe procedurale, care să acceseze baza dedate înregistrare cu înregistrare utilizând legături fizice pentru

înregistrări, pentru modelul relaţional, o singură instrucţiune de limbaj neprocedural(cum este SQL), determină de obicei prelucrarea mai multor înregistrări.

O altă proprietate specifică modelului relaţional este aceea că nefiind orientatspre sistemul de calcul, se pot adresa doar proprietăţile logice ale sistemului de bazede date, nu şi cele fizice. Drept urmare, modelul nu include regulile, structurile şi

operaţiile referitoare la implementarea fizică a unui sistem de baze de date. De astfelunul din obiectivele modelului relaţional a fost acela de a introduce o distincţie clarăîntre aspectele fizice şi cele logice ale unei baze de date, obiectiv numit de E.F. Codd„independenţa datelor”.

La începutul fundamentării teoretice a modelului relaţional, au existat temeriserioase privind eficienţa aplicării modelului relaţional pentru baze de date dedimensiuni mari. Dezvoltarea tehnologică fără precedent în domeniul electronicii şiinformaticii din ultimii ani, concretizată în creşterea puterii de prelucrare acalculatoarelor a condus la eliminarea acestor temeri prin larga utilizare a sistemelor de baze de date relaţionale inclusiv pe calculatoarele personale.

1.3.2 Reguli de fidelitate ale bazelor de date

Pe la mijlocul anilor ’80 matematicianul Edgar F. Codd a publicat un set dereguli în raport cu care un sistem de gestiune a bazelor de date (SGBD) poate fiapreciat ca fiind „relaţional”. Aceste reguli sunt denumite „Cele 13 reguli de fidelitateale lui Codd”. Ulterior Codd a extins numărul acestora, de la 13 reguli publicate înanul 1986, la un număr de 100 în 1990. Totuşi nici un sistem de gestiune a bazelor dedate pus în vânzare pe piaţa comercială nu respectă absolut toate regulile definite deCodd, ci doar un număr mai mic sau mai mare al lor. Spre exemplu, produsul IBMDB2 respectă un număr de 7 reguli din cele 13.

Pag. 11

Page 7: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 7/295

Astfel cele 13 reguli de fidelitate ale lui Codd sunt[2] următoarele:

Regula 0: (Regula de bază)

 Pentru a fi relaţional, un SGBD trebuie să fie capabil să gestioneze o bază de

date prin intermediul caracteristicilor sale relaţionale.Astfel un SGBD trebuie să cuprindă trei părţi: o parte de definire a datelor (DDL), o parte de manipulare a datelor (DML) şi o altă parte de integritate şi control adatelor (DCL)

Regula 1: (Regula reprezentării informaţiei)

  Într-o bază de date relaţională, informaţia este reprezentată la nivel logicîntr-un singur fel, şi anume sub forma unor tabele.

Datele sunt stocate sub forma unor structuri tabelare, formate din rânduridenumite tuple şi coloane denumite atribute. Aceste structuri sub formă de tabele,oferă o serie de avantaje şi anume: claritate, generalitate (majoritatea tipurilor de date  pot fi reprezentate sub această formă) şi flexibilitate (această structură poate fimodificată atât pe rânduri cât şi pe coloane).

Regula 2: (Regula accesului garantat la date) Fiecare dată dintr-o bază de date relaţională trebuie să poată fi adresată în

mod logic printr-o combinaţie formată din numele relaţiei în care se află, valoareacheii primare şi numele atributului.

Se poate regăsi orice valoarea aparţinând oricărui atribut al unei relaţii, dacăsunt specificate: numele relaţiei, numele tuplei (prin utilizarea cheii primare) şinumele atributului.

Regula 3: (Regula reprezentării informaţiei necunoscute)

Un SGBD în totalitate relaţional trebuie să poată permite utilizatoruluidefinirea unui tip de date denumit „NULL” pentru reprezentarea unei informaţiinecunoscute la momentul respectiv şi aceasta într-un mod sistematic pentru orice tipde date.

Într-un SGBD relaţional trebuie să se poată face diferenţierea între o valoarefixată intenţionat pe 0, un şir vid de caractere şi o valoare necunoscută.

Regula 4: (regula dicţionarului de date)

Pag. 12

Page 8: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 8/295

 Asupra descrierii bazelor de date trebuie să se poată aplica aceleaşi operaţiica cele asupra datelor din baza de date.

Toate informaţiile referitoare la relaţii, vizualizări, indexi etc. , trebuie să poatăfi stocate sub forma unor relaţii ce formează un catalog de sistem (dicţionar), şi prinurmare să poată fi accesate în acelaşi mod ca şi datele propriu-zise prin intermediul

aceloraşi comenzi.Regula 5: (Regula limbajului de interogare)

Un SGBD relaţional trebuie să poată permite utilizarea a cel puţin unuilimbaj, care să prezinte următoarele caracteristici: să permită definirea datelor,definirea vizualizărilor, manipularea datelor, restricţii de autorizare, realizareatranzacţiilor (operaţiile COMMIT şi ROLLBACK).

Această regulă precizează că manipularea datelor dintr-o bază de date trebuie

să se facă printr-un limbaj de nivel înalt (de exemplu SQL), limbaj care permiteutilizatorilor să definească relaţii şi vizualizări, să regăsească informaţia şi să o poatăactualiza. De asemenea limbajul mai permite verificarea şi corectarea datelor deintrare, precum şi restrângerea accesului la relaţii şi vizualizări prin intermediul parolelor de acces. El trebuie să păstreze integritatea bazelor de date prin gestiuneatranzacţiilor 1.

Regula 6: (Regula de actualizare a vizualizării)

Un SGBD trebuie să poată determina dacă o vizualizare poate fi actualizată şi să stocheze rezultatul interogării într-un dicţionar de tipul unui catalog sistem.

Unele vizualizări pot fi actualizate, altele nu, în funcţie de varianteleinstrucţiunii SELECT utilizate, pe baza cărora sunt construite. Prin urmare, un SGBDtrebuie să determine acest lucru printr-un anumit mecanism.

Regula 7: (Regula limbajului de nivel înalt)

 Regulile de manipulare asupra unei relaţii luată ca întreg, sunt valabile atât   pentru operaţiile de regăsire a datelor, cât şi asupra operaţiilor de inserare,actualizare şi ştergere a datelor.

Operaţiile de manipulare a datelor (selecţia, actualizarea, inserţia, ştergerea) seaplică asupra oricărei părţi dintr-o relaţie, plecând de la întreaga relaţie şi sfârşind cu otuplă sau nici una. Astfel un SGBD relaţional, nu trebuie să oblige utilizatorul să cauteîntr-o relaţie tuplă de tuplă pentru a regăsi informaţia dorită.

Regula 8: (Regula independenţei fizice a datelor)

1 Tranzacţie –o comandă sau un grup de comenzi ale limbajului respectivPag. 13

Page 9: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 9/295

  Într-un SGBD relaţional trebuie să se separeu aspectul fizic al datelor (metoda de stocare sau metoda de acces la date) de aspectul logic, şi anume programele de aplicaţie.

Orice modificare în modul de stocare al datelor nu trebuie să afecteze în niciun fel programele de aplicaţie, utilizatorilor fiindu-le transparente asemenea operaţii.

Regula 9: (Regula independenţei logice a datelor)

 Programele de aplicaţie trebuie să fie transparente la modificările de orice tipefectuate asupra datelor.

Orice modificare asupra unei relaţii nu trebuie să afecteze operaţiile demanipulare a datelor. Totuşi pot apărea modificări ale acestor operaţii, dacă se ştergrelaţii, vizualizări sau atribute.

Regula 10: (Regula independenţei datelor din punct de vedere al integrităţii)Un SGBD relaţional trebuie să permită atât definirea unor restricţii de

integritate asupra bazelor de date prin intermediul limbajului, cât şi stocarea lor îndicţionare de tipul cataloagelor sistem.

Un SGBD relaţional trebuie să permită operaţii de validare a datelor (restricţiide integritate), utilizând de exemplu limbajul SQL, gestiunea acestor operaţii trebuiesă poată fi făcută prin stocarea lor în dicţionarul de date şi nu prin scrierea de programe.

Regula 11: (Regula independenţei datelor din punct de vedere al distribuirii)

 Distribuirea datelor pe mai multe calculatoare dintr-o reţea de comunicaţii dedate, nu trebuie să afecteze programele de aplicaţi.

Această regulă reprezintă o extensie a regulii 8, deoarece în acelaşi mod cumutilizatorii trebuie să fie transparenţi faţă de unitatea de disc pe care se află stocaterelaţiile, în acelaşi mod ei trebuie să fie transparenţi şi faţă de calculatorul pe care seaflă aceste relaţii.

Regula 12: (Regula versiunii procedurale a SGBD)

Orice componentă procedurală a unui SGBD trebuie să respecte aceleaşirestricţii de integritate ca şi componenta relaţională.

De exemplu, dacă în partea de manipulare a datelor a limbajului relaţional(DML), data dintr-o coloană este de tipul NOT NULL, orice altă metodă proceduralăde accesare a acestei coloane nu trebuie să permită introducerea unei valori NULL înaceastă coloană.

Pag. 14

Page 10: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 10/295

Bibliografie

1. Eduard Koller, Monica Roşculeţ - Programare în Acces 97, EdituraTEORA, Bucureşti 1999

2. Corina Pascu, Adrian Pascu -Totul despre… SQL, Editura Tehnica,Bucuresti 1994

3. John L. Viescas -Totul despre Microsoft Access. EdituraTeora Bucuresti 1999

CAP:2. Baze de date, tabele şi relaţii

Încă de la varianta 95, Access vă pune la dispoziţie experţi care pot crea pentru dumneavoastră toate tabelele, formularele şi rapoartele unei baze de date pecare o veţi specifica. De asemenea, Access vă pune la dispoziţie un număr de baze dedate predefinite, din domenii variind de la administrarea unei biblioteci, fonoteci sauvideoteci, până la contacte de afaceri, informaţii despre companii, servicii, etc. Deşiaceşti experţi vă pot uşura considerabil munca, scopul nostru este să vă arătăm cum săcreaţi propria bază de date, pornind de la zero.

Pag. 15

Page 11: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 11/295

2.1 Crearea unei baze de date

La pornire, Access vă prezintă o cutie de dialog care vă permite să optaţi întrea deschide o bază de date existentă şi a crea una nouă. Pentru a crea manual o bază de

date, selectaţi Blank Database şi apăsaţi butonul OK .Altfel, dacă doriţi să creaţi o bază de date nouă în timp ce lucraţi cu Access,alegeţi comanda File/New Database sau apăsaţi butonul New Database de pe bara cuinstrumente şi apoi alegeţi Blank Database din pagina General a cutiei de dialogNew.

Fig. 2.1. Fereastra de deschidere din Access

Să creeăm împreună baze de date Cursuri opţionale. Specificaţi în câmpulFile Name al cutiei de dialog File New Database numele Cursuri Opţionale şialegeţi din lista Save In directorul în care doriţi ca Access să salveze noul fişier (aveţigrijă ca tipul fişierului să fie Microsoft Access Database (*.mdb)).

Pag. 16

Page 12: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 12/295

Fig. 2.2. Tastaţi “Cursuri optionale” în loc de db1 pentru a denumi baza de date

2.2. Crearea tabelelor

În acest moment, baza de date nu conţine nici o tabelă (dacă aţi fi folosit unexpert pentru a crea baza de date, acesta ar fi creat şi tabelele, şi chiar ar fi stocat înele informaţie)

„Atelierul” pe care Access vi-l pune la dispoziţie este fereastra Database, carese deschide imediat după ce aţi creat o bază de date nouă, sau aţi deschis una dejaexistentă. Aceasta conţine pagini pentru diferitele tipuri de obiecte care pot alcătui o

 bază de date Access: tabele, interogări, rapoarte, formulare şi module. Pe parcursulacestui capitol ne vom concentra atenţia asupra paginii Tables a ferestrei Database.

Access vă oferă mai multe posibilităţi de a crea o tabelă nouă, după cum se poate observa şi din figura:

Fig. 2.3. Pagina Tables

Pag. 17

Page 13: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 13/295

- Datasheet View: vă permite să creaţi o tabelă pe baza datelor stocate în ea (pentru Acces 97);

- Design View: vă ajută să definiţi structura tabelei, specificândcoloanele care o compun şi proprietăţile acestora;

- Table Wizard: este un expert care creează pentru dumneavoastră o

tabelă pe baza unor structuri predefinite;2.2.1 Crearea manuală a tabelelorPentru a crea manual o tabelă, puteţi folosi fie modul Datasheet View, fie

modul Design View.Modul Datasheet View vă ajută să creaţi tabele simple, prin simpla

introducere a datelor în tabel. Access determină apoi, pe baza cestor date, tipurile şiformatele coloanelor. De asemenea, Access poate crea şi o cheie primară. Cu toateacestea, Datasheet View nu vă va permite să intraţi în detalii cum ar fi stabilirea

 proprietăţilor tabelei sau ale coloanelor. Pentru acestea, folosiţi modul Design View,care vă va oferi control asupra tuturor proprietăţilor disponibile ale tabelei şi alecoloanelor care o compun, inclusiv reguli de validare şi valori implicite.

2.2.2 Datasheet View: avantaje• crearea tabelei• umplerea ei cu date

În ciuda acestor avantaje, trebuie să ţinem cont de faptul că în majoritateacazurilor, bazele de date nu sunt create doar pentru a stoca informaţiileexistente, ci pentru a oferi un mecanism pentru introducerea ulterioară a

datelor şi pentru lucrul cu acestea. După cum puteţi observa din figură,folosirea modului Datasheet View se aseamănă cu lucrul cu Microsoft Excel:fiecare linie reprezintă o înregistrare în tabelă

Pentru a crea o tabelă nouă în modul Datasheet View (97), procedaţi în felulurmător:1. În fereastra Database, apăsaţi butonul New. Va apărea fereastra New

Table.2. Din lista prezentată în fereastra New Table, alegeţi Datasheet View şi

apăsaţi butonul OK .Acum, pe ecran a apărut o fereastră conţinând o tabelă fără date, dar cu 20 de

coloane şi 30 de linii (dacă doriţi, puteţi adăuga mai multe). În partea de sus a fiecăreicoloane se află un selector ce conţine numele coloanei respective. Făcând clic cu butonul din stânga al mouse-ului pe acest selector, puteţi selecta coloana. Iniţial,aceste nume sunt Field1, Field2 etc. dar, ulterior, le vom schimba în aşa fel încât săreflecte atributele entităţii descrise de tabelă. Pentru a redenumi o coloană, puteţi proceda în unul din următoarele trei moduri:

1. Faceţi dublu-clic pe selectorul coloanei, care se va schimba într-uncâmp de editare. Introduceţi noul nume.

Pag. 18

Page 14: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 14/295

2. Selectaţi coloana, alegeţi comanda Format | Rename column şieditaţi numele.

3. faceţi clic dreapta pe selectorul coloanei. Din meniul context,

selectaţi comanda Rename Column şi editaţi numele.Notă: deşi Access vă permite includerea de spaţii în numele coloanelor,

încercaţi, pe cât posibil, să evitaţi acest lucru. Unele sisteme de baze de date (cum ar fidBase) nu permit folosirea spaţiilor în numele coloanelor. Deci, dacă aveţi de gând sălegaţi o tabelă dintr-un astfel de DBMS (Data Base Management System – Sistem degestionare a bazelor de date) la baza dumneavoastră de date, nu folosiţi spaţii.

Fig. 2.4. Tabela “Curs_Student

 Notă: Access consideră că un câmp gol, care nu conţine date, are o valoare  specială, numită null . Astfel, regăsirea ulterioară a înregistrărilor pentru care uncâmp nu conţine date va fi foarte uşoară, comparând valoarea lui cu null .

2.2.3 Design View:Spre deosebire de modul Datasheet View, modul Design View nu vă permiteintroducerea de date în tabelă. Cu toate acestea, el este indispensabil datorită posibilităţilor pe care vi le oferă.

Pag. 19

Page 15: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 15/295

Fig. 2.5. Modul Design View

Pentru a crea o tabelă în modul Table Design View, procedaţi în felul următor:1. apăsaţi butonul Tables.2. Selectaţi din listă opţiunea Create table using Design View .

Va apărea o fereastră ce nu conţine informaţie. Aici se pot defini coloanele

(numite şi câmpuri) ce compun tabela, precum şi proprietăţile acestora. După cum se poate observa din figură, fereastra este împărţită în două părţi. Partea de sus foloseştela definirea coloanelor, iar partea de jos la stabilirea proprietăţilor fiecărei coloane în parte şi conţinutul ei se schimbă în funcţie de tipul pe care l-aţi atribuit coloanei.

2.2.4 Definirea coloanelorDupă cum s-a observat, pentru a defini coloanele, se foloseşte partea de sus a

ferestrei Table Design. Pentru a defini prima coloană, introduceţi numele acesteia în prima linie a coloanei Field Name. Treceţi apoi în coloana Data Type pentru a alege

tipul pe care doriţi să-l atribuiţi noii coloand. Access vă pune la dispoziţie un număr de tipuri de date predefinite, despre care vom vorbi în cele ce urmează:• Text: şir de caractere (maximum 255), pentru stocarea datelor alfanumerice. Folosit şi pentru numerele ce nu vor fi folosite la calcule(de exemplu, numere de telefon).• Memo: folosit pentru stocarea textelor lungi, de până la 65.535 decaractere.• Number: folosit pentru stocarea datelor numerice de tipul: întreg,întreg lung, în virgulă mobilă, cu precizie simplă sau dublă.

• Date/Time: folosit pentru stocarea datei şi a orei.• Currency: un tip numeric special, folosit pentru valori monetare,deoarece nu permite rotunjirile de calcul.

Pag. 20

Page 16: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 16/295

• Autonumber: un tip numeric special care poate fi folosit pentrucheile primare. Coloanele de acest tip sunt de tip read-only (doar 

citire), Access introducând automat ori valori consecutive, ori valori

aleatoare la crearea unor înregistrări noi.• Yes/No: folosit pt stocarea datelor booleene.• OLE Object: folosit pentru a stoca text sau o combinaţie de text şidate numerice, folosite ca adresă de hiperlegătură ce poate conţine trei părţi separate prin semnul #: textul afişat într-un control sau câmp,adresa (calea către un fişier (UNC) sau către o pagină (URL)) şi osubadresă (o locaţie din cadrul fişierului sau paginii).• Lookup Wizard: vă dă posibilitatea să definiţi un câmp în careutilizatorul să poată selecta o valoare din altă tabelă sau dintr-o listă

 predefinită. (vom reveni asupra acestei probleme)După ce s-a ales tipul coloanei care se doreşte să o creaţi, puteţi introduce o

scurtă descriere a acesteia în coloana Description. Deşi acest lucru este opţional, este bine să profitaţi de el, pentru ca tabela să fie uşor de întreţinut.

2.2.5 Stabilirea proprietăţilor câmpurilor

În această secţiune vom descrie diferitele proprietăţi pe care le poate acea uncâmp (coloană) şi care pot fi stabilite folosind partea de jos a ferestrei Table design.Setul de proprietăţi pe care îl aveţi la dispoziţie variază în funcţie de tipul de date ales pentru coloana respectivă. Multe dintre proprietăţile de bază sunt comune tuturor tipurior de date. În afară de proprietăţile booleene (Required, Allow Zero Length şiIndexed), singurele proprietăţi pe care trebuie să le specificaţi sunt Field Size (pentrutipurile de date Text, Number şi Autonumber) şi New Values (pentru Autonumber).Toate celelalte proprietăţi sunt opţionale. În continuare, vom vorbi mai pe larg despre proprietăţi.

• Field Size: specifică lungimea şirului de caractere sau tipul numeric al datelor stocate în acest câmp.

• Format: specifică formatul în care vor fi afişate datele. Puteţi alege un format predefinit sau puteţi crea dumneavoastră unul. Nu afectează modul de stocarea datelor.

• Decimal Places: Specifică numărul de cifre de după virgulă. Valoarea Autoarată faptul că numărul de zecimale este dat de proprietatea Format.

• Input Mask: controlează formatul în care trebuie introduse datele în câmp.Definiţi acest format apăsând butonul...

• Caption: specifică denumirea sub care va apărea coloana în formulare şirapoarte. Dacă nu o completaţi, Access va folosi numele coloanei.

Pag. 21

Page 17: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 17/295

• Default Value: valoarea atribuită din oficiu câmpului la inserarea unei noiînregistrări.

• Validation Rule: expresie (regulă de validare) ce limitează valorile ce pot fiintroduse în câmp.

• Validation Text: textul afişat dacă datele introduse în câmp nu respectă

regula de validare.• Required: arată dacă un câmp poate conţine valoarea null• Allow Zero Length: arată dacă în câmpurile de tip Text sau Memo pot fi

introduse şiruri de caractere de lincime zero. Această proprietate esteindependentă de proprietatea Required. Dacă ea are valoarea Yes, un şir delungime zero este o valoare validă pentru un câmp, indiferent de valoarea proprietăţii Required.

• Indexed: arată dacă un câmp este indexat sau nu. Valoarea Yes (No

Duplicates) arată faptul că un câmp poate fi indexat, iar valorile stocate în eltrebuie să fie unice. Valoarea Zes (Duplicates Allowed) înseamnă faptul că uncâmp este indexat, iar valorile sale trebuie să fie unice. Valoarea No aratăfaptul că un câmp nu este indexat. Despre indecşi şi coloane indexate vomvorbi mai pe larg în acest capitol.

• New Values: este o proprietate specifică tipului de date Autonumber şi indicămodul în care Access generează numerele ce vor fi stocate în câmp: crescător (Increment) sau aleator (Random).

Aceste proprietăţi le găsiţi în pagina General din partea de jos a ferestrei TableDesign. Cea de-a doua pagină este Lookup şi, pentru unele tipuri de date (Text, Number, Yes/No), ea vă permite să alegeţi tipul de control folosit pentru introducereadatelor în câmp. Figura reprezintă pagina Lookup pentru un câmp de tip text.

Pag. 22

Page 18: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 18/295

Fig. 2.6. Pagina “Lookup” pentru un cîmp de tip text

Prima proprietate din pagine Lookup este Display Control şi ea specificămodul în care vor fi afişate datele. În funcţie de valoarea sa, sunt disponibile sau nu şialte proprietăţi. Dacă la tipul coloanei aţi ales Lookup Wizard, valoarea pentruDisplay Control va fi stabilită automat. Pentru coloane de tip Text sau Number,valorile disponibile pentru Display Control sunt Text Box, Combo Box sau List Box,iar pentru coloane de tip Yes/No, puteţi alege Text Box, Combo Box sau Check Box.

Dacă aţi optat pentru Text Box, nu mai sunt alte proprietăţi de stabilit. ValorileText Box sau Combo Box vă dau posibilitatea să specificaţi liste din care utilizatorulsă selecteze datele ce trebuie introduse în câmp. Aceste date pot proveni din liste

 predefinite sau din alte tabele. Asupra acestei probleme vom reveni ulterior în acestcapitol.

Cel mai simplu mod de a folosi proprietăţile din pagina Lookup este cuajutorul expertului Lookup Wizard, despre care vom vorbi în secţiunea următoare.

2.2.6 Lookup wizardExpertul Lookup Wizard este folosit pentru a defini modul în care pot fi

regăsite şi afişate valorile ce pot fi introduse într-un câmp. După cum am mai spus,aceste valori pot proveni din alte tabele, dintr-o interogare sau dintr-o listă specificată

de dumneavoastră.Pentru a înţelege mai bine mecanismul şi utilitatea expertului Lookup Wizard,

vă propunem să creăm împreună, în modul Table Design View, tabela Curs_Student,Pag. 23

Page 19: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 19/295

despre care am mai vorbit. Pentru aceasta este necesar ca dumneavoastră să fi creat în prealabil tabelele Curs şi Student. Pentru a putea fi stabilite ralaţiile. Vom folosiLookup Wizard pentru a regăsi denumirile cursurilor opţionale disponibile şi a-i oferiutilizatorului posibilitatea de a alege un curs dintr-o listă.

 Notă: dacă tabela Curs este deschisă în modul Datasheet View sau DesignView, închideţi-o, pentru ca Lookup Wizard să îşi poată finaliza acţiunile.

După ce aţi creat coloanele NrMatricol şi Nota (vezi figura 2.6) , urmaţi paşiiurmători pentru a crea coloana IdCurs:

1. în câmpul Field Name: Introduceţi numele coloanei, IdCurs.2. în câmpul Datatype: alegeţi Lookup Wizard.3. în prima cutie de dialog a expertului alegeţi prima opţiune, prin care

specificaţi că doriţi ca datele să fie luate dintr-o tabelă sau interogare.Apăsaţi butonul Next.4. în cea de-a doua cutie de dialog, selectaţi din listă tabela Curs şi apăsaţi

Next5. în cea de-a treia cutie de dialog specificaţi din care coloane ale tabelei

Curs doriţi să fie luate datele. Selectaţi coloana Denumire şi apăsaţi Next.6. cea de-a patra cutie de dialog vă permite să ajustaţi lăţimea coloanelor 

selectate. De asemenea, în căsuţa de validare Hyde key column,specificaţi dacă doriţi să apară şi coloana care face legătura între cele

două tabele (IdCurs). Cum nu dorim acest lucru, lăsaţi căsuţa validată şiapăsaţi Next.

7. în ultima cutie de dialog introduceţi numele pe care doriţi să-l aibă nouacoloană în modul Datasheet View sau în formulare („Curs”). Apăsaţi butonul Finish.

8. Lookup Wizard va salva tabela cu noile modificări şi va stabili relaţia întretabela Curs şi Curs_Student (care este de tipul 1:m).

9. observaţi în fereastra Table Design noile valori ale proprietăţilor din pagina Lookup (vezi figura). Proprietatea Caption din pagina general areacum valoarea Curs.

Pag. 24

Page 20: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 20/295

Fig. 2.7. Utilitarul “Lookup Wizard”

Pentru a vedea rezultatele acestor acţiuni, treceţi în modul Table DatasheetView. Selectaţi coloana Curs şi apăsaţi butonul din parteadreaptă a câmpului. Vaapărea o listă a tuturor cursurilor din tabela Curs (fig. 2.8). dacă selectaţi un nume dinlistă, acesta va fi afişat în câmp. Deşi ceea ce vedeţi este denumirea cursului, în tabelaCurs_Student este stocat doar IdCurs, astfel încât regulile de integritate referenţială să poată fi păstrate. Astfel, în cazul în care denumirea unui curs în tabela Curs semodifică, această modificare să se reflecte şi în tabela Curs_Student, fără ca ea sătrebuiască să fie făcută manual.

Pag. 25

Page 21: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 21/295

Fig. 2.8. Creearea tabelei Curs_Student

În continuare, vom descrie procedeul prin care valorile stocate în câmpul Cursal tabelei Curs_Student să poată fi selectate dintr-o listă definită de dumneavoastră.

1. în modul Table Design, alegeţi pentru coloana Curs: tipul LookupWizard, ca mai înainte.2. în prima cutie de dialog a lui Lookup Wizard alegeţi cea de-adoua opţiune, prin care specificaţi faptul că veţi introduce dumneavoastră

valorile dorite. Apăsaţi butonul Next.3. cea de-a doua cutie de dialog vă permite să specificaţi numărul decoloane ce vor fi afişate şi valorile lor. În câmpul Number of Columns,introduceţi cifra 2. În partea de jos a cutiei de dialog, vor apărea douăcoloane, în care introduceţi, de exemplu, datele din tabelul următor. Apoi,apăsaţi Next.

Col. 1 Col.21 Programare

2 Engleză3 Franceză4 Germană

4. în cea de-a treia cutie de dialog, specificaţi care dintre cele două coloaneva avea datele stocate în tabela Curs_Student. Alegem Col1, datele dinCol2 vor fi doar afişate, ajutând utilizatorul la alegerea lor. Astfel, datelestocate în tabelă vor ocupa mai puţin spaţiu. Apăsaţi butonul Next.

5. dialogul final vă cere să introduceţi denumirea coloanei. Aceasta este

Curs. Apăsaţi butonul Finish.

Pag. 26

Page 22: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 22/295

Acum, în pagina Lookup a ferestrei Table Design, puteţi modifica unele proprietăţi, cum ar fi lăţimea coloanelor (Column Widths) sau puteţi specifica dacăutilizatorul poate introduce în câmpul Curs Numai valori din listă sau şi alte valori(prin proprietatea Limit to List).

2.2.7 Value ListPuteţi beneficia de facilităţile coloanelor de tip Lookup (de căutare) şi fără aapela la Lookup Wizard (deşi aceasta este cea mai comodă cale). De exemplu, pentrua specifica o listă de valori aveţi grijă ca, în funcţie de tipul valorilor ce vor fi stocateîn tabelă, să alegeîi în câmpul Data Type tipul Text, Number sau Yes/No. În cazulexemplului nostru, tipul este Number (dacă aţi fi dorit să stocaţi în tabelă denumirile,ar fi trebuit să alegeţi tipul Text). Apoi, în pagina Lookup, pentru proprietatea DisplayControl stabiliţi valoarea Combo Box sau List Box, iar pentru proprietatea RowSource Type, alegeţi valoarea Value List. În câmpul proprietăţii Row Source

introduceţi valorile din tabel, parcurse pe linii, sub formă de listă, separate prin punctşi virgulă, ca în figura. (datele de tip text este bine să le introduceţi între ghilimele).

Fig. 2.9. Alcatuirea unei liste derulante

Dacă doriţi ca valorile pentru coloana de căutare să fie luată dintr-o tabelă, vatrebui să folosiţi Query Builder, un alt instrument util pus la dispoziţie de Access, cevă va permite să specificaţi coloanele din care să fie luate datele prin intermediul uneiinterogări. Despre interogări şi Query Builder vom vorbi în capitolele următoare.

Pag. 27

Page 23: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 23/295

2.2.8 Definirea cheilor primare şi a indecşilorUn index reprezintă o cale rapidă de localizare şi sortare a înregistrărilor dintr-

o tabelă prin gruparea tuturor înregistrărilor pentru un anumit atribut sau grup deatribute. Indexarea este utilizată în două scopuri principale:accelerarea căutărilor în

 baza de date şi asigurarea unicităţii înregistrărilor.De exemplu, dacă vă interesează anumite nume de familie în tabela Student, puteţi crea un index pentru coloana NumeSt, pentru a regăsi mai rapid studenţii cu unanumit nume de familie.

Cheia primară a unei tabele este indexată automat. Nu pot fi indexatecoloanele de tipul Memo, Hyperlink sau OLE Object.

Utilizarea unui index are sens doar dacă se vor face interogări frecvente relativla coloana indexată. Deşi accelerează procesul de regăsire a datelor, indecşiiîngreunează serios actualizarea lor. După fiecare operaţie de actualizare a datelor 

(inserare, modificare sau ştergere) trebuie să verificaţi şi să actualizaţi şi indecşii. Deaceea, folosurea lor trebuie să fie bine întemeiată, deoarece, altfel, ei pot mări timpulde răspuns al sistemului şi ocupă spaţiu suplimentar pe disc.

Pentru a crea cheia primară a unei tabele, treceţi în modul Design View alacelei tabele. Selectaţi coloana sau grupul de coloane ce va servi drept cheie primarăşi apoi apăsaţi butonul Primary Key de pe bara cu instrumente sau alegeţi comandaEdit | Primary Key.

 Notă: Pentru a selecta un câmp în Table Design View, faceţi clic în coloana

cea mai din stânga a ferestrei Table Design. Pentru a selecta mai multe câmpuri, ţineţiapăsată tasta Ctrl în timp ce efectuaţi operaţia de mai sus pentru fiecare câmp.Când o coloană face parte din cheia primară a unei tabele, proprietatea

Indexed are valoarea o coloană face parte din cheia primară a unei tabele, proprietateaIndexed are valoarea Yes (No Duplicates), adică Access indexează acea coloană şiduplicatele nu sunt permise. Proprietatea Required primeşte valoarea Yes, deoarececheia primară nu poate conţine valoarea null.

Să presupunem că se fac frecvente căutări în tabela Student, după numelecomplet (NumeSt+PrenumeSt). Pentru a crea un index pe aceste două coloane, procedaţi astfel:deschideţi tabela Student în Table Design View.apăsaţi butonul Indexes de pe bara de instrumente sau alegeţi comanda View |Indexes. Va apărea fereastra Indexes pentru tabela Student (fig.). Observaţi că eaconţinde deja o intrare pentru cheia primară a tabelei, NrMatricol, deci există un indexde pe coloana NrMatricol, numit Primary Key.

Pag. 28

Page 24: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 24/295

Fig. 2.10. Stabilirea indecşilor

1. deoarece sortarea studenţilor se va face după nume şi prenume, vom crea şi un index pe aceste coloane. Pentru aceasta,introduceţi în primul câmp liber al coloanei Index Name denumireaindexului: să-i spunem Nume.

2. faceţi clic în coloana Field Name a aceleiaşi linii şi alegeţi dinlista derulantă coloana NumeSt. Cum de cele mai multe ori vom dori

ca studenţii să fie sortaţi în ordine alfabetică, lăsaţi în coloana SortOrder valoarea Ascending.3. lăsaţi necompletat câmpul din linia următoare a coloanei Index

 Name (am precizat deja numele indexului) şi alegeţi în câmpul FieldName coloana PrenumeSt. Ordinea sortării va fi tot crescătoare.Astfel am creat indexul Nume pe coloanele NumeSt şi PrenumeSt.

Proprietăţile fiecărui index le puteţi vedea în partea de jos a ferestrei Indexesdacă faceţi clic în celula în care aţi specificat numele indexului (nume şi, respectiv,

Primary Key). Proprietăţile pentru noul index creat le puteţi vedea în figură.

Pag. 29

Page 25: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 25/295

Fig. 2.11. Crearea celui de-al doilea index

2.2.9 Crearea unei tabele folosind experţii Access.Pînă acum am discutat despre cel mai complicat mod de a crea o tabelă.

Acesta este şi modul care vă oferă cel mai mult control asupra tabelelor create şi proprietăţilor lor. Access vă pune la dispoziţie şi trei experţi: Table Wizard, ImportTable Wizard şi Linking Table Wizard.

Primul vă ajută să creaţi o tabelă pe baza unei tabele predefinite. Table Wizardvă dă posibilitatea să alegeţi tabela care să vă servească drept model, să selectaţicoloanele dorite, să le redenumiţi, să spuneţi dacă doriţi ca Access să creeze o cheie primară, să stabiliţi relaţii între noua tabelă şi alta existentă. O dată tabela creată, puteţi folosi modul Table Design pentru a-i modifica proprietăţile sau Table Datasheet  pentru a introduce datele. Table Wizard este util mai ales pentru aceia dintre

dumneavoastrp care nu au mai lucrat cu Access. Cei cu experienţă vor găsi că este maisimplu să pornească direct cu Table Design View.Expertul Import Table Wizard vă permite să importaţi obiecte şi date din surse

externe, cum ar fi: tabele Excel, dBase, Fox Pro, fişiere text, documente HTML, oricesursă ODBC disponibilă în sistemul dumneavoastră sau din alte baze de date Access.

Link table Wizard creează legături între baza de date curentă şi tabele dintr-unfişier extern (oricare din cele specificate mai sus). Puteţi vizualiza şi modifica dateledintr-o tabelă legată de baza dumneavoastră de date, să le modificaţi anumite proprietăţi, să stabiliţi relaţii. Dacă ştergeţi o tabelă legată din baza de date curentă, se

şterge doar legătura, nu şi tabela din baza de date sursă.2.3 Stabilirea relaţiilor între tabele

Posibilitatea de a crea şi de a folosi relaţiile dintre tabelele unei baze de dateeste punctul forte al bazelor de date relaţionale şi al sistemelor de administrare a bazelor de date relaţionale, cum este şi Microsoft Access.

Pentru a stabili relaţii între tabele, bazele de date relaţionale folosesc coloanecheie care sunt comune tabelelor pe care le leagă.

2.3.1. Fereastra RelationshipsRelaţiile pot fi definite fie în timpul creării unei tabele noi, fie după aceea.

Pentru a defini o relaţie, ambele tabele trebuie să existe în baz ade date.În primul caz, în care relaţia este definită în timpul creării unei tabele, veţi

folosi pentru definirea relaţiei ori expertul Table Wizard, ori coloanele de căutare.Table Wizard vă permite acest lucru într-una dintre cutiile sale de dialog. Cea de-adoua modalitate este să definiţi coloane de tip lookup (despre care am mai vorbit încadrul acestui capitol). Prin crearea unei coloane de tip lookup (de căutare) care să-şiia datele din altă tabelă, se stabileşte şi o relaţie între cele două tabele.

 Nu este necesar ca relaţiile să fie create o dată cu tabelele. De fapt, cel maisimplu mod de a crea o relaţie între două tabele este folosirea ferestrei Relationships.

Pag. 30

Page 26: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 26/295

Aceasta poate fi deschisă fie prin comanda Tools | Relationships, fie apăsând butonul Relationships de pe bara cu instrumente.

 Notă: înainte de a folosi fereastra Relationships pentru crearea saumodificarea unei relaţii, este bine să închideţi orice fereastră Datasheet View pentrucă nu pot fi impuse regulile de integritate referenţială dacă tabelele implicate sunt 

deschise într-unul din cele două moduri amintite.Dacă fereastra Relationships este deschisă pentru prima dată pentru baza de

date curentă sau dacă a mai fost folosită, dar relaţiile nu au fost salvate, ea va apărea pe ecran goală, împreună cu cutia de dialog Show table.

Fig. 2.12. Vizualizarea tabelelor pentru stabilirea de relaţii

Dacă pentru baza de date curentă există relaţii salvate, cutia de dialog Showtable nu va apăre ci, în fereastra, vor fi afişate tabelele şi relaţiile dintre acestea.Relaţiile sunt prezentate sub forma unei linii continue ce leagă câmpurile cheie aletabelelor ce participă la o relaţie.

Pentru a adăuga o tabelă sau o interogare la fereastra Relationships, faceţidublu clic pe numele ei în cutia de dialog Show Table. Astfel, ea va apărea înfereastra Relationships împreună cu toate relaţiile la care participă. Pentru a vedeatoate relaţiile care au fost definite pentru o anume tabelă, adăugaţi tabela la fereastraRelationships, închideţi cutia de dialog Show Table şi alegeţi comanda Relationships| Show Direct. Access va adăuga automat în fereastra Relationships toate tabelele care participă la relaţii cu tabela aleasă, precum şi relaţiile respective. Figura prezintărelaţiile la care participă tabela Curs_Student.

Pag. 31

Page 27: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 27/295

Fig. 2.13. Relaţiile petru tabela Curs_Student

Pentru a putea vedea relaţiile stabilite între toate tabelele bazei de date curente,alegeţi comanda Relationships | Show All. Pentru a înlătura o tabelă din fereastra

Relationships fără a şterge vreuna din relaţiile la care participă, selectaţi tabela făcândclic pe oricare dintre câmpurile ei şi apoi alegeţi comanda Relationships | Hide Tablesau Edit | Delete. (aveţi grijă să selectaţi o tabelă şi nu o relaţie). Pentru a înlăturatoate tabelele din fereastra Relationships fără a şterge relaţiile dintre ele, folosiţicomanda Edit | Clear Layout.

Din fereastra Relationships puteţi accesa modul Table Design View pentru otabelă. Pentru aceasta, faceţi clic pe unul dintre câmpurile tabelei şi din meniulderulant alegeţi comanda Table Design. (După ce terminaţi lucrul în fereastra TableDesign View, închideţi-o.)

2.3.2 Crearea relaţiilor dintre tabele.Acum, după ce aţi aflat cum să adăugaţi şi să înlăturaţi o tabelă din fereastra

Relationships, este timpul să învăţaţi cum se poate stabili o relaţie între două tabele.Vom crea o relaţie între tabelele Profesor şi Titlu. Pentru aceasta, procedaţi astfel:

1. adăugaţi ambele tabele la fereastra Relationships.2. faceţi clic pe câmpul IdTitlu din tabela Titlu şi, ţinănd mouse-ul apăsat,

trageţi câmpul peste câmpul IdTitlu din tabela Profesor.

Pag. 32

Page 28: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 28/295

Fig. 2.14. Stabilirea relaţiilor petru tabela Curs_Student

3. va apărea cutia de dialog Relationships (fig.) apăsaţi butonul Create pentrua accepta valorile propuse de Access. Acum, în fereastra Relationshipsrelaţia este figurată printr-o linie ce uneşte câmpurile IdTitlu din cele douătabele.

Fig. 2.15. Stabilirea relaţiilor între tabelele Profesor şi Titlu

De cele mai multe ori, pentru a crea o relaţie 1:m între două tabele va trebui sădeplasaţi cheia primară (afişată îngroşat) a uneia dintre tabele peste câmpulcorespunzător (cheie străină) din cealaltă tabelă. Cele două câmpuri trebuie să aibăacelaşi tip de date. Câmpurile de tip Autonumber, pentru care valoarea New Value arevaloarea Increment, pot fi puse în relaţie cu coloane de tipul Number, pentru careProprietatea Field Size este stabilită la Long Integer. Dacă ambele câmpuri sunt detipul Number, proprietatea Field Size trebuie să aibă aceeaşi valoare.

Pag. 33

Page 29: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 29/295

2.3.3 Proprietăţile relaţiilorCutia de dialog Relationships vă permite să stabiliţi proprietăţile relaţiilor.

Aici puteţi adăuga câmpuri pentru a defini o relaţie, făcând clic într-o celulă goală agrilei şi alegând câmpul dorit din lista derulantă. (Dacă adăugaţi un câmp, trebuie săalegeţi un câmp corespunzător din cealaltă tabelă.)

Dacă doriţi să schimbaţi câmpul unei tabele care participă la relaţie, faceţi clicîn celula care îl conţine şi alegeţi noul câmp ca mai înainte.

Tot aici puteţi stabili tipul de asociere ( join) pe care Access îl va folosi cândveţi crea o interogare bazată pe cele două tabele. Acest lucru îl realizaţi apăsând butonul Join Type. Se va deschide cutia de dialog Join Properties (fig.2.16). despretipurile de asociere vom vorbi în secţiunea următoare.

Fig. 2.16 Cutia de dialog Join Type

De asemenea, puteţi decide dacă Access va impune regulile de integritatereferenţială asupra tabelelor care participă la relaţie, problemă asupra căreia vomreveni.

2.3.4. Tipuri de asociere

Tipul de asociere (join) al unei relaţii specifică modul în care sunt regasiteinformaţiile din două tabele corelate şi nu afectează relaţia însăşi. Cele trei tipuri principale sunt: inner join, outer join şi self-join. Tipul outer join poate fi, la rândulsău, left outer join şi right outer join. Rezultatul unei interogări bazate pe douătabele corelate poate fi interpretat ca o tabelă în care fiecare linie este o combinaţie aunei linii luate din prima tabelă şi a uneia din cea de-a doua tabelă.

O asociere de tipul inner join este aceea în care liniile celor două tabele suntconcatenate şi adăugate la rezultatul unei interogări numai dacă valorile câmpurilor delegătură sunt egale. Acest tip de asociere este util atunci când doriţi numai

Pag. 34

Page 30: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 30/295

înregistrările care au valori în câmpurile corelate. Tipul inner join mai este cunoscutşi sub numele de equi-join şi este opţiunea implicită propusă de Access.

Tipul outer join este opusul lui inner join. El permite adăugarea unei linii larezultatele unei interogări chiar dacă nu există o linie corespunzătoare în tabelacorelată. De exemplu, dacă doriţi să vedeţi numai cursurile pentru care a optat cel

 puţin un student, folosiţi un inner join. Dacă doriţi să regăsiţi cursurile indiferent dacăau fost alese sau nu de cel puţin un student, folosiţi un outer join.O asociere de tipul left outer join (sau left join) vă dă posibilitatea să includeţi

în rezultatele interogării toate înregistrările din tabela din partea stângă a operatoruluiLEFT JOIN, iar din tabela din partea dreaptă, doar înregistrările care au corespondentîn tabela din stânga. Pentru a ilustra cele mai de sus, vă prezentăm interogarea ceregăseşte toate cursurile disponibile şi numerele matricole ale studenţilor care s-auînscris la cel puţin un curs:

SELECT Denumire, NrMatricolFROM Curs LEFT JOIN Curs_StudentON Curs.IdCurs = Curs_Student.IdCurs

O asociere de tip right outer join (right join) va include în rezultateleinterogării toate înregistrările din tabela din partea dreaptă a operatorului TIGHTJOIN, iar din tabela din partea stângă a operatorului doar înregistrările care au uncorespondent din tabela din dreapta. Observaţi că cei doi operatori, LEFT JOIN şi

RIGHT JOIN pot produce aceleaşi efecte dacă sunt schimbaţi între ei şi dacă semodofică ordinea tabelelor. Astfel, interogarea următoare va avea acelaşi efect ca şicea de mai sus:

SELECT Denumire, NrMatricolFrom Curs_Student RIGHT JOIN CursOn Curs.IdCurs = Curs_Student.IdCurs

  Notă: nu există nici o legătură între poziţionarea tabelelor în fereastra  Relationships (una la stânga celeilalte) şi poziţionarea lor în stânga sau îndreapta operatorului LEFT JOIN sau RIGHT JOIN. În cazul în care între douătabele există definită o relaţie, la creareea interogării Access va considera cătabela care conţine cheia primară este tabela din stânga operatorului.

După ce aţi selectat o asociere de tipul outer join, Access o va reprezenta printr-o linie cu săgeată la unul din capete. Reţineţi că sensul în care este orientatăsăgeata este dinspre tabela din care se vor include toate înregistrările către tabela dincare se vor include doar înregistrările ce au un corespondent.

O asociere de tip self-join este între două copii ale aceleiaşi tabele şi o puteţicrea prin corelarea a două câmpuri ale aceleiaşi tabele.

Pag. 35

Page 31: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 31/295

Access vă dă posibilitatea de a opta doar pentru inner join, left outer join sauright outer join. Pentru relaţia Profesor/Titlu, alegeţi în cutia de dialog Join Propertiesopţiunea cu nunărul unu, inner join.

2.3.5 Asigurarea integrităţii referenţiale

Access va asigura în mod automat integritatea referenţială pentru două tabelecorelate dacă veţi valida caseta de validare Enforce Referential Integrity din cutia dedialog Relationships. Astfel, dacă în tabela Profesor există o valoare pentru câmpulIdTitlu, va trebui ca acea valoare să existe şi în tabela Titlu. De asemenea, nu veţi putea şterge o înregistrare din tabela Titlu dacă tipul respectiv este atribuit unui profesor din tabela Profesor. Dacă veţi încerca să introduceţi date sau să le modificaţiastfel încât să fie încălcată integritatea referenţială, Access va afişa o cutie de dialogîn care vă va spune că acţiunea dorită nu se poate finaliza. De asemenea, vă va spuneşi care dintre tabelele corelate cauzează violarea integrităţii referenţiale.

Access vă dă şi posibilitatea de a specifica în ce mod doriţi să fie rezolvate problemele legate de integritatea referenţială. Astfel, puteţi alege ca modificările sauştergerile dintr-o tabelă să se reflecte şi în tabela corelată, pentru ca integritateareferenţială să nu fie afectată.

Prima opţiune vă este oferită prin intermediul casetei de validare CascadeUpdate Related Fields. Această opţiune vă asigurăcă orice modificare a valorilor dincheia primară a unei tabele va duce automat la modificarea corespunzătoare avalorilor din cheia străină a tabelei corelate. Astfel, dacă modificaţi o valoare acoloanei IdTitlu din tabela Titlu, Access va modifica, în consecinţă, toate apariţiile

acelei valori în coloana IdTitlu a tabelei Profesor.

2.3.6. Modificarea relaţiilor existentePentru a modifica o relaţie existentă între două tabele, adăugaţi tabelele

respective în fereastra Relationships. Apoi faceţi dublu clic pe linia ce reprezintărelaţia pe care doriţi să o modificaţi. Va apărea cutia de dialog Relationships, în care puteţi efectua modificările dorite.

Pentru a şterge o relaţie, selectaţi-o făcând clic pe linia care o reprezintă şiapoi apăsaţi tasta Delete.

2.4.1 Importul datelorPentru a importa un fişier în Access, selectaţi comanda File | Get External

Data | Import sau faceţi clic dreapta în fereastra Database şi alegeţi din meniulderulant comanda Import. Va apărea cutia de dialog Import (fig.2.17).

Pag. 36

Page 32: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 32/295

Fig. 2.17. Importul datelor

Aici puteţi alege fişierul pe care doriţi să-l importaţi. În funcţie de formatul defişier ales, Access, va prezenta cutiile de dialog corespunzătoare, în care veţi puteaspecifica opţiunile dumneavoastră.

2.4.2 Exportul datelorAccess vă dă posibilitatea de a exporta toate tipurile de obiecte dintr-o bază de

date. Totuşi, există câteva reguli de care este bine să ţineţi cont:•  puteţi exporta o tabelă sau o interogare fie salvând-o într-un fişier nou,

fie într-o nouă tabelă sau interogare din baza de date curentă.•  puteţi exporta un formular sau un raport în unul din formatele: Access,

Excel, text şi RTF (Rich Text Format). În toate cazurile în afară deformatul Access , veţi exporta şi datele ce creează formularul sauraportul.

• Puteţi exporta un modul numai în formatul Access sau text.

Pentru a exporta un obiect din baza de date curentă, selectaţi-l în fereastraDatabase şi alegeţi comanda File | Save As | Export. Va apărea o cutie de dialog carevă va întreba dacă doriţi să salvaţi obiectul într-un fişier extern sau în baza de datecurentă. Dacă selectaţi prima opţiune, va apărea cutia de dialog prezentată în fig. .

Pag. 37

Page 33: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 33/295

Fig. 2.17. Exportul datelorAici puteţi alege tipul de fişier extern în care doriţi să salvaţi obiectul şi locaţiaacestuia. În funcţie de formatul ales, Access va prezenta diferite interfeţe.

2.4.3. Formate standardAccess vă pune la dispoziţie peste unsprezece formate pentru exportul datelor 

şi peste nouă formate pentru import. De asemenea, aveţi la îndemână şi trei experţi :Import Text Wizard, care vă ajută să importaţi date din formatul text, ImportSpreadsheet Wizard, pentru importul tabelelor Excel sau lotus şi Export Text Wizard,

 pentru exportul datelor în format text.

• Microsoft FoxPro (.DBF): puteţi importa sau exporta date în format FoxPro,versiunile de la 2.0 la 3.0.

• DBase (.DBF): puteţi importa sau exporta date în format dBase, versiunile III, IVşi V.

• Paradox (.DB): puteţi importa sau exporta date în formatul Paradox, versiunile3.x, 4.0 şi 5.0.

• Baze de date ODBC: pentru a importa sau exporta date din sau în Microsoft SQL

Server, Sybase SQL Server, Oracle Server sau alte formate, trebuie să aveţiinstalat un driver ODBC.

• Microsoft Excel (.XLS): puteţi importa sau exporta date în format Excel,versiunile 3.0 – 7.0 şi 97.

• Lotus: puteţi importa sau exporta date în format Lotus 1-2-3.• Text: formatele text în care puteţi importa sau exporta date sunt: .TXT, .CSV,

.TAB, .ASC. În plus, puteţi exporta în formatul .RTF (Rich Text Format).• Access: formatele Access în care puteţi importa sau exporta date sunt: .MDB,

.MDW, .MDA şi .MDE.• HTML: formatele disponibile pentru importul şi exportul datelor sunt .HTML

şi .HTM. Puteţi ataşa ieşirea unui obiect la un mesaj e-mail.

Pag. 38

Page 34: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 34/295

CAP:3. Interogări

Interogările sunt una dintre cele mai puternice componente din Access 97. Elevă permit să regăsiţi anumite informaţii stocate în baza de date. Abilitatea de a creainterogări este considerată a fi „creierul” unui sistem de baze de date relaţional,deoarece nu contează doar faptul că puteţi stoca informaţii, ci mai ales faptul că puteţiregăsi exact informaţia de care aveţi nevoie la un moment dat.

În Access, interogările deţin un rol foarte important (ele pot fi sursa unuiraport, formular sau a listei de valori posibile pentru o coloană de căutare). Existădouă modalităţi de creare a interogărilor în Access: folosirea ferestrei QBE (Query by

Example), numită şi Query Design, sau introducerea directă de comenziSQL.indiferent pe care dintre cele două moduri le folosiţi, intern, interogarea va fidefinită tot ca o instrucţiune SQL. Access SQL este dialect care diferă substanţial destandardul ANSI.

3.1. Folosirea ferestrei QBE

După cum puteţi observa din fig.3.1, fereastra QBE este compusă din două părţi. Partea de sus (pe care o vom numi şi panou) prezintă tabelele pe care se bazează

interogarea şi relaţiile dintre ele. Partea de jos, numită şi grila QBE, precizeazăcâmpurile tabelelor şi criteriile pe baza cărora este definită interogarea. Deşi arelimitările sale, folosirea ferestrei QBE este un mod simplu şi intuitiv de a crea ointerogare.

Fig. 3.1. Fereastra QBE (Query by Example)

Pag. 39

Page 35: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 35/295

3.1.1. Specificarea surselor de datePuteţi specifica sursele de date pe care se bazează o interogare(tabele sau alte

interogări) fie în timpul creării interogării, fie după aceea prin intermediul cutiei de

dialog Show Table. Aceasta va apărea automat la crearea unei noi interogări sau dacăalegeti comanda Query | Show Table. Aici puteţi selecta tabelele sau interogările cese vor servi drept sursă de date pentru interogarea curentă. O altă cale prin care puteţiadăuga tabele sau interogări la interogarea curentă este de a le plasa din fereastraDatabase în panoul ferestrei QBE.

Pentru a defini o interogare,trebuie să aveţi cel puţin o tabelă sau o interogareîn panoul ferestrei QBE, şi cel puţin un câmp în grila ferestrei QBE. După cumspuneam, rezultatele unei interogări sunt prezentate sub forma unei tabele virtuale, alecărei câmpuri sunt cele specificate în grila QBE. Datele acestei tabele sunt selectate

din câmpurile din grila QBE pe baza unor criterii.Dacă doriţi ca rezultatul interogării să conţină anumite câmpuri ale unei tabelesau interogării din panoul ferestrei QBE, introduceţi-le în grila QBE în felul următor:selectaţi-le în tabela sau interogarea respectivă (făcând clic pe ele) şi deplasaţi-le pestegrila QBE. Pentru a introduce în grilă toate câmpurile unei tabele, sau interogări din panou, selectaţi asteriscul care apare imediat sub bara de titlu şi deplasati-l peste grilă.Chiar dacă rezultatul interogării va conţine toate câmpurile din tabelă (rezultatul îl puteţi vedea în modul Datasheet View, în care treceţi cu comanda View | DatasheetView), în grila QBE va apărea doar asteriscul. Dacă doriţi să stabiliţi anumite criterii

 pe baza cărora datele unui câmp să fie incluse în rezultatul interogării, câmpul trebuiesă fie vizibil în grilă, aşa că va trebui să-l introduceti separat.O altă cale de a introduce în grila QBE un câmp este să faceţi clic în prima

celulă liberă din linia Field a grilei şi să apăsaţi butonul don dreapta. Se va deschide olistă cu toate câmpurile tavelelor şi interogărilor din panoul QBE. O dată selectat uncâmp, se va completa automat şi celula corespunzătoare din linia Table.

3.1.2. Proprietăţile interogărilorCând vorbim despre proprietăţile unei interogări ne referim de fapt la

 proprietăţile mai multor obiecte: ale interogării ca obiect în sine, ale tabelelor, alecâmpurilor acestora şi relaţiilor.

Dacă selectaţi o interogare din pagina Queries a ferestrei Database şi apoiapăsaţi butonul Properties de pe bara cu instrumente, se va deschide cutia de dialog prezentată în figură:

Pag. 40

Page 36: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 36/295

Fig. 3.2. Proprietăţile interogăriilor

Pentru fiecare obiect puteţi introduce o descriere de maximum 255 decaractere. Pe lângă descriere, cutia de dialog Properties vă arată când a fost creatobiectul, când a fost modificat ultima dată şi cine este proprietarul lui. Dacă validaţicaseta Hidden, obiectul nu va mai apărea în fereastra Database (aceasta este o măsurăde securitate). Cea de-a doua casetă de validare vă lasă să specificaţi dacă obiectuleste replicabil.

Pentru a vedea şi obiectele cu proprietatea Hidden (ascunse), alegeţi comandaTool | Options şi, în pagina View, validaţi caseta Hidden Objects.Pentru a vedea pagina de proprietăţi a ferestrei QBE, faceţi dublu-clic în

 panou. Aceasta este o pagină detaliată de proprietăţi a interogării.În continuare, vom prezenta în detaliu aceste proprietăţi:

• Description: aici puteţi introduce o descriere de maximum 255 de caractere ainterogării.

• Output All Fields: valoare Yes va introduce în rezultatele interogării toatecâmpurile tabelelor/interogărilor din panoul QBE.

Top Values: returnează numai primele n sau n% înregistrări.

• Unique Values: dacă valoarea sa este Yes, returnează numai înregistrărileunice pentru câmpurile din grila QBE. De exemplu, dacă în grilă se află numaicâmpul IdCurs al tacelei Curs_Stud, vom vedea numai valorile unice a luiIdCurs.

• Unique Records: dacă valoarea sa este Yes, returnează numai înregistrărileunice în cadrul sursei de date (tabelă sau interogare).

• Run Permissions: specifică dacă interogarea rulează cu drepturile proprietarului (owner’s) sau a utilizatorului (user’s). Astfel, puteţi da unuiutilizator permisiunea de a efectua o acţiune pe care, altfel, nu ar avea drept săo execute.

Pag. 41

Page 37: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 37/295

• Source Database: puteţi specifica o bază de date externă care conţine tabeleleşi interogările sursă. Valoarea implicită este baza de date curentă.

• Source Connect String: numele şi versiunea aplicaţiei în care a fost creată

 baza de date externă, urmate de punct şi virgulă (ex: dBase IV;).• Record Locks: această proprietate este utilă pentru sistemele multiuser şispecifică modul în care sunt blocate datele în timpul execuţiei interogării.

• ODBC Timeout: timpul, în secunde, în care se întrerupe execuţia interogăriidacă serverul ODBC nu răspunde.

• Filter: funcţionează asemănător cu opţiunea Criteria a grilei QBE. Estecompletat automat în timpul rulării interogării dacă în modul Datasheet Viewveţi folosi comentile Filter by Form, Filter by Selection sau AdvancedFilter/Sort din meniul Records. Vă permite să selectaţi anumite înregistrări din

rezultatul interogării.• Order By: funcţionează asemănător cu secţiunea Sort a grilai QBE. Estecompletat automat în timpul rulării interogării dacă în modul Datasheet Viewselecteţi o coloană (sau două) şi apoi apăsaţi butonul Sort Ascending sau ortDescending de pe bara cu instrumente.

Acestea au fost proprietăţile unei interogări privite ca întreg. Pe lângă acestea, puteţi stabili şi unele proprietăţi ale obiectelor ce compun interogarea: tabele, alteinterogări şi câmpuri.Proprietăţile lor le puteţi vedea în modul Design View

selectându-le şi, apoi, alegând comanda View | Properties.Cele două proprietăţi disponibile pentru tabele sunt următoarele:

• Alias: Vă dă posibilitatea să specificaţi un nume alternativ, temporar pentru otabelă. Este util în cazul în care interogarea se bazează pe o asociere self-join.

• Source: Este asemănătoare cu proprittăţile Source Database sau SourceConnect String ale unei interogări. Sacă interogarea foloseşte tabele din maimulte baze de date externe, stabiliţi acestă proprietate pentru fiecare tabelă în parte.

Fiecare câmp din grila QBE are proprietaţile sale. Cutia de dialog Properties pentru un câmp are două pagini: General şi Lookup. Iată care sunt aceste proprietăţi:

• Descriptions: Conţine o descriere a câmpului, de maximum 255 de caractere.• Format: Vă permite să specificaţi modul în care vor fi afişate şi tipărite datele

din câmpul respectiv.• Imput Mask : Funcţionează ca şi proprietatea Format, cu diferenţa că aici

 puteţi preciza un format pentru introducerea datelor. Dacă apăsaţi butonul dindreapta câmpului Imput Mask, va porni un wizard care vă va ajuta săspecificaţi modul în care vreţi să arate datele.

• Decimal Places: Pentru câmpurile numerice, precizează numărul de zecimalecare vor fi afişate.

Pag. 42

Page 38: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 38/295

• Caption:Titlul sub care va apărea câmpul în modul Datasheet View sau pe unformular.

• Display Control: Tipurile de control folosite pentru afişarea datelor câmpuluirespectiv în modul Datasheet View sau pe un formular sunt: text box, list box

sau combo box. Acestea sunt disponibile numai pentru câmpuri numerice, textşi de tip yes/no. Dacă celectaţi list box sau combo box, vor apărea atributelecorespunzătoare.

 Notă: pentru acelaşi câmp, puteţi stabili calităţi diferite în interogări diferite. Dacă un formular este bazat pe o tabelă, atributele câmpurilor sunt cele specificateîn tabelă. Dacă formularul se bazează pe o interogare, atributele câmpurilor sunt cele specificate în interogare.

3.2. Tipuri de interogări

Există interogări pentru regăsirea datelor (cele de tip selectare) şi pentrumodificarea datelor (inserare, ştergere şi actualizare). Până acum am vorbit numaidespre interogări simple de tip selectare. Pentru a crea o astfel de interogare nu trebuiedecât să folosiţi fereastra QBE pentru a specifica sursele datelor pe care doriţi să leaflaţi şi, eventual, tipul de asociere. Rezultatele interogării le puteţi vedea intrând în

modul Datasheet pentru acea interogare. Pentru aceasta, alegeţi comanda Query |Run sau apăsaţi butonul Run de pe bara cu instrumente.În afară de interogările de tip selectare simple, Acces vă mai oferă un tip de

interogări pentru regăsirea datelor: interogările agregat.

3.2.1. Interogări agregatInterogările agregat vă dau posibilitatea de a analiza datele, calculând sume,

extreme, medii, dispersii etc. Ele vă pot fi foarte utile la întocmirea rapoartelor statistice sau a graficelor. Cele două tipuri de interogări agregat pe care Access le pune la dispoziţie sunt Totals şi Crosstab.

3.2.2. Interogări de tip totalsSă presupunem că doriţi să aflaţi numărul de studenţi înscrişi în fiecare curs

opţional. Interogarea care vă va furniza aceste informaţii este prezentată în fig. înmodul Design View şi în fig. 3.3 în modul Datasheet View (rezultatele).

Pag. 43

Page 39: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 39/295

Fig. 3.3. Mod de realizare a interogărilor de tip Total

Pentru a crea o interogare de tip totals, procedaţi astfel:1. creaţi o nouă interogare de tip select şi adăugaţi tabelele necesare la panoul

ferestrei Qbe.

2. introduceţi în grila ferestrei QBE coloanele pentru care doriţi să calculaţitotalul, media, extremele etc.

Fig. 3.4. Mod de realizare a interogărilor de tip Medie

Pag. 44

Page 40: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 40/295

3. schimbaţi tipul interogării în Totals, alegând comanda View | Totals sauapăsând butonul Totals de pe bara cu instrumente. Observaţi că în câmpulTotal al grilei QBE va apărea în dreptul coloanelor selectate opţiunea GroupBy.

4. selectaţi în grila QBE coloana în funcţie de care doriţi să aflaţi totalul, sumamedia etc. coloanelor cu opţiunea Group By. În câmpul Total corespunzător acestei coloane alegeţi una dintre funcţiile agregat, care să efectueze operaţiadorită.

5. stabiliţi eventuale criterii şi rulaţi interogarea.

În continuare, vom vorbi mai pe larg despre opţiunile unei interogări de tipTotals. Fiecare coloană selectată în grila ferestrei QBE trebuie să aibă specificată o

opţiune în câmpul Total. Iată care pot fi aceste opţiuni:• Group By: folosită pentru a defini grupurile de înregistrări pentru care doriţi

să calculaţi totalurile. Dacă în grila QBE selectaţi o singură coloană, cuopţiunea Group By, interogarea va returna o linie pentru fiecare valoare unicăa coloanei respective. Dacă selectaţi mai multe câmpuri cu opţiunea Group By,rezultatele interogării vor conţine câte o linie pentru fiecare combinaţie unicăde valori ale câmpurilor respective.

• Count: funcţie agregat folosită pentru a număra înregistrările dintr-un grup ale

căror valori sunt diferite de null.• Sum: funcţie agregat folosită pentru a calcula suma valorilor unui câmp, pentru fiecare grup definit de opţiunea Group By.

• Min: funcţie agregat ce calculează valoarea minimă a unui câmp pentrufiecare grup. Valorile null nu sunt luateîn considerare.

• Max: funcţie agregat ce calculează valoarea maximă a unui câmp pentrufiecare grup. Valorile null nu sunt luateîn considerare.

• First:  funcţie agregat folosită pentru a afla prima valoare (într-o anumităordine) a unui câmp pentru fiecare grup. Valorile null nu sunt luate înconsiderare.

• Last: funcţie agregat folosită pentru a afla ultima valoare (într-o anumităordine) a unui câmp pentru fiecare grup. Valorile null nu sunt luate înconsiderare.

• Avg: funcţie agregat ce calculează media valorilor unui unui câmp pentrufiecare grup definit prin opţiunea Group By. Valorile null nu sunt luate înconsiderare.

• StDev: funcţie agregat ce calculează deviaţia standard a valorilor unui unuicâmp pentru fiecare grup. Deviaţia standard este un estimator statistic aldispersiei distribuţiei valorilor unui câmp. Valorile null nu sunt luate înconsiderare.

Pag. 45

Page 41: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 41/295

• Var: funcţie agregat ce calculează dispersia valorilor unui unui câmp pentrufiecare grup. Dispersia este pătratul deviaţiei standard. Valorile null nu suntluate în considerare.

• Expression: folosită pentru a calcula alte totaluri decât cele oferite de funcţiileagregat, prin intermediul unei expresii introduse de dumneavoastră. O expresie

 poate fi orice combinaţie de oparatori, contante, nume de coloane,funcţii agregat, etc., prin evaluarea căreia obţinem o singură valoare. O astfelde expresie este Count(*), ce calculează numărul total de înregistrări dintr-ungrup, incluzând inregistrările care conţin valoarea null.

• Where: clauză folosită pentru specificarea unor criterii care să limitezerezultatele interogării. Când folosiţi această opţiune, devalidaţi caseta din liniaShow a grilei QBE corespunzătoare coloanei asupra cărei impuneţi limitările.

3.2.2.1 Sortarea rezultatelor unei interogări de tip totalsAccess vă dă posibilitatea de a sorta crescător sau descrescător rezultatele unei

interogări, alegând în câmpul Sort al grilei QBE opţiunea Ascending sau Descending.Dacă folosiţi mai multe coloane cu opţiunea Group By, Access va sorta automatdatele, întâi în funcţie de prima coloană din grila QBE, apoi în funcţie de a doua, etc.,de la stânga spre dreapta. În exemplul din figura., înregistrările sunt sortate crescător,întâi în funcţie de numele studentului şi apoi de prenume. Dacă am fi dorit cainterogările să fie sortate întâi în funcţie de prenume şi apoi în funcţie de nume (ca în

figura), nu ar fi trebuit decât să trecem în grila QBE coloana PrenumeSt în stângacoloanei NumeSt.Access urmează următoarele reguli pentru sortarea rezultatelor unei interogări

de tip Totals:• Dacă în câmpul Sort al grilei QBE corespunzător coloanelor cu opţiunea

Group By alegeţi Not sorted, adică nu specificaţi modul în care să fie sortatedatele, Access va sorta crescător aceste coloane, precedenţa fiind de la stângaspre dreapta.

• Dacă în câmpul Sort al grilei QBE corespunzător coloanelor cu opţiuneaGroup By specificaţi opţiunea Ascending sau Descending, Access va sortacrescător respectiv descrescător aceste coloane, precedenţa fiind de la stângaspre dreapta.

• Dacă specificaţi ordinea de sortare numai pentru anumite coloane (pentruunele dintre coloanele cu opţiunea Group By, pentru coloanele agregat sau pentru o combinaţie de coloane agregat şi Group By), Access va sorta numaicoloanele pentru care aţi specificat ordinea respectând precedenţa de la stângaspre dreapta.

Pag. 46

Page 42: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 42/295

3.2.2.2 Stabilirea criteriilorSă presupunem că doriţi să aflaţi care sunt studenţii al căror nume începe cu

litera „P” şi a căror medie este peste 7. Figura prezintă interogarea care vă furnizeazăaceste informaţii în modul Design View.

Fig. 3.5.Exemplu de realizare a interogărilor

Primul criteriu este deci aplicat unei coloane având opţiunea Group By,  NumeSt, iar cel de-al doilea criteriu este aplicat unei coloane agregat. Criteriileimpuse asupra coloanelor având opţiunea Group By sau Where sunt luate înconsiderare înainte ca datele să fie grupate, în timp ce criteriile asupra coloanelor agregat sunt impuse după ce datele au fost grupate şi s-au aplicat funcţiile agregat.

Dacă doriţi totuşi să impuneţi limitări şi asupra datelor ce vor fi supuseoperaţiilor de agregare, puteţi face acest lucru prin intermediul opţiunii Where. Să

 presupunem că dorim să aflăm media cursurilor la care studenţii al căror nume începecu „P” au luat peste nota 7. acest lucru îl puteţi realiza dacă ştergeţi criteriul „>7”impus coloanei agregat Media şi îl aplicaţi coloanei Nota având opţiunea Where, ca înfig. 3.6.

Pag. 47

Page 43: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 43/295

Fig. 3.6.Exemplu de realizare a interogărilor

 Notă: criteriile asupra coloanelor agregat sau cu opţiunea Group By sunt  specificate în SQL cu ajutorul clauzei HAVING, iar criteriile asupra coloanelor cuopţiunea Where sunt implicate în SQL în cadrul clauzei WHERE.

3.2.3. Interogări de tip Crosstab Interogările de tip Crosstab se aseamănă cu cele de tipul Totals prin faptul că

vă permit aplicarea operaţiilor de agregare asupra datelor. Ceea ce le deosebeşte estemodul de afişare a rezultatelor. Rezultatele unei interogări Crosstab sunt prezentate

sub forma unei tabele în care atât coloanele, cât şi liniile, au titluri.Să presupunem că dorim să aflăm, pentru fiecare catedră, numărul de profesoridin fiecare categorie (preparatori, asistenţi, lectori, etc.).Ar fi convenabil ca datele săfie afişate într-un tabel având catedrele drept capete de linii şi titlurile drept capete decoloane. Pentru aceasta, veţi crea o interogare Crosstab (pe care o puteţi numiTotal_Profesori_Crt), în felul următor:

1. Creaţi o nouă interogare de tip select şi adăugaţi tabelele necesare.2. Introduceţi în grila QBE cele două câmpuri de valori care vor defini

grupurile (de exemplu, Catedra şi Titlu).3. Schimbaţi tipul interogării în Crosstab, alegând comanda Query |Crosstab Query. În câmpul Total al grilei QBE corespunzător celor douăcoloane va fi selectată opţiunea Group By.

4. Alegeţi care dintre cele două câmpuri va da numele liniilor şi care pe celeale coloanelor în cadrul tabelei cu rezultatele interogării, selectândopţiunea Row Heading, respectiv Column Heading în celulacorespunzătoare din câmpul Crosstab al grilei QBE.

5. În funcţie de datele pe care doriţi să le aflaţi, introduceţi într-o nouă

coloană a grilei QBE opţiunile dumneavoastră. Pentru exemplul nostru,introduceţi în câmpul Field expresia IdProf: Count(*), în câmpul Totalselectaţi Expression, iar în câmpul Crosstab selectaţi opţiunea Value.

Pag. 48

Page 44: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 44/295

6. Stabiliţi eventuale criterii şi rulaţi interogarea.

Figura prezintă interogarea în modul Design View.Câmpul care dă numele coloanelor din tabela cu rezultatele interogării poartă

numele de pivot. În cazul interogării prezentate în figura câmpul pivot este Titlu iar în

următoarea este prezentat rezultatul.

Fig. 3.7. Exemplu de realizare a interogărilor de tip Crosstab

3.2.3.1 Crearea totalurilor pe liniiPuteţi crea o coloană care să arate totalul valorilor pe o linie, adăugând la grila

QBE un duplicat al coloanei care are opţiunea Value. Duplicatul trebuie să aibă unalias(pe care îl puteţi introduce in câmpul Field corespunzător, înaintea expresiei şiurmat de două puncte) şi să aibă opţiunea Row Heading în câmpul Crosstab.

Pag. 49

Page 45: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 45/295

Fig. 3.8. Exemplu de realizare a totalurilor pe linie pentru interogărilor de tipCrosstab

3.2.3.2 Limitările intergărilor CrosstabDupă cum aţi observat, într-o interogare de tip Crosstab numele coloanelor sunt luate dintre valorile coloanei cu opţiunea Column Heading. De aceea, ele ar  putea să încalce regulile impuse numelor de coloane. De exemplu, dacă o coloană detip text, conţinând, printre altele şi unele valori precum ON, AS sau alte cuvinterezervate, va da numele coloanelor într-o interogare crosstab, acea interogare nu

va putea fi folosită ca sursă de date pentru un raport, grafic sau altă interogare. Deregulă, puteţi rezolva această problemă incluzând numele ilegale între paranteze

drepte ([ON]).În al doilea rând, în interogările crosstab nu puteţi impune criterii asupracâmpurilor cu opţiunea Value. De exemplu, dacă vom dori ca interogareaTotal_Profesori_Crt să ne dea catedrele care au mai mult de 2 profesori din fiecarecategorie (titlu), nu vom putea specifica „>=2” în câmpul Criteria al coloanei de tipValue. Puteţi înlătura acest inconvenient cu ajutorul unei interogări de tip Totals, pecare o vom folosi în interogarea Crosstab. Creaţi deci o interogare de tip Totals,numită Total_Profesori, bazată pe tabelele Profesor şi Titlu, în care câmpurile Catedraşi Titlu să aibă opţiunea Group By, iar pentru agregare să se folosească expresia:Count (*) (ca în fig. ), pentru care puteţi impune şi criteriul „>=2”. Daţi câmpuluiagregat numele TotalPr.

Pag. 50

Page 46: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 46/295

Apoi, creaţi interogarea Cross_Total_Profesori, de tip Crosstab şi bazaţi-o peTotal_Profesori, în care catedra va fi Row Heading, Titlu va fi Column Heading şiTotalPr va avea opţiunea Value. Deoarece datele din coloana TotalPr a interogăriiTotal_Profesori_Crt au fost agregate o dată, alegeţi în câmpul Total al grilei QBEcorespunzător lui TotalPr o funcţie agregat care, aplicată unei singure valori, să de ca

rezultat acea valoare (Sum, Min, Max, Avg, First, Last).Valori NULL în coloane Row Heading sau Column Heading

Să presupunem că în tabela Profesor există şi înregistrări pentru care câmpulIdTitlu are valoarea NULL. În acest caz, rezultatele interogării Total_Profesor_Crt vor conţine şi o coloană al cărui nume va fi „<>”.

Această problemă poate fi rectificată prin două metode. Prima ar fi să nu luămîn considerare înregistrările care conţin valoarea Null în câmpul IdTitlu. Acest lucru îl putem realiza introducând criteriul „Is Not Null” în câmpul Criteria corespunzător 

coloanei Titlu. În acest mod, rezultatele interogării nu vor da nici un fel de informaţiidespre profesorii pentru care titlul nu a fost specificat.Dacă totuşi, nu ne putem lipsi de aceste informaţii, vom face în aşa fel încât în

locul semnului „<>”, pentru numele coloanei să apară un text dorit de noi în cazul încare valoarea este NULL. Pentru aceasta, vom introduce în câmpul Field al grilei QBEcorespunzător coloanei cu opţiunea Column Heading (care conţine valorile null şi dănumele coloanelor tabelei cu rezultate), expresia:

IIf (IsNull([Titlu]), „Nespecificat”, [Titlu])

Expresia de mai sus se traduce astfel: „Dacă valoarea câmpului Titlu este Null,atunci pentru titlul coloanei din tabela de rezultate se va afişa „Nespecificat”; altfel, seva afişa valoarea din câmpul Titlu”.

3.2.4. Interogări pentru definirea şi modificarea datelorInterogările pentru definirea şi modificarea datelor vă dau posibilitatea de a

actualiza eficient, printr-o singură operaţie, mai multeînregistrări. Cele 4 tipuri deinterogări care pot efectua diferite acţiuni asupra datelor sunt: interogări de tipul MakeTable, Update, Append şi Delete.

3.2.4.1. Interogări de tip Make TableInterogările de tip Make Table vă ajută să creaţi tabele noi furnizate cu tabele

existente sau alte interogări. Ele vă pot fi utile dacă doriţi să faceţi o copie desiguranţă a unei tabele sau să exportaţi date către alte baze de date Access sau ODBC.

Pentru a crea o interogare de tipul Make Table, deschideţi o nouă interogare şiintroduceţi în panoul ferestrei QBE tabelele (sau interogările) care vor furniza datele pentru noua tabelă. Apoi selectaţi în grila QBE coloanele care vor compune nouatabelă şi, eventual, specificaţi criterii pentru limotarea datelor. Dacă veţi dori ca înnoua tabelă coloanele să aibă alte nume, introduceţi aceste nume în câmpul Field al

Pag. 51

Page 47: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 47/295

grilei QBE, înaintea numelor coloanelor existente şi urmate de două puncte (deexemplu, Nume Profesor: Nume). Pe urmă, alegeţi comanda Query | Make TableQuery sau apăsaţi butonul Query Type de pe bara cu instrumente şi alegeţi MakeTable Query. Va apărea cutia de dialog Make Table, în care va trebui să specificaţinumele tabelei pe care vreţi să o creaţi şi, în cazul încare tabela va face parte dintr-o

 bază de date externă, numele acesteia cu calea completă. Dacă baza de date externă nueste Access, introduceţi între ghilimele şi urmat de punct şi virgulă numele aplicaţieiîn care a fost creată (de exemplu: c:\my documents\dbl „Paradox;”).

Puteţi vedea noua tabelă înainte ca ea să fie creată, trecând în modulDatasheet View. Dacă rezultatele sunt corecte, rulaţi interogarea şi noua tabelă va ficreată; dacă nu, întoarceţi-vă în modul Design View şi efectuaţi modificările necesare.

Dacă, ulterior, veţi dori să actualizaţi datele din tabela creată astfel, pentru caele să reflecte modificările din tabela de bază, nu va trebui decât să rulaţi din nou

interogarea respectivă.3.2.5. Interogări de tip AppendPentru aceasta, vom crea o nouă interogare de tip Append (numită

AppendProf), alegând comanda Query | Append Query. Va apărea cutia de dialogAppend, în care va trebui să specificaţi numele tabelei în care vor fi introduse dateleşi baza de date în care se află această tabelă (interogarea nu va putea fi executată dacătabela nu există deja). Apoi, cu ajutorul ferestrei Qbe, veţi preciza tabelele şicâmpurile acestora din care vor proveni datele, precum şi câmpurile tabelei destinaţie.

După cum puteţi observa în fig., grila QBE a unei interogări de tip Append conţine şilinia Append To, în care, pentru fiecare câmp-sursă selectat în grilă, puteţi alegecâmpul destinaţie (cu condiţia ca cele 2 câmpuri să aibă acelaşi tip de date).

 Notă: în cazul încare câmpurile sursă şi destinaţie au acelaşi nume, Access vaalege automat câmpul destinaţie, în momentul selectării câmpului sursă în grila QBE.

Acum, tot ce vă rămâne de făcut este să rulaţi interogarea şi să deschideţitabela ProfMate în modul Datasheet View pentru a vedea noile înregistrări.

3.2.6 Interogări de tip UpdateInterogările de tip Update vă sunt utile atunci când doriţi să modificaţi mai

multe înregistrări o dată. Să presupunem că toate salariile mai mici de 1.000.000 lei semajorează cu 15%. Pentru a actualiza în consecinţă datele din tabela Titlu, vom creatabela Majorare_Salariu, de tip Update. Pentru aceasta, creaţi o nouă interogare,introduceţi tabela Titlu în panoul ferestrei QBE şi schimbaţi tipul interogării înUpdate, alegând comanda Query | Update. În grila ferestrei QBE va apărea o nouălinie, Update To, în care veţi introduce regula pe baza căreia se va face actualizarea

Pag. 52

Page 48: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 48/295

(în acest caz, [Salariu] + [Salariu]*.15). în câmpul Criteria al grilei QBE vom limitaînregistrările ce vor fi actualizate la cele pentru care salariul este 1.000.000.

Interogările de tip Update au anumite limitări care fac să nu poată fi executateuneori. Înaceste situaţii, Access va da un mesaj de eroare. Iată care sunt cele maifrecvente situaţii în care o interogare de tip Update nu va putea fi executată:

interogarea este bazată pe altă înterogare de tip Crosstab, Union sau careconţine totaluri;• interogarea este bazată pe 2 tabele între care există o relaţie de tipul 1:m

(integritatea referenţială ar putea fi violată);• interogarea încearcă să scrie un text într-un câmp de tip Number;• interogarea încalcă regulile de validare impuse asupra datelor unui câmp la

nivel de tabelă.

3.2.7 Interogări de tip Delete

Folosind o interogare de tip Delete, puteţi şterge dintr-o tabelă mai multeînregistrări o dată. Notă: înainte de a executa o interogare de tip Delete, este bine să creaţi pe

aceleaşi criterii o interogare de tip Select care să regăsească datele pe care doriţi săle ştergeţi. Dacă ele sunt corecte, puteţi rula interogarea Delete fără grijă.

3.2.8 Interogări cu parametriPuteţi crea interogări care să permită utilizatorului specificarea unui criteriu în

timpul rulării interogării. Pentru a crea o astfel de, interogare va trebui să :

• introduceţi în câmpul Criteria corespunzător coloanei asupra căreia vor fi impuse limitările un text prin care să cereţi utilizatorului specificareacriteriului (textul va fi inclus între paranteze drepte, ca în figura )

• folosiţi comanda Query / Parameters pentru a specifica tipul datelor cevor fi introduse de utilizator în timpul rulării interogării (figura)

3.3. Expresii şi funcţii în interogări

Expresiile sunt instrumente folosite de programatori pentru a spori performanţele aplicaţiilor. Ele sunt formate dintr-o combinaţie de operatori, constante,variabile şi funcţii care au ca rezultat o numită valoare. Expresiiloe pot fi folosite îninterogări, formulare, rapoarte, proprietăţi ale câmpurilor tabelelor sau ale controalelor din formulare şi rapoarte, în funcţii macro şi module. Ele pot fi folosite pentru a stabilicriterii, ca reguli de validare sau ca bază pentru coloanele calculate. De exemplu, dacăîntr-o interogare introduceţi următoara expresie în câmpul Criteria corespunzător uneicoloane de tip Date/Time (tip folosit pentru stocarea datelor şi orelor), ea va returnanumai înregistrările mai vechi de 3 zile:

<Now () + 3.

Pag. 53

Page 49: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 49/295

3.3.1. Părţile componente ale expresiilor

Expresiile pot fi privite ca nişte propoziţii matematice, în componenţa cărora pot intra:

• operatori: simboluri matematice;•

constante: valori numerice sau şiruri de caractere ce nu îşi schimbă valoarea;• funcţii: proceduri ce returnează o valoare (de exemplu, funcţia Nowreturnează data curentă);

• nume de câmpuri: de obicei sunt introduse între paranteze drepte

OperatoriOperatorii joacă un rol important în cadrul expresiilor. Există mai multe tipuri

de operatori pe care vi le prezentăm în cele ce urmează.Operatori aritmetici

Sunt folosiţi pentru a efectua calcule matematice cu 2 sau mai multe valorinumerice.

• ^ ridică un număr la o putere (de exemplu 2^3=23)• * înmulţeşte 2 numere• / împarte 2 numere şi returnează un număr real• \ împarte 2 numere şi returnează un număr întreg

• MOD returnează restul împărţirii a 2 numere• + adună 2 numere• - scade 2 numere

Operatori de concatenare

Sunt folosiţi pentru a lega 2 şiruri de caractere.• & concatenează 2 şiruri de caractere• + adună valorile a 2 câmpuri numerice. Poate fi folosit şi pentru a

concatena şiruri de caractere.

Operatori de comparaţieSunt folosiţi pentru a compara valorile a 2 sau mai multe câmpuri şi/sau

expresii.• = verifică egalitatea a 2 valori• <> verifică dacă 2 valori sunt diferite• < verifică dacă o valoare este strict mai mică decât alta

Pag. 54

Page 50: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 50/295

• > verifică dacă o valoare este strict mai mare decât alta• <= verifică dacă o valoare este mai mică sau egală cu alta• >= verifică dacă o valoare este mai mare sau egală cu alta

Operatori logici

Efectuează operaţii logice.• Not introduce o negaţie (de exemplu, Not T* introdus într-o inte-

rogare în câmpul Criteria al coloanei Nume va regăsi toţi studenţii alecăror nume nu încep cu litera T)

• And efectuează conjuncţia a 2 valori• Or efectuează disjuncţia a 2 valori• Xor efectuează disjuncţia exclusivă a 2 valori• Eqv verifică echivalenţa a 2 valori• Imp operatorul „implică”

Precedenţa operatorilorDe multe ori, a calcula valoarea unei expresii implică efectuarea mai multor 

operaţii. Aceste operaţii se efectuează într-o anumită ordine predefinită, care este şiordinea în care au fost prezentaţi operatorii mai sus.

Dacă doriţi o schimbare în această ordine (de exemplu să efectuaţi întâi ooperaţie de adunare şi apoi o ridicare la putere) folosiţi parantezele pentru a precizacare operator va fi aplicat primul.

ConstanteConstantele sunt un fel de cuvinte rezervate, în sensul că valoarea lor nu seschimbă pe parcursul rulării aplicaţiei. Ele se împart în 3 grupe, pe care vi le prezentăm în continuare.

Constante predefiniteAcestea sunt definite de programator, de obicei în module. Declaraţia unei

constante predefinite începe cu cuvântul cheie CONST. De exemplu:CONST Pi = 3.14

După ce au fost declarate, ele pot fi folosite oriunde.

Constante intrinseceSunt constante furnizate de Visual Basic (cum ar fi VbString sau VarType) şi

nu trebuie să fie declarate separat. Programatorul nu poate defini o constantă care săaibă acelaşi nume ca o constantă intrinsecă. Constantele intrinseci se pot folosi numaiîn module.

Pag. 55

Page 51: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 51/295

Constante sistemYes, No, On, Off şi Null sunt cele 5 componente sistem. Ele pot fi folosite în

orice obiect din baza de date, mai puţin în module.

Funcţii

Funcţiile pot intra în componenţa expresiilor. Ele acţionează ca şi operatorii,dar nu sunt reprezentate prin simboluri. De exemplu, operatorul + şi funcţia Sumefectuează aceeaşi operaţie: cea de adunare. Diferenţa este aceea că funcţia Sum poatefi aplicată mai multor valori o dată. Access vă pune la dispoziţiepeste 160 de funcţii,dintre care câteva le puteţi vedea în câmpul Totals al grilei QBE a unei interogări detip Totals.

3.4. Lucrul cu date şi ore

În Access, expresiile pot conţine date sau ore. Acestea sunt stocate ca numerereale pe 64 de biţi. Intervalul maxim pentru date este 1 Ian 100 şi 31 Dec 9999, iar cel pentru ore, între 0:00:00 şi 23:59:59. După ce o dată/oră a fost introdusă într-oexpresie, Access parcurge expresia şi recunoaşte formatul respectiv, incluzând data(ora) între 2 caractere diez (#).

Access vă pune la dispoziţie aproximativ 22 de funcţii pentru lucrul cu date şiore. De exemplu, în interogarea Vechime, prezentată în figura., am folosit funcţiileYes şi Now pentru a calcula câţi ani au trecut de la angajarea unui profesor şi până în

 prezent. Funcţia Year () returnează numai anul dintr-o dată completă, iar funcţia Now() returneazădata (şi ora) curentă.Există câteva formate predefinite pentru afişarea datelor/orelor în formulare,

rapoarte, în modul Datasheet View al unei tabele sau interogări etc. tabelul vă prezintăo listă cu aceste formate, pe care o puteţi vedea şi în câmpul proprietăţii Format a uneicoloane de tip Date/Time a unei tabele (în modul Table Design).

Format Afişare (exemplu)General 01/01/98 12:00:00 AM

Short date 01/01/98Medium date 1-Jan-98Long date Thursday, January, 1, 1998Short time 00:00:00

Medium time 12:00 AMLong time 12:00:00 AM

Prin intermediul expresiilor puteţi să personalizaţi modul cum vor fi afişate

datele/orele. În tabel sunt descrise diferite formate pe care le puteţi folosi în acestscop.

Pag. 56

Page 52: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 52/295

Format Afişare (exemplu)d Ziua din lună, între 1 şi 31dd Ziua din lună, între 01 şi 31ddd Ziua săptămânii (primele 3 litere din ziua săptămânii; de

exemplu, Monday pentru luni, Tuesday pentru marţi etc)

dddd Ziua săptămânii din limba engleză (întreg cuvântul; deexemplu, Monday pentru luni, Tuesday pentru marţi etc)w Ziua săptămânii, între 1 şi 7ww Săptămâna din an, între 1 şi 52m Luna anului, între 1 şi 12mm Luna anului, între 01 şi 12mmm Primele 3 litere din luna anului în engleză (de exemplu, Jan

 pentru ianuarie, Feb pentru februarie, etc)Mmmm Luna anului în limba engleză (întreg cuvântul; de exemplu,

Jan pentru ianuarie, Feb pentru februarie, etc)q Trimestrul anului, între 1 şi 4y Ziua din an, între 1 şi 365yy Anul, între 00 şi 99yyyy Anul, între 0100 şi 9999h Ora, între 1 şi 23hh Ora, între 01 şi 23n Minutul, între 1 şi 59nn Minutul, între 01 şi 59

s Secunda, între 1 şi 59ss Secunda, între 01 şi 59AM/PM AM pentru ore între miezul nopţii şi miezul zilei; PM

 pentru ore între miezul zilei şi miezul nopţiiam/pm am pentru ore între miezul nopţii şi miezul zilei; pm pentru

ore între miezul zilei şi miezul nopţiiA/P A pentru ore între miezul nopţii şi miezul zilei; P pentru

ore între miezul zilei şi miezul nopţii

Semnul slash (/) este folosit, de obicei, ca separator pentru dată, iar două puncte (:), ca separator pentru oră.

Folosind aceste formate, puteţi crea expresii care să returneze valori de genul: Luna angajării este Feb

Pentru aceasta, introduceţi în câmpul Field al grilei QBE expresia:

Luna: “Luna angajării este “ & Format ([Data Angajării], “mmm”) , unde:

Pag. 57

Page 53: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 53/295

• Luna: este numele coloanei care va conţine, în tabela derezultate, valorile expresiei;• “Luna angajării este “ este textul care va apărea înaintea luniiangajării;• Format ([Data Angajării], “mmm”) converteşte valoarea

stocată în câmpul Data Angajării la formatul mmm.

Funcţia Now () returnează data şi ora curentă în funcţie de ceasul sistemului.O funcţie asemănătoare este Date (), care returnează doar data curentă.

 Notă: dacă observaţi că informaţiile returnate sunt eronate, verificaţi data şiora sistemului (în Control Panel, la secţiunea Date/Time), deoarece funcţiile Now () şi Date () se bazează pe acestea.

3.5. Funcţia IIF în expresii

Sintaxa funcţiei IIF este următoarea:

IIF (<Expresie>, valoare1, valoare2)

Unde:• este o expresie a cărei valoare de adevăr este evaluată pentrufiecare înregistrare în parte.;

• valoare1 este valoarea returnată dacă <expresie> esteadevărată;• valoare2 este valoarea returnată dacă <expresie> este falsă.

Astfel, să presupunem câmpul pentru fiecare student dorim să aflăm dacă a promovat sau nu oate cursuriile opţionale la care s-a înscris (adică, dacă nota minimăobţinută este sau nu mai mare sau egală cu 5). În tabela cu rezultatele interogării vomavea o coloană, numită Situaţia, care va avea valoarea “promovat” sau “Nepromovat”.Expresia care dă valorile acestei coloanea este următoarea:

Situaţia: IIf (Min ( [ Nota ] )>= 5, “promovat”, “nepromovat”

3.6. Strategii de parcurgere a tabelelor de bază

Access Jet Engine poate alege una dintre următoarele 3 strategii pentru parcurgerea datelor din tabelele de bază:

Pag. 58

Page 54: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 54/295

• Parcurgerea secvenţială: este, de obicei, cea mai puţin rapidă metodă,deoarece sunt citite toate înregistrările din tabela de bază, şi, pentru fiecareînregistrare sunt verificate restricţiile. Această metodă este aleasă pentrutabele mici şi neindexate.• Parcurgerea pe indecşi: Această metodă este aleasă atunci cînd există

restricţii asupra unei coloane indexate dintr-o tabelã de bază. După cesubnt selectate doar înregistările pentru care sunt verificate aceste restricţii,aceste înregistrări vor fi supuse şi restului de restricţii (dacă există).Această metodă este eficientă atunci când tabelele de bază sunt mari, astfelîncât, deşi se vor citi aceleaşi înregistrări de mai multe ori, timpul total estemai mic decât cel necesar pentru a citi întraga tabelă.• Tehnica restricţionării Rushmore: este aplicată atunci când existărestricţii asupra mai multor coloane indexate. Prin folosirea mai multor indecşi, motorul Jet reduce considerabil numărul de înregistrări ce trebuie

citite. În funcţie de tipul restricţiei, Jet engine va efectua una dintreurmătoarele 3 operaţii:• intersecţia indecşilor: pentru restricţii de forma:unde col1 şi col2 sunt coloane indexate. Pentru fiecarerestricţie este creată câte o mulţime de rezultate, care apoisunt intersectate pentru a găsi înregistrările ce verificăambele restricţii.• reuniunea indecşilor: pentru restricţii de forma:• col1 = <exp> OR col2 = <exp>•

unde col1 şi col2 sunt coloane indexate. Pentru fiecarerestricţie este creată câte o mulţime de rezultate, care apoisunt reunite pentru a găsi înregistrările ce verifică ceverifică cel puţin una dintre cele 2 restricţii.• numărarea indecşilor: pentru interogări ce returneazănumărul înregistrprilor ce verifică o anumită mulţime derestricţii:• SELECT Count (*) FROM Tabela• WHERE col1 = <exp> AND col2 = <exp>

• Pentru astfel de interogări, Jet Engine nu trebuie decâtsă citească paginile cu indecşi.

3.7. Greşeli frecvente

În continuare, vă prezentăm câteva dintre greşelile cel mai des întâlnite lacrearea interogărilor şi care pot duce la mărirea semnificativă a timpului de execuţie.

• Expresii în coloanele rezultat: motorul Jet Engine nu poate optimizainterogările care conţin expresii de tip IIF pentru coloanele rezultat.

Pag. 59

Page 55: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 55/295

Folosiţi expresiile la nivelul controalelor din rapoartele sau formularelecare vor folosi rezultatele interogării.• Prea multe coloane cu clauza GROUP BY: când creaţi o interogarede tip Totals, impuneţi clauza Group By asupra cât mai puţinor coloane.Astfel, timpul de execuţie va fi mai redus.•

Indexarea coloanei de asociere pentru o singură tabelă: cândfolosiţi o asociere între 2 tabele, indexaţi c-mpurile de asociere din ambeletabele.• Folosirea insuficientă a indecşilor: dacă nu se efectuează modificărifrecvente asupra datelor, este bine să folosiţi indecşi pentru coloanele deasociere sau pentru coloanele asupra cărora se impun restricţii. Altfel,indecşii pot îngreuna sensibil operaţiile de actualizare a datelor.

3.8. Importanţa compactării

Compactarea unei baze de date este o operaţie asemănătoare defragmentăriidiscurilor fizice. Pe măsură ce ştergeţi obiecte sau înregistrări din baza de date, vor rămâne spaţii nefolosite care măresc dimensiunile fişierului şi scad performanţeleacţiunilor. Singurul mod în care pot fi eliminate aceste spaţii este comanda DatabaseUtilities | Compact Database. Astfel, vor fi reînoite statisticile asupra tabelelor, vor fireordonate înregistrările din tabele, iar spaţiul liber va putea fi folosit. În consecinţă,vor creşte şi performanţele interogărilor, despre care am mai spus că sunt cel maiimportant instrument pus la dispoziţia programatorilor şi fără de care bazele de date

nu şi-ar mai afla utilitatea.

Pag. 60

Page 56: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 56/295

CAP: 4. Crearea şi lucrul cu formulareleFormularele oferă unei baze de date o interfaţă prietenoasă şi elegantă, prin

care programatorul poate controla acţiunile utilizatorului. Un formular are peste 70 de

 proprietăţi, la care se adaugă cele ale controalelor, între 38 şi 58 pentru fiecare.Principalul rol al formularelor este introducerea datelor, dar ele pot folosi şi laregăsirea datelor sau afişarea meniurilor, a ecranelor de tip splash etc.

Sursele de înregistrări ale formularelor indică de unde provin sau unde vor fistocate datele şi sunt specificate printre proprietăţile formularelor.

Pentru a vedea pagina de proprietăţi a unui formular deschis în modul DesignView, faceţi clic pe butonul selector care se află în colţul din stânga-sus alformularului şi apoi selectaţi comanda View Properties sau apăsaţi butonulProperties pe bara cu instrumente.

 Notă: Pentru a vedea pagina de proprietăţi a unui control al formularului, faceţi clic pe el pentru a-l aduce în prim plan şi apoi alegeţi comanda View Properties sauapăsaţi butonul Properties de pe bara cu instrumente.

4.1 Sursele de înregistrări ale formularelor

Sursa de înregistrări a unui formular poate fi o tabelă, o interogare sau oinstrucţiune SQL, specificată în proprietatea Record Source a formularului respectiv.

Figura 4.1.

În figura 4.1 observaţi că în dreapta câmpului proprietăţii Record Source se

află două mici butoane. Dacă faceţi clic pe primul (cel reprezentat de o săgeată), se vadeschide o listă cu toate tabelele şi interogările din baza de date curentă, dintre

Pag. 61

Page 57: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 57/295

care veţi selecta sursa de înregistrări. Pentru a modifica sursa de date a unui formular apăsaţi cel de al doilea buton din dreptul proprietăţii Record Source (cel reprezentat prin trei puncte…) care va deschide fereastra SQL Ouery Builder (figura 4.2). Aceastase aseamănă cu fereastra QBE atât ca aspect, cât şi ca funcţionare.

Figura IV.2.

Dacă formularul se bazează pe o interogare, modificările aduse acesteia înfereastra SQL Builder se vor reflecta şi în interogarea propriu-zisă.

După cum am arătat în capitolele precedente, există două tipuri de interogări: pentru regăsirea datelor şi pentru definirea şi modificarea datelor. Dintre acestea,numai interogările pentru regăsirea datelor (de tip SELECT) pot servi drept sursă deînregistrări pentru un formular.

Dacă vă întrebaţi ce să alegeţi ca sursă de date pentru un formular dintre ointerogare salvată şi o instrucţiune SQL, răspunsul este următorul: dacă interogareaeste complexă, salvaţi-o şi apoi alegeţi-o în câmpul proprietăţii Record Source; dacăeste simplă, introduceţi instrucţiunea SQL corespunzătoare direct în câmpul proprietăţii Record Source a formularului. Formularele bazate pe interogări salvate

sunt mai rapide, dar aceste interogări sporesc numărul de obiecte din baza de date,făcând-o să ocupe mai mult spaţiu.

4.2. Crearea unui formular simplu

Access vă pune la dispoziţie două componente pentru crearea formularelor simple: AutoForm Wizard, pentru crearea automată a formularelor şi Form Wizard, ceîi dă programatourlui mai multă libertate de decizie. Pe lângă acestea, puteţi crea

formulare şi singuri, pornind de la zero, în modul Design View.Formularele create automat cu ajutorul vrăjitorului AutoForm wizard, conţincâte un control (câmp) pentru fiecare coloană a tabelei sau a interogării pe care

Pag. 62

Page 58: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 58/295

sunt bazate. În partea dreaptă a fiecărui câmp există o denumire (etichetă) care estedată de valoarea prorietăţii Label a coloanei respective. Controlul corespunzător uneicoloane este cel specificat în proprietatea Display Control a coloanei respective şi poate fi Text Box, Combo Box, List Box sau Check Box, în funcţi de tipul de date.

Figura 4.3. prezintă formularul DetaliiProfesor, creat automat şi care se bazează pe interogarea DetaliiProf din figura 4.2.

Figura IV.3.

Puteţi alge tiparul, adică fundalul implicit şi fontul şi culoarea implicită aetichetelor folosite de AutoForm Wizard la crearea automată a formularelor. Pentruaceasta, deschideţi formularul în modul Design View, efectuaţi modificările dorite şialegeţi comanda AutoFormat.

Spre deosebire de vrăjitorii pentru crearea automată a formularelor (AutoFormColumnar Wizard, AutoForm Tabular Wizard şi AutoForm Datasheet Wizard, carediferă prin modul în care sunt prezentate datele în formular), vrăjitorii de tip FormWizard (Form Wizard, Chart Wizard şi Pivot Table Wizard) îi dau programatorului posibilitatea de a specifica tabelel sau interogările pe care se va baza formularul,câmpurile acestora care vor apărea pe formular, ordinea de sortare a datelor, fundaluletc. Notă: Dacă folosiţi mai multe tabele şi interogări ca sursă de înregistrări pentru un formular, între acestea trebuie să fie stabilite relaţii.

Apăsând butonul „Create form by using wizard” din pagina Forms a ferestreiDatabase Container, se va deschide fereastra de dialog (figura 4.4), în care veţi alegevrăjitorul care vreţi să vă ajute la crearea unui nou formular.

Pag. 63

Page 59: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 59/295

Figura 4.4.După ce aţi ales opţiunea Form Wizard, acest vrăjitor vă va prezenta succesiv

 patru cutii de dialog, în care veţi putea alege câmpurile dorite din una sau mai multetabele sau interogări din baza de date (între care trebuie să existe relaţii), modul cumvor fi prezentate datele (pe o singură coloană (Columnar), sub formă de tabel(Tabular), ca în modul Datasheet View (Datasheet) sau aliniate atât la stânga cât şi ladreapta formularului (Justified)), fundalul şi, în final, numele formularului.

Dacă doriţi să creaţiun formular pornind de la zero, fără nici un ajutor, în cutiade dialog New Form alegeţi opţiunea „Create Form in Design View”. Astfel, se vadeschide un formular fără nici un control, urmând ca dumneavoastră să adăugaţicontroalele dorite, folosind cutia de instrumente (Toolbox).

4.3. Secţiunile unui formular

Un formular Access poate avea între una şi cinci secţiuni. Iată care suntacestea (prezentate şi în figura 4.5):

Pag. 64

Page 60: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 60/295

Figura IV.5

• Detail – Această secţiune conţine datele din fiecare înregistrare a sursei de date.Pentru a trece de la o înregistrare la alta veţi folosi butoanele de navigare aleformularului.

• Form Header – Această secţiune apare întotdeauna în partea de sus aformularului. Aici puteţi include informaţii care nu se schimbă în funcţie defiecare înregistrare, cum ar fi un antet sau un control ce nu are legătură cuînregistrarea curentă, precum şi o casetă combinată folosită pentru filtrareaînregistrărilor.

• Form Footer - Această secţiune apare în partea de jos a unui formular. Aici puteţiinclude informaţii despre data şi ora la care a fost creat formularul sau totalurilecoloanelor unui formular tabelar.

• Page Header – Această secţiune apare între Form Header şi Detail. Formularelecare conţin un număr mare de controale pot fi împărţite cu ajutorul unui control detip Page Break în două sau mai multe pagini, pentru a fi afişate pe rând. SecţiunilePage Header şi Page Footer vor rămâne nemodificate când se trece de la o paginăla alta a formularului.

• Page Footer – Această secţiune apare între Detail şi Form Footer şi se aseamănă

cu secţiunea Page Header.

Pag. 65

Page 61: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 61/295

4.4. Lucrul cu formularele

Un formular o dată creat poate fi deschis în mai multe feluri: din pagina Formsa ferestrei Database Container, din alt formular (cu ajutorul unui buton), dintr-unmacro sau cu ajutorul limbajului VBA.

Principalul rol al formularelor este acela de a împiedeca utilizatorul săinteracţioneze direct cu tabelele sau cu tabelele de rezultate ale interogărilor din bazade date. De aceea, pentru a reduce cât mai mult contactul utilizatorului cu fereastraDatabase Container şi cu obiectele sale, cel mai elegant mod de a deschide unformular este prin intermediul unui buton din alt formular. Astfel, un exemplu clasicde formular folosit pentru a lansa alte formulare este acela al unui meniu ce conţinemai multe butoane, prin intermediul cărora utilizatorul putea deschide diferite alteformulare.

Indiferent de cum a fost deschis un formular, veţi putea face trecerea la oricare

dintre cele trei moduri în care poate fi văzut formularul: Design View (pentru a lucracu controalele formularului), Datasheet View (pentru a avea acces numei la datele pecare se bazează formularul) sau Form View (pentru a vedea formularul în forma safinală), alegând una dintre aceste comenzi din meniul View.

Într-un formular puteţi naviga atât între controale, cât şi între înregistrări. Cuajutorul tastei Tab puteţi trece de la un control la altul. Pentru a stabili ordinea în carese face această trecere, alegeţi comanda View Tab Order.

Pentru a trece la înregistrarea următoare, treceţi la ultimul control de peformular şi apoi apăsaţi tasta Enter. Un alt mod de a trece de la o înregistrare la lata

este prin folosirea tastelor  Page Up şi Page Down. Mult mai simplu este însă săfolosiţi butoanele pentru navigarea printre înregistrări. Aceste butoane apar în

colţul din stânga jos al unui formular, dacă în pagina de proprietăţi a acestuia proprietatea Navigation Buttons are valoarea Yes.

Tot în pagina de proprietăţi a unui formular veţi găsi şase proprietăţi ce vă  permit să controlaţi acţiunile utilizatorului asupra datelor pe care se bazeazăformularul:

• Allows Edits: Dacă are valoarea Yes, utilizatorul va putea modificaînregistrările; dacă are valoarea No, aceasta nu va putea schimba în nici unfel datela afişate în formular.• Allow Deletions: Dacă are valoarea Yes, utilizatorul va putea ştergeînregistrări, cu condiţia ca integritatea referenţială să nu fie violată.• Allow Additions: Dacă are valoarea Yes, utilizatorul va puteaintroduce noi înregistrări prin intermediul formularului.• Data Entry: dacă are valoarea Yes, formularul deschide automat oînegistrare nouă, fără date. Utilizatorul nu are acces la înregistrărileexistente. Dacă proprietatea Alow Additions are valoare No, iar Data Entryare valoarea Yes, va rezulta o eroare.

Pag. 66

Page 62: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 62/295

• Recordset Type: Poate fi Dynaset, Dynaset (Inconsistent Updates) sauSnapshot. Se referă la formularele ce au mai multe tabele ca sursă de date.Dacă valoarea este Dynaset, datele din controalele asociate câmpurilor vor  putea fi editate de către utilizator, ceea ce nu este valabil în cazul valoriiSnapshot.•

Record Locks: Se referă la aplicaţii multiuser. Dacă are valoarea NoLocks, mai mulţi utilizatori vor putea modifica aceleaşi înregistrări înacelaşi timp, fiind luate în considerare numai modificările care au fostsalvate primele. Opţiunea Edited Records împiedică ceilalţi utilizatori de aopera schimbări asupra unei înregistrări care este deja în curs demodificare. Opţiunea All Records blochează toate înregistrările dinformular şi din tabelele de bază atâta timp cât un utilizator editează oriceînregistrare din tabelă.

O dată ce au fost făcute modificări asupra unei înregistrări dintr-un formular,

acestea vor fi salvate fie când se trece la înregistrarea următoare, fie când se închideformularul.Proprietăţile din pagina Format a ferestrei de proprietăţi a formularului

controlează aspectul acestuia. Printre ele se numără:• Caption: Păstrează textul ce va fi afişat în bara de titlu a formularului.• Default View: Stabileşte dacă formularul va fi afişat în modul SingleForm (cel mai des folosit), Continuos Form sau Datasheet.• Views Allowed: Stabileşte dacă utilizatorul poate trece din modulForm View în modul Datsheet View.•

ScrollBars: Stabileşte dacă formularul are bare de derulare verticaleşi/sau orizontale.• RecordSelectors: Dacă valoarea sa este Yes, pe latura din stânga asecţiunii Detail va apărea un selector pentru înregistrări.• NavigationButtons: Dacă valoarea este Yes, formularul va fi dotat cu butoane pentru parcurgerea înregistrărilor.

• RecordDividers: Dacă valoarea este Yes, în modul Continuos vaapărea o linie de separare între înregistrări.• AutoResize: Dacă valoarea este Yes, fereatra formularului va fidimensionată corespunzător la fiecare deschidere a acestuia.• AutoCenter: Dacă valoarea este Yes, la deschidere formularul vaapărea centrat pe ecran.• ControlBox: Dacă valoarea este Yes, caseta de control va apărea în partea din stânga a barei de titlu.• MaxMinButtons: Precizează dacă butoanele Minimize şi Maximizevor fi incluse în bara de titlu. În acest caz, valoarea proprietăţiiWhatsThisButton trebuie să fie No.• CloseButton: Dacă valoarea este Yes, butonul (X) pentru închidereaformularului va fi inclus în partea dreaptă a barei de titlu.

Pag. 67

Page 63: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 63/295

• WhatsThisButton: Dacă valoarea este Yes, butonul (?) va apărea în partea din dreapta a barei de titlu în cazul în care şi CloseButton arevaloarea Yes.

Pe lângă acestea, ar fi mai interesant să menţionăm două dintre cele maiimportante proprietăţi din pagina Other a ferestrei Properties:

Pop Up: Dacă valoarea sa este Yes, formularul va fi afişat deasupraaltor ferestre, putând fi mutat şi în afara ferestrei Access.• Modal: Dacă valoarea sa este Yes, alte ferestre deschise nu pot primicontrolul până când formularul nu este închis.

4.5. Despre controale

Fiecare element de pe un formular este un control de un anumit tip. Puteţi

adăuga controale la un formular deschis în modul Design View folosind cutia deinstrumente Toolbox, pe care o puteţi vedea alegând comanda View Toolbox sauapăsând butonul Toolbox de pe bara de instrumente. Majoritatea butoanelor dinToolbox reprezintă un tip de control ce poate fi plasat pe un formular. Figura V.6 prezintă cutia de instrumente Toolbox şi descrie componentele sale.

Pentru a plasa un control din Toolbox pe un formular, faceţi clic pe butonulcorespunzător tipului de control dorit, după care faceţi clic pe formular. O datăadăugat, controlul poate fi redimensionat în funcţie de necesităţi. Puteţi selecta uncontrol sau un grup de controale cu ajutorul săgeţii din cutia cu scule. Alegeţi săgeata

şi apoi trasaţi un dreptunghi în jurul controalelor pe care doriţi să le selectaţi. O altămetodă ar fi să ţineţi tasta Shift apăsată în timp ce faceţi clic pe controalele respective.Pentru a stabili proprietăţile şi comportamentul unui control, Access vă pune

la dispoziţie vrăjitorul control Wizard, care va fi activat atunci când controlul este plasat pe formular, dacă butonul Control Wizard din cutia de scule este apăsat (ca înfigura 4.6).

Pag. 68

Page 64: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 64/295

Figura IV.6

4.5.1. Tipuri de controaleExistă trei tipuri de controale ce pot fi plasate pe un formular: ataşate,

neataşate şi calculate.Controale neataşateUn control este folosit pentru a furniza sau primi de la utilizator informaţii ce

nu sunt sau nu vor fi stocate în baza de date. Iată câteva exemple de astfel decontroale:

• O etichetă ce descrie alt control;• Un buton prin care se deschide un alt formular;• Un bitmap ce face formularul mai atractiv etc.

Controale ataşateControalele ataşate sunt folosite pentru a afişa sau edita informaţii din baza de

date şi lor le corespunde câte un câmp dintr-o tabelă sau un câmp returnat de ointerogare sau instrucţiune SQL. Orice control poate fi ataşat, cu excepţia dreptelor,dreptunghiurilor, sfârşitului de pagină, etichetelor şi cadrelor pentru imagini.

Un control ataşat va moşteni multe dintre proprietăţile câmpului corespunzător (cum ar fi Caption, Description, Input Mask, Format), dar aceste proprietăţi pot fimodificate prin intermediul paginii de proprietăţi a controlului.

Pentru a plasa un control ataşat pe un formular procedaţi astfel:1. Alegeţi comanda View Field List pentru a afişa câmpurile sursei de date pe

care se bazează formularul.2. Selectaţi un câmp sau un grup de câmpuri din această listă.3. Faceţi drag & drop cu selecţia pe formular. Astfel, pentru fiecare câmp selectat

va apărea pe formular un control şi o etichetă ce va afişa textul din proprietatea

Caption a câmpului corespunzător.Puteţi transforma un control neataşat într-unul ataşat folosind proprietateaControl Source a controlului respectiv, în care să specificaţi câmpul corespunzător.

Pag. 69

Page 65: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 65/295

Controale calculateControalele calculate folosesc expresii pentru a-şi obţine datele. Deşi casetele

text sunt cel mai frecvent întâlnite controale de acest tip, orice alt fel de control ce are proprietatea Control Source poate fi calculat. Orice expresie trebuie să înceapă cu

semnul egal (=). De exemplu, dacă în formularul DetaliiProfesor dorim să avem uncâmp ce calculează impozitul din salariul afişat în controlul Salariu, expresia folosităva fi:

=[Salariu]*0.12Această expresie poate fi introdusă direct în control dacă acesta este o casetă

text sau în câmpul proprietăţii Control Source a controlului.

4.5.2. Casete combinate, casete listă şi grupuri de opţiuniÎn continuare, vă vom arăta cum puteţi să profitaţi de ajutorul oferit de

vrăjitorul Control Wizard pentru lucrul cu controalele de tip casetă combinată, casetălistă şi grup de opţiuni. Dacă butonul Control Wizard din cutia de instrumente esteapăsat, prin plasarea pe formular a unui control de tipul celor enumerate anterior, seva activa vrăjitorul corespunzător (Combo Box Wizard, List Box Wizard sau OptionGroup Wizard).

Vrăjitorii pentru casete combinate şi casete listă sunt foarte asemănători cuvrăjitorul Lookup Wizard, care vă ajută să creaţi într-o tabelă o coloană ale căreivalori proveaneau din altă tabelă sau dintr-o listă specificată de dumneavoastră.

Pentru a ilustra lucrul cu ei, ne vom întoarce la formularul DetaliiProf care

trebuie să fie deschis în modul Design View. Să presupunem că în locul casetei textTitlu vom introduce o casetă combinată din care utilizatorul să poată alege una dintrevalorile din coloana Titlu a tabelei cu acelaşi nume. Ştergeţi aşadar controlul Titlu de pe formular (faceţi clic pe el pentru a-l selecta şi apoi apăsaţi tasta Del) şi adăugaţi uncontrol de tip Combo Box. În prima cutie de dialog a vrăjitorului Combo Box Wizardalegeţi prima opţiune, prin care specificaţi că valorile controlului vor proveni dintr-otabelă sau interogare. În a doua cutie de dialog va trebui să alegeţi tabela sauinterogarea respectivă, în speţă, tabela Titlu. În cea de-a treia cutie de dialog veţi alegecâmpurile din tabela Titlu ce vor da valorile din caseta combinată. Deoarece în listădorim să fie afişate titlurile din coloana Titli, dar în tabela Profesor se vor stoca doar identificatorii din coloana IdTitlu, aici vom selecta atât coloana Titlu, cât şi IdTitlu. Încea de-a patra cutie de dialog veţi ajusta, eventual, lăţimea listei şi veţi lăsa validatăcaseta Key Column, deoarece nu doriţi ca în listă să apară şi valorile coloanei IdTitlu.Cea de-a cincea cutie de dialog vă întreabă dacă valorile selectate în caseta combinatăvor fi memorate pentru a fi folosite ulterior sau vor fi stocate în baza de date. Alegeţi adoua opţiune şi specificaţi că valorile vor fi stocate în coloana IdTitlu. Ultima cutie dedialog vă lasă să introduceţi textul etichetei plasat în dreptul casetei combinate. Scrieţi“Titlu” şi apăsaţi butonul Finish pentru a închide vrăjitorul şi a crea controlul. Treceţiapoi în modul Form View şi testaţi formularul (figura 4.7).

Pag. 70

Page 66: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 66/295

Figura IV.7

Să privim pagina de proprietăţi a casetei combinate Titlu pentru a înţelege cea făcut Combo Box Wizard (figura 4.8). În câmpul proprietăţii Row Source Typeeste selectată valoarea Table / Query, deoarece valorile din lista casetei combinate provin dintr-o tabelă, interogare sau instrucţiune SQL. Proprietatea Row Sourcespecifică această instrucţiune:

SELECT DINCTINCROW [Titlu].[IdTiltu], [Titlu].[Titlu] FROM [Titlu];

Proprietatea Control Source specifică exact coloana din care provin datele dincaseta combinată: IdTitlu. Atunci când veţi dori să introduceţi în tabela Profesor datedespre un nou profesor prin intermediul acestui formular, în coloana IdTitlu a tabeleiProfesor va fi stocată valoarea lui IdTitlu din tabela Titlu, în funcţie de alegereadumneavoastră din caseta combinată.

Figura IV.8

Pag. 71

Page 67: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 67/295

În continuare, vom adăuga formularului DetaliiProf un grup de opţiuni cuajutorul vrăjitorului Option Group Wizard. Pentru aceasta, va trebui să adăugăm onouă coloană la tabela Profesor şi anume Statut, de tip Number (FieldSize=Integer) şicare va avea valoarea 1 dacă profesorul este titular sau 0 dacă este suplinitor.

De asemenea, va trebui să modificăm şi sursa de date a formularului (interogareaDetaliiProf) astfel încât ea să conţină şi această coloană.

Deschideţi din nou formularul DetaliiProf în modul DesignView şi, din cutiade instrumente selectaţi controlul de tip grup de opţiuni. Dacă butonul ControlWizard din cutia de instrumente este apăsat, când veţi plasa controlul pe formular, seva activa vrăjitorul Option Group Wizard. În prima cutie de dialog a vrăjitorului veţispecifica etichetele fiecărui buton de opţiune: “Titular” şi “Suplinitor”. Înurmătoarea cutie de dialog veţi alege care dintre cele două opţiuni să fie implicită:

alegeţi opţiunea Titular. În cea de-a treia cutie de dialog veţi introduce valorilecorespunzătoare opţiunilor, valori ce vor fi stocate în tabelă: 1 pentru Titular şi 0 pantru Suplinitor. Următoarea cutie de dialog ne cere să specificăm dacă valorile vor fi stocate într-o tabelă, şi dacă da, în ce câmpuri. Alegeţi aici coloana Statut şi apăsaţiNext. Următoarea cutie de dialog ne propune diferite tipuri de controale ce pot apăreaîntr-un grup de opţiuni. Selectându-le, le veţi putea vedea în partea stângă a cutiei dedialog. Acceptaţi, de exemplu, varianta implicită şi treceţi la ultima cutie de dialog încare va trebui să introduceţi denumirea grupului de opţiuni (să-i spunem “Statutul”).Pentru a vedea funcţionarea grupului de opţiuni treceţi în modul Form View şi testaţi

formularul. El va arăta ca în figura 4.9.Pentru ca la introducerea datelor să nu poată apărea neconcordanţe între casetacombinată Titlu şi câmpul IdTitlu al formularului, daţi proprietăţii Locked a caseteitext IdTitlu valoarea Yes, astfel încât valorile sale să nu poată fi modificate direct decătre utilizator.

Figura IV.9

Să vedem acum ce a făcut Option Group Wizard. Observaţi că grupul conţinedouă butoane de opţiune, ale căror etichete sunt “Titular” şi “Suplinitor”. Din pagina

Pag. 72

Page 68: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 68/295

de proprietăţi a grupului de opţiuni (figura IV.10), merită să remarcăm valoarea  proprietăţii Control Source, şi anume coloana Statut. De asemenea, proprietateaDefault Value are valoarea 1, corespunzătoare opţiunii Titular (aşa cum amspecificat în cea de-a doua cutie de dialog a vrăjitorului). Din pagina de proprietăţi a primului buton de opţiune, Titlu, remarcăm doar că valoarea 1 pe care o specificasem

în cea de-a treia cutie de dialog a vrăjitorului se regăseşte în valoarea proprietăţiiOption Value. Analog, valoarea 0 corespunzătoare opţiunii

Suplinitor se regăseşte în valoarea proprietăţii Option Value a celui de-al doilea butonde opţiune.

Figura IV.10

 4.6. Subformulare

Atunci când avem două tabele între care există o relaţie de tip 1:m, poate fiavantajos să putem lucra cu amândouă prin intermediul unui singur formular. Deexemplu, tabelele Profesor şi Titlu sunt legate printr-o astfel de relaţie, coloana delegătură fiind IdTitlu. Ar fi interesant ca, atunci când obţinem informaţii despre titlulde lector, să putem vedea şi toţi profesorii care au acest titlu.

Pentru aceasta, vom crea un formular ce va conţine un subformular.Formularul părinte va lucra cu datele din tabela aflată în partea (1) a relaţiei, iar subformularul, cu cele ale tabelei din partea (m). Access recunoaşte faptul că întrecele două tabele este definită o relaţie şi, pentru o anumită înregistrare din tabela Titlu,limitează înregistrările din subformular la cele pentru care valorile câmpului delegătură din cele două tabele sunt egale.

Puteţi avea maximum două niveluri de imbricare a subformularelor şi oricâtesubformulare pe acelaşi nivel de imbricare. Access 97 vă pune la dispoziţie uninstrument foarte prietenos pentru crearea de formulare cu subformulare: Form

Wizard. Paşii pe care trebuie să-i parcurgeţi pentru aceasta sunt următorii:1. În pagina Forms a ferestrei Database alegeţi butonul New şi apoi, din cutia

de dialog New Forms, alegeţi Form Wizard.Pag. 73

Page 69: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 69/295

2. În prima cutie de dialog a Vrăjitorului, selectaţi din caseta combinatăTables/Queries tabela Profesor şi apoi, din lista Available Fields alegeţicoloanele Nume, Catedra şi Data Angajării. Selectaţi apoi din casetacombinată rabela Titlu şi coloanele Titlu şi Salariu.

3. Pe baza datelor pe care le-aţi selectat, Access îşi dă seama că doriţi să

creaţi un formular bazat pe două tabele între care există o relaţie de tip1:mşi vă pune la dispoziţie trei moduri de a vizualiza aceste date. Dacă în ceade-a doua cutie de dialog din Wizard alegeţi ca datele să fie prezentate înfuncţie de tabela Profesor, atunci formularul va fi de tip Single Form,adică datele din cele două tabele vor fi afişate într-un

singur formular. Dacă alegeţi ca datele să fie prezentate în funcţie detabela Titlu, atunci puteţi opta între 2 posibilităţi: Linked Forms(formulare legate) (în acest caz vor fi create două formulare separate,

cel care se bazează pe tabela din partea (1) a relaţiei având un buton, pecare dacă apăsaţi se va deschide formularul bazat pe tabela din partea (m)a relaţiei) şi Form with subform(s) (formular cu subformulare). Alegeţiaceastă ultimă posibilitate.

4. Următoarele cutii de dialog din Wizard se ocupă cu caracteristicile graficeale formularului.

Pentru a înţelege legătura dintre formularul părinte şi subformular, să le privimîn modul Design View. Observaţi,că formularul părinte, Titlu_Profesori are, în plus

faţă de casetele text Titlu şi Salariu şi etichete corespunzătoare acestora, un control detip Subform/Subreport. Legătura între cele două formulare se face prin intermediul adouă proprietăţi ale controlului de tip Subform/Subreport: Link Child Fields şi Link Master Fields care specifică numele coloanelor de legătură ce formează cheia străinăîn tabela din partea (m) şi, respectiv, ale coloanelor ce formează cheia primară atabelei din partea (1) a relaţiei. Mai observaţi faptul că proprietatea Source Object areca valoare numele subformularului (Profesori Subform).

Un subformular poate fi adăugat unui formular părinte şi fără ajutorul lui FormWizard. Nu trebuie decât să trageţi numele subformularului din pagina Forms aferestrei Database Container peste formularul principal deschis în modul Design Viewşi apoi să stabiliţi proprietăţile Link Child Fields şi Link Master Fileds ale controluluide tip Subform/Subreport care va conţine subformularul. Altă metodă ar fi să selectaţidin cutia de instrumente un control de tip Subform/Subreport şi să-i stabiliţi în modcorespunzător proprietăţile Link Child Fields, Link Master Fileds şi Source Object.

Pag. 74

Page 70: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 70/295

CAP: 5. Modelul orientat pe evenimenteMicrosoft Access vă permite dezvoltarea de aplicaţii orientate pe evenimente.

Un astfel de eveniment este o acţiune pe care aplicaţia o recunoaşte (cum ar fiapăsarea unei taste, efectuarea unui clic cu mouse-ul, deschiderea unui formular sauraport etc.) şi care generează un anumit răspuns. Răspunsul poate fi executarea uneimacrocomenzi, a unei proceduri VBA sau evaluarea unei expresii. Evenimentele suntdeclanşate de acţiunile utilizatorului. Obiectele supuse evenimentelor suntformularele, rapoartele şi controalele acestora. Astfel, aplicaţiile Access trebuie să fie

 proiectate în aşa fel încât să răspundă evenimentelor declanşate de utilizator.Pentru a răspunde unui anumit eveniment, trebuie să îi atribuiţi omacrocomandă, o procedură sau o expresie. Acest lucru îl puteţi face în pagina Eventa ferestrei Properties a obiectului respectiv (figura 5.1).

Ordinea în care se execută codul aplicaţiei este astfel determinată de ordinea încare sunt invocate evenimentele prin acţiunile utilizatorului. Aceasta este esenţa programării orientate pe evenimente: utilizatorul este cel care efectuează anumiteacţiuni, iar aplicaţia răspunde în consecinţă, prin intermediul codului scris de programator. La acest lucru trebuie să vă gândiţi mereu atunci când creaţi o aplicaţieAccess (sau o aplicaţie Windows în general). Cu alte cuvinte, programatorul trebuie săfacă o serie de presupuneri pentru a determina comportamentul aplicaţiei. Spreexemplu, puteţi presupune că utilizatorul va trebui să introducă o valoare într-o casetăde text înainte de a putea să apese pe un buton. Pentru aceasta, va trebui să dezactivaţi butonul respectiv înainte ca utilizatorul să introducă o valoare în caseta de text.

Pag. 75

Page 71: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 71/295

Fig. 5.1

5.1. Tipuri de evenimente în Access

Access îi pune programatorului la dispoziţie mai multe tipuri de evenimente ce pot fideclanşate de acţiunile utilizatorului şi tratate de aplicaţie. În cele ce urmează, vomvorbi despre evenimentele cel mai des întâlnite.

5.1.1. Evenimente generate de accesarea datelorAceste evenimente au loc ori de câte ori utilizatorul adaugă, modifică sau

şterge datele dintr-un formular ori control sau când trece de la o înregistrare la alta.• Current – Are loc la deschiderea unui formular sau când se trece de lao înregistrare la alta.• Delete – Are loc atunci când utilizatorul efectuează o operaţie deştergere a datelor, înainte ca datele să fie efectiv şterse. Procedura pentrutratarea acestui eveniment are un parametru: Cancel care, dacă arevaloarea True, ştergerea nu va fi efectuată, iar dacă are valoarea False, vor avea loc următoarele evenimente, în ordine: Delete, Current (pentruaccesarea înregistrării următoare), BeforeDelConfirm, afişarea uneicasete de mesaj pentru confirmarea ştergerii, AfterDelConfirm.• BeforeDelConfirm – Are loc după ce utilizatorul a şters una sau maimulte înregistrări şi înainte ca sistemul să afişeze caseta de mesaj pentruconfirmare. Procedura pentru tratarea acestui eveniment are doi parametri:Cancel şi Response. Dacă parametrul Cancel are valoarea True,înregistrările nu vor mai fi şterse şi caseta de mesaj nu va mai apărea. Dacăel are valoarea False, iar parametrul Response are valoarea 0, ştergerea va

Pag. 76

Page 72: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 72/295

fi efectuată fără a mai apărea caseta de mesaj, iar dacă Response arevaloarea 1, caseta de mesaj va apărea.• AfterDelConfirm – Are loc după confirmarea şi/sau ştergereaînregistrărilor. Procedura pentru tratarea acestui eveniment are unargument, Status, care poate avea valorile 0,1 sau 2. Valoarea 0 spune că

ştergerea a fost efectuată cu succes, 1 că Access a anulat-o şi 2 căutilizatorul a anulat-o.• BeforeInsert – Are loc numai atunci când utilizatorul introduce primulcaracter al unei înregistrări noi, dar înainte ca înregistrarea să fie inseratăîn tabelă. Procedura pentru tratarea acestui eveniment are un argument,Cancel, care, dacă are valoarea True, acţiunea de inserare va fiabandonată.• AfterInsert – Are loc după inserarea unei înregistrări noi într-o tabelă.• BeforeUpdate – Apare înainte ca datele dintr-un control sau dintr-o

înregistrare să fie modificate efectiv. Procedura pentru tratarea acestuieveniment are un argument, Cancel, care, dacă are valoarea True,modificarea nu se va mai efectua.• AfterUpdate – Are loc după ce au fost modificate datele dintr-uncontrol sau dintr-o înregistrare. Controalele ataşate au o anumită proprietate, Old Value, care păstrează valoarea controlului dinainteamodificării până după ce acest eveniment a avut loc. Astfel, aveţi posibilitatea ca în

 procedura pentru tratarea acestui eveniment să redaţi controlului vecheavaloare astfel:

FORMS!formular!control = FORMS!formular!control.OldValue

• Change – Apare atunci când se efectuează o modificare într-o casetăde text sau în câmpul de editare al unei casete combinate.• NotInList – Este un eveniment specific casetelor combinate şi poateapărea numai dacă proprietatea LimitToList a unui astfel de control arevaloarea Yes. Astfel, evenimentul are loc dacă utilizatorul introduce încâmpul de editare al casetei combinate o valoare care nu se regăseşte înlista acestuia. Procedura pentru tratarea acestui eveniment are douăargumente: NewData, care păstrează valoarea nou introdusă de utilizator şi Response, care poate avea valorile 0,1 sau 2. Valoarea 0 îi indică luiAccess să afişeze un mesaj standard pentru a înştiinţa utilizatorul că aintrodus o valoare care nu se află în lista casetei combinate, 1 îi indică luiAccess să nu afişeze masajul standard şi nici să nu introducă noua valoareîn listă (dându-vă posibilitatea de a afişa un mesaj propriu), iar valoarea 2îi indică lui Access să nu afişeze mesajul standard şi să introducă nouavaloare în listă. În acest ultim caz, va trebui să introduceţi noua valoare şiîn sursa de date a casetei combinate.

Pag. 77

Page 73: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 73/295

• Updated – Are loc atunci când au fost modificate datele unui obiectOLE şi este specific controalelor cadru pentru obiecte OLE ataşate sauneataşate. Procedura pentru tratarea acestui eveniment are un parametru,Code, care poate avea valorile 0, 1, 2 sau 3. Valoarea 0 îi indică lui Accesscă datele obiectului au fost modificate, 1 că datele au fost salvate de

aplicaţia care a creat obiectul, 2 că fişierul ce conţine obiectul OLE a fostînchis de aplicaţia care l-a creat, iar 3 că fişierul ce conţine obiectul a fostredenumit de aplicaţia care l-a creat.

5.1.2. Evenimente legate de focusAcestea apar atunci când un control, formular sau raport primeşte sau pierde

focusul (sau când devine activ sau inactiv).• Enter – Are loc înainte ca un control să primească focusul de la un alt

control al aceluiaşi formular sau la deschiderea formularului, pentru primulcontrol al acestuia. Evenimentul apare înaintea lui GotFocus şi dupăCurrent.• Exit – Are loc înainte ca un control să piardă focusul în favoarea altuicontrol de pe formular, înaintea evenimentului LostFocus.

 Notă:Spre deosebire de evenimentele GotFocus şi LostFocus, evenimentele Enter şi Exit nu vor avea loc dacă focusul trece la un alt formular sau raport. Ele pot fi folosite pentru a afişa mesaje înaintea actualizării controalelor sau pentru a schimbaordinea în care se trece cu tasta Tab de la un control al formularului la altul.

• GotFocus – Apare atunci când un control de pe un formular primeştefocusul sau când un formular primeşte focusul, dacă toate controalele luisunt dezactivate. Un control nu poate primi focusul dacă este dezactivatsau dacă nu este vizibil. Acest eveniment are loc după evenimentul Enter.• LostFocus – Are loc atunci când un formular sau un control de pe unformular pierde focusul, după apariţia evenimentului Exit (care poate săaibă loc sau nu).• Activate – Are loc atunci când un formular sau un raport primeştefocusul şi devine activ. Aceasta se întâmplă la deschiderea formularuluisau a raportului, când se face clic pe un control al său sau când este apelată procedura Visual Basic SetFocus. Formularul sau raportul trebuie să fievizibil pentru ca evenimentul să aibă loc.

Pag. 78

Page 74: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 74/295

• Deactivate – Apare atunci când un formular sau raport pierde focusulîn favoarea altei ferestre (cum ar fi fereastra Database, fereastra uneitabele, a unei macrocomenzi, a unui modul sau alt formular sau raport).Acest eveniment nu are loc dacă focusul trece către o cutie de dialog saucătre altă aplicaţie.

5.1.3. Evenimente legate de tastaturăAcestea au loc la apăsarea unei taste sau ca rezultat al instrucţiunii SendKeys.

• KeyDown – Apare de câte ori este apăsată o tastă atunci când uncontrol sau un formular are focusul.• KeyUp  – apare de câte ori o tastă care a fost apăsată se relaxează(când un control sau formular are focusul).

Procedurile ce tratează aceste evenimente au două argumente: KeyCode şiShift.  KeyCode are ca valoare un întreg ce reprezintă tasta care a fost apăsată.

Valoarea 0 nu corespunde nici unei taste. Argumentul Shift are ca valoare un întreg cearată dacă tastele Shift, Ctrl sau Alt au fost apăsate în combinaţie cu alte taste.Valoarea 0 arată că aceste taste nu au fost apăsate, 1 că a fost apăsată tasta Shift, 2 pentru Ctrl, 4 pentru Alt. Dacă este apăsată o combinaţie a acestor taste, valoarea parametrului Shift este suma valorilor corespunzătoare.

• KeyPress – Apare atunci când o tastă sau o combinaţie de taste cecorespund unui caracter ce poate fi tipărit este apăsată şi apoi relaxată,  pentru un control sau formular. El nu are loc la apăsarea tastelor funcţionale (F1 – F12), a tastelor pentru navigare (săgeţi, Home, End, Page

Up, Page Down) sau Shift, Ctrl şi Alt. Procedura pentru tratarea acestuieveniment are un argument, KeyAscii, ce are ca valoare un întregreprezentând codul caracterului respectiv.

Notă: Folosiţi aceste evenimente cu precauţie, deoarece dacă o tastă este ţinutăapăsată, evenimentele KeyDown şi KeyPress au loc repetat, ceea ce poate duce laterminarea resurselor sistemului. Pentru a urmări acţiunile utilizatorului, puteţi folosiîn schimb evenimentele generate de accesarea datelor, cum ar fi Change şi Updated.

5.1.4. Evenimente legate de activitatea cu mouse-ulApar atunci când se efectuează anumite acţiuni cu mouse-ul asupra unui

control sau formular.• Click – Are loc atunci când se efectuează un clic cu mouse-ul pe unformular sau pe un control ori pe o secţiune a unui formular. Atunci cândse face clic pe un control aflat în cadrul unui grup de opţiuni, acesteveniment nu este al controlului respectiv, ci al grupului. Acest evenimentmai apare şi în următoarele situaţii (când nu se face clic cu mouse-ul):

- când este selectată o valoare din lista unei casete combinatecu ajutorul săgeţilor şi este apăsată tasta Enter pentru a plasavaloarea în câmpul de editare al casetei combinate;

Pag. 79

Page 75: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 75/295

- dacă este apăsată tasta Space atunci când o casetă de validare,un buton de comandă sau un buton de opţiune are focusul;- dacă se apasă tasta Enter pentru un formular care are un butona cărui proprietate Default are valoarea Yes sau dacă se apasătasta Esc pentru un formular cu un buton a cărui proprietate

Cancel are valoarea Yes;- dacă se accesează un buton de comandă cu ajutorul comenziisale prescurtate (Alt + litera subliniată dintitlul butonului).

• DblClick  – Are loc atunci când se face clic de două ori la rând cumouse-ul pe un formular, pe un control al lui sau pe o secţiune a acestuia.Atunci când se face clic pe un control aflat în cadrul unui grup de opţiuni,acest eveniment nu este al controlului respectiv, ci al grupului. Procedura pentru tratarea acestui eveniment are un argument, Cancel, care, dacă arevaloarea True, evenimentul este anulat.•

MouseMove – Apare atunci când utilizatorul mişcă mouse-ul.Procedura pentru tratarea acestui eveniment are patru argumente: Button(care arată care dintre butoanele mouse-ului a fost apăsat), Shift (aratădacă au fost apăsate tastele Shift, Ctrl sau Alt), X şi Y (care daucoordonatele curente ale cursorului mouse-ului). Argumentul Button poatelua valorile: 0 dacă nu a fost apăsat nici unul dintre butoanele mouse-ului,1 dacă a fost apăsat butonul din stânga, 2 pentru cel din dreapta şi 4 pentrucel din mijloc. Dacă au fost apăsate mai multe butoane o dată, valoarea luiButton va fi suma valorilor corespunzătoare. Valorile argumentului Shift

sunt aceleaşi ca la procedurile pentru tratarea evenimentelor de la tastatură.

• MouseDown şi MouseUp – Au loc atunci când un buton al mouse-ului este apăsat sau relaxat, în timp ce cursorul se află deasupra unuiformular, control al lui sau secţiune a acestuia. Procedura pentru tratareaacestui eveniment are aceleaşi argumente ca şi cea pentru tratarea luiMouseMove, cu diferenţa că argumentul Button poate avea valorile: 1

(pentru butonul din stânga), 2 (pentru butonul din dreapta) sau 4 (pentru butonul din mijloc). Dacă au fost apăsate mai multe butoane o dată, vor avea loc tot atâtea evenimente MouseDown şi MouseUp.

5.1.5. Evenimente legate de tipărireAcestea au loc pentru fiecare secţiune a unui raport atunci când acesta este

tipărit sau este formatat pentru a fi tipărit.• Format – Apare înainte ca Access să formateze fiecare secţiune a unuiraport, dar după ce datele au fost selectate. Pentru secţiunea Detail, acesteveniment se produce pentru fiecare înregistrare în parte. Procedura pentrutratarea acestui eveniment are două argumente: Cancel şi FormatCount.

Pag. 80

Page 76: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 76/295

Dacă argumentul Cancel are valoarea True, se renunţă la formatareasecţiunii curente şi se trece la următoarea secţiune. FormatCountreprezintă numărul de evenimente Format produse pentru secţiuneacurentă.• Retreat – Apare atunci când Access trebuie să revină la o secţiune

anterioară a unui raport în timpul formatării. El are loc după evenimentulFormat şi înaintea evenimentului Print, pentru a vă da posibilitatea de amodifica formatările făcute deja.• Print – Are loc după formatare şi înainte de afişare sau tipărire. Ca şievenimentul Format, acest eveniment are loc pentru fiecare secţiune în  parte. Procedura de tratare are două argumente: Cancel şi PrintCount.Dacă argumentul Cancel are valoarea True, secţiunea sau înregistrareacurentă nu va mai fi tipărită. PrintCount reprezintă numărul de apariţii aleacestui eveniment pentru înregistrarea curentă. Astfel, puteţi afla dacă o

înregistrare va fi tipărită pe mai mult de o pagină şi puteţi renunţa la ea.5.1.6. Evenimentele ferestrelorAcestea se produc atunci când o fereastră a unui formular sau raport este

deschisă, redimesionată sau închisă.• Open – Se produce la deschiderea unui formular sau raport şi înainteca prima înregistrare a formularului să fie afişată sau ca raportul să fieafişat sau tipărit. Procedura pentru tratarea evenimentului are un argument,Cancel, care dacă are valoarea True, formularul sau raportul respectiv nu

va mai fi deschis. Acest eveniment se produce înaintea evenimentuluiLoad.• Close – Are loc atunci când un formular sau un raport este închis saunu mai este vizibil pe ecran, după evenimentul Unload.

• Load – Apare la deschiderea unui formular şi la afişareaînregistrărilor, înaintea evenimentului Current al primei înregistrări sau al primului control al formularului, dar după evenimentul Open.• Unload – Apare la închiderea unui formular (dar înainte ca acesta sădispară de pe ecran), înaintea evenimentului Close. Procedura pentrutratarea evenimentului are un argument, Cancel, care, dacă are valoareaTrue, formularul nu va mai fi închis.

Notă:  Atenţie! Dacă daţi argumentului Cancel valoarea True, formularul nu va mai fiînchis sau ştrs de pe ecran. Astfel, dacă nu îi daţi explicit mai târziu valoarea False,nu veţi mai putea închide formularul decât închizând aplicaţia.

• Resize – Apare la deschiderea unui formular sau la redimesionarea sa.Astfel, aveţi posibilitatea să redimensionaţi şi controalele formularului.

Pag. 81

Page 77: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 77/295

5.1.7. Evenimente generate de erori• Error – Are loc atunci când apare o eroare de execuţie la rulareaaplicaţiei. Astfel, aveţi posibilitatea de a intercepta mesajele de eroare alelui Access şi de a afişa propriile dumneavoastră mesaje. Procedura pentrutratarea acestui eveniment are două argumente: DataErr, care reprezintă

codul de eroare returnat de funcţia Err ce se apelează de câte ori apare oeroare şi Response, care determină dacă trebuie să fie afişat un mesaj deeroare standard. Dacă Response are valoarea 0, Access nu mai afişamesajul de eroare, putând astfel să afişaţi un mesaj personalizat, iar dacăare valoarea 1, Access va afişa mesajul standard.

5.1.8. Evenimentele legate de timer• Timer   – Apare la intervale de timp regulate, dacă aţi stabilit proprietatea TimerInterval a unui formular. Dacă această proprietate are

valoarea 0, evenimentul nu se va produce. Pentru valori cuprinse între 0 şi65536, evenimentul va avea loc la intervalul stabilit, valoarea reprezentândmărimea intervalului în milisecunde.

5.2. Ordinea producerii evenimentelor în Access

După ce aţi făcut cunoştinţă cu câteva dintre evenimentele ce pot apărea într-oaplicaţie Access, este important să înţelegeţi ordinea în care acestea se succed, pentruale putea folosi la stabilirea comportamentului aplicaţiei.

5.2.1. Ordinea producerii evenimentelor legate de controaleCând un control primeşte focusul, au loc următoarele evenimente:

Când introduceţi sau modificaţi datele dintr-un control şi apoi treceţi focusulaltui control, ordinea producerii evenimentelor este următoarea:

Pag. 82

Enter GotFocus

KeyDown KeyPress Change KeyUp BeforeUpdate

AfterUpdate Exit LostFocus

Page 78: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 78/295

Notă:  Dacă în câmpul de editare al unei casete combinate este introdusă o valoareacare nu se regăseşte în lista acestuia, după evenimentul KeyUp apar evenimentele NotInLst şi Error.

5.2.2. Ordinea producerii evenimentelor legate de lucrul cu înegistrărileunui formular

Evenimentele ce se produc atunci când sunt afişate înregistrările unuiformular, sunt diferite de cele ale controalelor care afişează date ale înregsitrărilor respective.

Dacă modificaţi o înregistrare prin intermediul controalelor unui formular şitreceţi apoi la următoarea înregistrare, se vor produce, în ordine, următoareleevenimente:

La ştergerea unei înregistrări, ordinea producerii evenimentelor esteurmătoarea:

Când treceţi focusul pe o înregistrare nouă (ce nu conţine încă date), vor apărea evenimetele:

5.2.3 Ordinea producerii evenimentelor legate de formulareLucrul cu un formular implică generarea unor evenimente legate de închidere,

deschidere, trecerea de la un formular la altul şi lucrul cu datele formularului.

Pag. 83

Current (formular) Entercontrol

GotFocuscontrol

BeforeUpdatecontrol

AfterUpdate (control) BeforeUpdate(formular)

AfterUpdateformular

Exit (control) LostFocus (control)

Current (formular)

Delete BeforeDelConfirm AfterDelConfirm

Current (formular) Enter (formular) GotFocuscontrol

BeforeInsert (formular) AfterInsert (formular)

Page 79: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 79/295

De exemplu, dacă deschideţi formularul f1, apăsaţi pe un buton al său pentru adeschide formularul f2 şi apoi treceţi din nou la formularul f1, vor avea loc, în ordine,evenimentele:

Observaţi că evenimentul Deactivate al formularului f1 apare dupăevenimentele Open, Load şi Resize ale lui f2. Astfel, dacă în timpul deschiderii celui

de-al doilea formular apare o eroare, îl puteţi închide şi pune focusul pe primulformular.Când lucraţi cu subformulare, ordinea producerii evenimentelor este

următoarea:

5.2.4. Ordinea producerii evenimentelor legate de tastatură şi mouseDupă cum am mai spus, aceste evenimente apar atunci când un formular sau

un control al unui formular primeşte focusul. Ordinea producerii evenimentelor generate de apăsarea unei taste este:

Ordinea evenimentelor generate de apăsarea unui buton al mouse-ului este:

Dacă de efectuează un dublu clic, evenimentul DblClick va apărea dupăevenimentul Click.

Pag. 84

Open (f1) Load (f1) Resize (f1) Current (f1)

Open (f2) Load (f2) Resize (f2) Deactivate (f1)

Activate (f2) Current (f2) Deactivate (f2) Activatef1

Evenimente ale controalelor subformularului

Evenimente ale controalelor formularului

Evenimentele formularului Evenimentele subformularului

KeyDown KeyPress KeyUp

MouseDown MouseUp Click  

Page 80: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 80/295

5.2.5. Ordinea producerii evenimentelor rapoartelorEvenimentele unui raport sunt generate de tipărirea, afişarea sau de închiderea

raportului respectiv. Astfel, când deschideţi un raport pentru a-l tipări sau afişa şi apoiîl închideţi, vor apărea, în ordine, evenimentele:

Evenimentul Open are loc înainte ca înregistrarea pe care se bazează raportulsă fie executată. Dacă interogarea nu generează nici o înregistrare, se produceevenimentul NoData.

5.3. Tratarea evenimentelor

După ce aţi decis ce acţiuni doriţi să fie efectuate ca răspuns la anumiteevenimente, nu mai trebuie decât să le scrieţi codul Visual Basic corespunzător   procedurilor pentru tratarea evenimentelor respective. Figura VII.1 prezintă paginaEvent a ferestrei Properties a unui formular. Făcând clic pe săgeata din dreaptacâmpului unui eveniment, se va deschide o listă din care veţi putea alege omacrocomandă. Pentru a crea procedura pentru tratarea unui eveniment şi a-i scriecodul VBA, procedaţi astfel:

1. Deschideţi formularul sau raportul în modul Design. Dacă doriţi să trataţiun eveniment al unui control sau al unei secţiuni, selectaţi controlul sau

secţiunea respectivă.2. Deschideţi fereastra Properties a formularului, raportului, secţiunii saucontrolului respectiv şi selectaţi pagina Event.

3. Din lista corespunzătoare evenimentului pe care doriţi să îl trataţi, alegeţiopţiunea [Event Procedure] şi apăsaţi butonul Build (…) pentru adeschide fereastra modului în care se va afla procedura.

4. Access va scrie automat scheletul procedurii, care va arăta astfel:Sub nume_procedura ()… End Sub

5. Alegeţi comanda Debug | Compile Loaded Modules pentru a compila procedura.

6. Salvaţi modulul.

Astfel, de câte ori va avea loc evenimentul respectiv, această procedură va fiapelată şi executată.

Pag. 85

Open Activate Format Print Close Deactivate

Page 81: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 81/295

Despre procedurile VBA vom vorbi pe larg mai tîrziu. Aţi observat că în acestcapitol am insistat mai mult pe folosirea procedurilor VBA decât a macrocomenzilor   pentru tratarea evenimentelor. Aceasta pentru că procedurile sunt mai rapide înexecuţie, mai flexibile şi mai uşor de întreţinut. Spre deosebire de macrocomenzi, elevă dau posibilitatea de a intercepta şi a trata erorile cu ajutorul evenimentului Error şi

a funcţiei OnError. Cu toate acestea, există şi câteva macrocomenzi care nu aucorespondent în VBA: AutoKeys, Autoexec şi AddMenu.

.

CAP:6. Macrocomenzi

Macrocomenzile reprezintă o metodă simplă de a efectua anumite acţiuni într-o aplicaţie Access, fără a avea prea multe cunoştinţe de programare. Mai precis, omacrocomandă este o înşiruire de acţiuni, programată să se execute în cazul producerii unui anumit eveniment.

Macrocomenzile sunt, aşadar, nişte instrumente utile, care vă permit să programaţi acţiuni simple, de la deschiderea şi închiderea unui formular ori raport saustabilirea unor opţiuni, până la emiterea unui semnal sonor, totul în doar câtevasecunde. Pe de altă parte, macrocomenzile au dezavantajele lor, care îi determină pecei mai mulţi programatori Access să prefere modulele şi codul VBA. Access vă dăchiar posibilitatea de a transforma o macrocomandă în codul VBA echivalent. Pelângă faptul că macrocomenzile sunt mai lente în execuţie decât procedurile, ele mai

Pag. 86

Page 82: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 82/295

au dezavantajul că nu oferă programatorului posibilitatea de a intercepta şi tratacorespunzător erorile.

Există însă şi unele acţiuni care pot fi efectuate numai prin intermediulmacrocomenzilor:

• Definirea comenzilor rapide de la tastatură pentru diferite acţiuni. Spre

exemplu, dacă veţi dori ca tasta F3 să deschidă un anumit formular, nu veţi putea stabili acest lucru decât cu ajutorul macrocomenzii AutoKeys.• Rularea anumitor acţiuni la deschiderea bazei de date.• Crearea şi utilizarea meniurilor şi a barelor cu instrumente personalizate.

6.1. Crearea unei macrocomenziPentru a înţelege mai bine cum se creează o macrocomandă, vom descrie în

cele ce urmează paşii necesari creării unei macrocomenzi care să afişeze o casetă de

mesaj cu un text de salut.1. Deschideţi pagina Macros a ferestrei Database şi apăsaţi butonul New. Seva deschide fereastra Macro Builder (figura 6.1).

2.

Fig. 6.1

3. Faceţi clic pe prima linie a coloanei Action şi apoi apăsaţi pe săgeata din  partea dreaptă a câmpului. Se va deschide o listă cu toate acţiunile.Selectaţi acţiunea MsgBox.

4. După ce aţi selectat o acţiune, în partea de jos a ferestrei Macro Builder vor apărea argumentele corespunzătoare acţiunii respective. În acest caz,ele sunt: Message (mesaj), Beep (semnal sonor), Type (tipul casetei demesaj) şi Title (titlul casetei de mesaj). Figura 6.1 prezintă valorile pe carele-am ales pentru aceste argumente.

5. Salvaţi macrocomanda cu ajutorul comenzii File | Save. Va apărea o cutiede dialog cerându-vă un nume pentru noua macrocomandă (să-i spunem“Salut”).

Pag. 87

Page 83: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 83/295

6. Pentru a rula macrocomanda, apăsaţi butonul Run de pe bara cuinstrumente sau alegeţi comanda Run | Run. Caseta de mesaj va arăta caîn figura 6.2.

Fig. 6.2

Notă: Este bine ca pentru fiecare acţiune a unei macrocomenzi să introduceţi un scurt comentariu care să descrie ce anume face acţiunea respectivă. Folosiţi pentru

aceasta liniile coloanei Comment. Dacă veţi converti ulterior macrocomanda la codul VBA corespunzător, aceste comentarii nu se vor pierde.După cum v-aţi putut da seama, pentru a crea o macrocomandă care să

îndeplinească o anumită cerinţă, este important să cunoaşteţi atât acţiunile disponibile,cât şi argumentele acestora..

6.2. Grupuri de macrocomenziGrupurile de macrocomenzi sunt, după cum le spune şi numele, colecţii de

macrocomenzi simple, salvate separat, dar cuprinse în aceeaşi comandă globală.

Fiecare macrocomandă din grup trebuie să aibă un nume propriu, pe care îl introduceţiîn coloana Macro Name a ferestrei Macro Builder (această coloană va fi afişată dacăselectaţi comanda View | Macro Names). Într-un grup, macrocomenzile componetetrebuie să fie separate prin linii goale (ca în figura 6.3).

Pag. 88

Page 84: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 84/295

Fig. 6.3

Grupurile de macrocomenzi sunt utile, de exemplu, atunci când doriţi să păstraţi toate macrocomenzile unui formular în acelaşi obiect, astfel încât numărulobiectelor din pagina Macro a ferestrei Database să fie mai mic. Pe de altă parte, omacrocomandă poate apela altă macrocomandă în cadrul unei condiţii, caz în care veţi prefera să le includeţi pe amândouă în acelaşi obiect, pentru a fi mai simplu dedepanat.

O macrocomandă din grup poate fi executată utilizând numele grupului, urmatde un punct şi de numele macrocomenzii:

nume_grup.nume_macroExecuţia unei macrocomenzi din grup se opreşte la întâlnirea următoarei linii

libere din coloana Action.O altă utilizare frecventă a grupurilor de macrocomenzi o reprezintă crearea

meniurilor personalizate, în care fiecărui control îi corespunde o macrocomandă dingrup.

6.3. Macrocomenzi imbricateÎn Access puteţi crea şi macrocomenzi compuse, în care o macrocomandă să

fie apelată de alta. Cel mai simplu mod de a realiza acest lucru este folosirea acţiuniiRunMacro. Figura 6.4 prezintă macrocomanda care apelează macrocomanda Mac1.

Pag. 89

Page 85: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 85/295

Fig. 6.4O altă situaţie în care se folosesc macrocomenzi imbricate este atunci când

veţi dori să controlaţi execuţia unei macrocomenzi impunând o condiţie. Desprecondiţii în macrocomenzi vom vorbi în secţiunea următoare.

6.3.1. Condiţii în macrocomenziAccess vă pune la dispoziţie un mod rudimentar de a controla firul de execuţie

al macrocomenzilor, prin intermediul coloanei Condition a ferestrei Macro Builder.Pentru a vedea această coloană, selectaţi comanda View | Conditions.

Dacă introduceţi o expresie în coloana Condition, acţiunea aflată pe aceeaşilinie în coloana Action se va executa numai dacă expresia este adevărată. Dacăexpresia este falsă, Access nu va executa acţiunea de pe aceeaşi linie cu condiţia şi vatrece la următoarea acţiune. Dacă introduceţi trei puncte de suspensie (…) în coloanaCondition pe linia de sub o condiţie existentă, Access va considera acţiunea de pe

aceeaşi linie cu punctele de suspensie ca fiind pusă aceleiaşi condiţii.

6.4. Macrocomenzi specialeÎn cele ce urmează, vom discuta despre două macrocomenzi ce merită o

atenţie specială: AutoKeys şi AutoExec.

6.4.1. Macrocomanda AutoKeysMacrocomanda AutoKeys vă permite să atribuiţi comenzi rapide de la

tastatură acţiunilor pe care le poate efectua aplicaţia dumneavoastră. De exemplu, ar fiutil ca, de câte ori utilizatorul foloseşte combinaţia de taste Ctrl+P, să fie tipăritraportul curent. Astfel, puteţi atribui orice combinaţie de taste oricărei acţiuni (sau

Pag. 90

Page 86: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 86/295

grup de acţiuni) care poate fi executată prin intermediul unei macrocomenzi. Pentru anu crea confuzii, evitaţi totuşi atribuirea combinaţiilor de taste predefinite în

Access (cum ar fi Ctrl +V pentru comanda Edit | Paste) deoarece, în astfel de cazuri,Access va executa macrocomanda dumneavoastră în locul comenzii predefinite.

 Nu puteţi atribui o macrocomandă unei singure taste alfanumerice sau uneitaste folosite, în general, în combinaţie cu alte taste (precum Ctrl sau Alt). Tastelor funcţionale (F1-F12) şi tastelor Insert şi Delete le puteţi atribui macrocomenzi.

Pentru a atribui o combinaţie de taste unei acţiuni, procedaţi astfel:1. Creaţi o nouă macrocomandă, apăsând butonul New din pagina Macros a

ferestrei Database.2. Alegeţi comanda View | Macro Names pentru a afişa coloana Name a

ferestrei Macro Builder. Introduceţi aici combinaţia de taste pe care doriţisă o atribuiţi, urmând instrucţiunile din tabelul 6.5.

3. Introduceţi în coloana Action corespunzătoare acţiunea atribuităcombinaţiei de taste din coloana Name. Dacă doriţi să atribuiţi mai multeacţiuni unei combinaţii de taste, nu trebuie decât să le introduceţi pe liniiconsecutive ale coloanei Action (fără a lăsa linii libere între ele).

4. Închideţi macrocomanda şi salvaţi-o cu numele “AutoKeys”. Esteimportant ca acesta să fie numele macrocomenzii, deoarece altfel Accessnu va efectua atribuirile.

5. Închideţi baza de date (cu comanda File | Close) şi deschideţi-o din nou pentru a activa macrocomanda AutoKeys.

Pentru a specifica o anumită combinaţie de taste, trebuie să folosiţi o sintaxăspecială, descrisă în tabelul 6.5, în care tastei din coloana Tasta îi corespund, încoloana Name a ferestrei Macro Buider, caracterele din coloana Corespondent atabelului. Coloana Exemplu vă arată concret ce aţi putea introduce în coloana Name aferestrei Macro Builder.

Tasta Corespondent ExempluCtrl ^ ^Z (pentru Ctrl+Z)

Tastăfuncţională { } {F8} (pentru tastaF8)Shift + +{F8} (pentru Shift+F8)Insert {INS} sau {INSERT} {INS} (pentru tasta Insert)Delete {DEL} sau {DELETE} {DEL} (pentru tasta Delete)Combinaţii detaste

Folosiţi caracterele de mai sus +^{F8} (pentru combinaţiaShift+Ctrl+F8)

Tabelul 6.5

În figura 6.6 este prezentată macrocomanda AutoKeys care atribuie acţiunii detipărire a primelor două pagini ale obiectului curent combinaţia de taste Ctrl+P.

Pag. 91

Page 87: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 87/295

Figura 6.6

6.4.2. Macrocomanda AutoExec

Dacă doriţi ca anumite ca anumite acţiuni să aibă loc ori de câte ori sedeschide o bază de date, puteţi crea o macrocomandă care să efectueze acţiunilerespective şi pe care să o salvaţi cu numele “AutoExec”. Cea mai frecventă utilizare amacrocomenzii AutoExec este ascunderea ferestrei Database şi deschiderea unuiformular care să joace rolul de meniu principal al aplicaţiei sau de spalsh-screen.

În Access 97 vă puteţi lipsi de această macrocomandă, deoarece există o cutiede dialog în care puteţi alege formularul care va fi afişat la deschiderea bazei de date.Pentru a deschide această cutie de dialog alegeţi comanda Tools | StartUp.

Ţinând tasta Shift apăsată, utilizatorul va putea, totuşi, să împiedice rularea

macrocomenzii AutoExec la deschiderea bazei de date.Figura 6.7 prezintă macrocomanda AutoExec care deschide formularul

„Student” ori de câte ori este deschisă baza de date Optionale.mdb.

Pag. 92

Page 88: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 88/295

Figura 6.7

6.5. Crearea meniurilor şi a barelor cu instrumente personalizateÎn versiunile anterioare lui Access 97, se foloseau macrocomenzi pentru

crearea barelor de meniuri personalizate pentru aplicaţii. Aceste bare de meniuriînlocuiau bara de meniu standard Access, pentru a limita acţiunile utilizatorului la celespecifice aplicaţiei sau pentru a simplifica efectuarea unor acţiuni prin rularea demacrocomenzi. Aceste versiuni anterioare de Access furnizau un instrument

specializat pentru crearea de astfel de meniuri, numit Menu Builder şi care vă ajuta săscrieţi macrocomenzile corespunzătoare.Access 97 nu mai include instrumentul Menu Builder, ci tratează barele de

meniuri şi barele cu instrumente unitar, numindu-le bare de comandă. Introducemtotuşi această discuţie aici, deoarece până la versiunea Access 97, meniurile şi barelecu instrumente erau create cu ajutorul macrocomenzilor. Şi în Access 97 mai pot fifolosite macrocomenzile în acest scop, dar există şi o modalitate mai simplă, pe care o prezentăm în continuare.

Pentru a crea sau a modifica o bară cu instrumente sau o bară de meniuri înAccess 97, procedaţi astfel:

1. Alegeţi comanda View | Toolbars | Customize. Se va deschide cutia dedialog Customize (figura 6.8).

Pag. 93

Page 89: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 89/295

2. Apăsaţi butonul New din pagina Toolbars pentru a crea o nouă bară cuinstrumente. Se va deschide cutia de dialog Toolbar Name, în care vatrebui să introduceţi un nume pentru bara cu instrumente. După ce apăsaţi butonul OK , va apărea pe ecran noua bară, ce nu conţine nici un buton şinici un meniu.

Pentru a adăuga butoane la o bară cu instrumente existentă, selectaţi-o în listadin pagina Toolbars a cutiei de dialog Customize şi treceţi la pagina

Commands. Dacă doriţi ca butonul să fie asociat deschiderii unui obiect din baza dedate (tabelă, interogare, formular sau raport) sau rulării unei macrocomenzi, selectaţidin lista Categories una dintre opţiunile All Tables, All Queries, All Forms, AllReports sau, respectiv, All Macros. În funcţie de opţiunea aleasă, în lista Commnadsvor apărea toate obiectele din baza de date curentă care fac parte din categoriarespectivă. Selectaţi şi executaţi drag & drop cu obiectul dorit pe bara cu instrumente

la care doriţi să îl adăugaţi. După ce închideţi fereastra Customize, nu trebuie decât săapăsaţi pe noul buton pentru a se efectua acţiunea pe care i-aţi atribuit-o.

Figura VIII.8

Pentru a adăuga un meniu la o bară cu instrumente existentă, procedaţi ca şi pentru butoane, cu diferenţa că din lista Categories trebuie să alegeţi opţiunea NewMenu. Selectaţi apoi articolul New Menu din lista Commands şi faceţi drag & dropcu el peste bara respectivă. Faceţi apoi clic dreapta pe meniul nou adăugat, pentru aafişa un meniu derulant. În caseta Name a acestui meniu derulat, scrieţi numele nouluimeniu şi apăsaţi tasta Enter. Acum, meniul există, dar nu are nici un articol de meniu.

Pentru a adăuga comenzi unui meniu, procedaţi la fel ca pentru adăugarea butoanelor la o bară cu instrumente, cu diferenţa că trebuie să faceţi drag & drop cu obiectele

Pag. 94

Page 90: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 90/295

selectate din lista Commands pe meniul respectiv. Exact în acelaşi mod puteţi adăugasubmeniuri la meniurile existente.

Pentru a şterge un meniu sau un buton al unei bare cu instrumente, selectaţi bara respectivă din lista din pagina Toolbars a cutiei de dialog Customize. Faceţiapoi clic dreapta pe butonul sau pe meniul respectiv şi alegeţi din meniul derulant

comanda Delete. Pentru a şterge o bară cu instrumente cu totul, selectaţi-o în paginaToolbars a cutiei de dialog Customize şi apăsaţi butonul Delete.

6.6. Rularea şi depanarea macrocomenzilor

Există mai multe modalităţi de rula o macrocomandă în Access:

1. Făcând dublu-clic pe numele macrocomenzii în pagina Macros a ferestreiDatabase.2. Prin intermediul codului VBA dintr-un modul, folosind metoda

RunMacro a obiectului DoCmd:DoCmd.RunMacro nume_macrocomanda

3. Dintr-o altă macrocomandă sau prin intermediul barelor personalizate demeniuri sau de instrumente.

4. La deschiderea bazei de date, dacă numele macrocomenzii este AutoExec.

Vă puteţi da seama dacă o macrocomandă nu funcţionează când vedeţi cutiade dialog (figura 6.9) aceasta vă prezintă numele macrocomenzii care a eşuat,acţiunea care a produs eroarea şi argumentele acţiunii respective. Apăsaţi butonulHalt pentru a depana macrocomanda.

Fig. 6.9

Puteţi depana o macrocomandă rulând-o acţiune cu acţiune, în felul următor:

Pag. 95

Page 91: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 91/295

• Deschideţi macrocomanda în fereastra Macro Builder.• Apăşaţi butonul Single Step de pe bara cu instrumente sau alegeţicomanda Run | Single Step.• Dacă macrocomanda începe pe prima linie a ferestrei Macro Builder, puteţi apăsa butonul Run de pe bară pentru a porni execuţia. Dacă depanaţi

o macrocomandă dintr-un grup, va trebui să rulaţi codul care apeleazămacrocomanda respectivă.Când macrocomanda începe să ruleze, pe ecran apare cutia de dialog Macro SingleStep, care prezintă acţiunea în curs de rulare şi valorile parametrilor 

acesteia. Această cutie de dialog vă oferă trei opţiuni: rularea acţiunii următoare (cu butonul Step), oprirea execuţiei macrocomenzii (cu butonul Halt) şi continuareaneîntreruptă a execuţiei (cu butonul Continue).De asemenea, puteţi opri de la tastatură execuţia unei macrocomenzi la un moment

dat, apăsând Ctrl + Break . Atunci, va apărea cutia de dialog Macro Single Step, cevă va permite rularea pas cu pas a macrocomenzii.

Pag. 96

Page 92: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 92/295

CAP:7. Visual Basic for Applications (VBA)

După cum v-aţi putut da seama, în Access puteţi realiza multe lucruri fără aavea prea multe calităţi de programator. Totuşi, dacă doriţi să creaţi o aplicaţie dotatăcu o interfaţă inteligentă şi prietenoasă, va trebui să învăţaţi să scrieţi codul necesar  pentru a controla aplicaţia.

Obiectul acestui capitol este limbajul VBA (Visual Basic for Applications),care este un limbaj de programare complex, ce vă permite dezvoltarea de aplicaţii atâtîn Access, cât şi în Microsoft Excel, Microsoft Project şi, bineînţeles, MicrosoftVisual Basic. Interceptarea şi tratarea erorilor, un control mai bun asupra interfeţei cuutilizatorul, mai multă rapiditate în execuţie, posibilitatea de a interacţiona cu alteaplicaţii şi de a apela funcţii Windows API sunt numai câteva dintre avantajele programării în VBA.

7.1 Mediul de programare Access

Access păstrează codul procedurilor scrise de dumneavoastră în aşa-numitelemodule. Acestea se împart în trei categorii: module standard, module pentru clase şimodule pentru formulare şi rapoarte.

Modulele standard sunt obiecte de sine stătătoare şi sunt folosite pentru a creaşi stoca proceduri ce nu sunt legate de un anumit formular sau raport. Le puteţi crea şivedea în pagina  Modules a ferestrei Database folosind butoanele  New şi, respectiv, Design. Modulele pentru clase sunt folosite pentru a crea şi a defini obiecte cărora le puteţi apoi crea instanţe (vom reveni asupra lor în secţiunea 7.6). Modulele pentruformulare şi rapoarte se deosebesc de celelalte tipuri de module prin faptul că nu suntobiecte independente, ci sunt incluse în formularul sau raportul corespunzător. Eleconţin procedurile pentru tratarea evenimentului formularului sau raportului respectivşi pot fi deschise cu ajutorul comenzii View | Code, atâta timp cât sunteţi în modulDesign View.

Ce conţin moduleleAţi văzut deja cum puteţi accesa un modul. Atunci când un modul este

deschis, în partea de sus a ferestrei asociate veţi vedea două casete combinate. Acesteavă ajută să găsiţi diferitele proceduri stocate în modulul respectiv. Cel din stânga vă permite să alegeţi obiectul al cărui cod doriţi să-l vedeţi sau să-l editaţi. În cazulmodulelor standard, singura opţiune este General , deoarece acestea nu conţin obiecte,

Pag. 97

Page 93: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 93/295

în timp ce în cazul unui modul al unui formular sau raport, această casetă combinatăva afişa lista tuturor obiectelor pe care le conţine. După ce aţi selectat un obiect, încaseta combinată din dreapta veţi putea alege un eveniment al acelui obiect.

Fig. 7.1

(General)(General) nu este un obiect, ci mai degrabă o secţiune în cadrul unui modul.

Aici veţi putea pune tot ce ţine de modulul respectiv, în general: opţiuni, declaraţii, proceduri care nu tratează evenimente (în cazul modulelor standard, toate procedurilese vor afla aici).

OpţiuniOrice modul are un set de opţiuni, pe care le puteţi stabili cu ajutorulcuvântului cheie Option şi pe care vi le prezentăm în continuare:

1. Option Base – vă permite să stabiliţi indicele cel mai mic pentruelementele unei matrice (array). Implicit, acesta este zero.2. Option Compare – determină modul în care Access va compara douăşiruri de caractere (lucru util, de exemplu, pentru sortări).3. Option Compare Binary – Access va folosi reprezentarea binară acaracterelor pentru comparaţiile făcute în cadrul modulului.

4. Option Compare Database – opţiune implicită, ce face ca Access săfolosească ordinea de sortare a bazei de date pentru efectuareacomparaţiilor între şiruri de caractere. Această ordine poate fi schimbată

Pag. 98

Page 94: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 94/295

cu ajutorul comenzii Tools | Options, dacă în pagina General a cutiei dedialog ce se va deschide veţi selecta o altă valoare în caseta combinată New Database Sort Order.5. Option Compare Text – similară cu Option Compare Database, cudeosebire că la efectuarea comparaţiilor între şiruri de caractere nu se face

diferenţă între literele mari şi mici.6. Option Explicit – Dacă specificaţi această opţiune, toate variabilelevor trebui să fie declarate înainte de a fi folosite în cadrul modulului.7. Option Private – Dacă stabiliţi această opţiune, codul aflat îninteriorul modulului nu va putea fi accesat dintr-un alt modul.

Declaraţii (Declarations)Tot la secţiunea (General) a unui modul mai puteţi declara proceduri, variabile

şi constante ce pot fi folosite în întregul modul.Proceduri pentru tratarea evenimentelorModulele pentru formulare şi rapoarte pot conţine şi alte secţiuni, în afară de

(General). Acestea corespund controalelor şi secţiunilor formularului sau raportuluirespectiv şi conţin procedurile pentru tratarea evenimentelor legate de ele.

7.2 Proceduri

O  procedură este o înşiruire de linii de cod, care ca scop îndeplinirea unuianumit obiectiv. În Access, procedurile pot fi de două tipuri: subrutine şi funcţii .O subrutină este, pur şi simplu, un bloc de cod care are un nume. Blocul de

cod ce compune subrutina poate fi folosit prin apelarea numelui. O funcţie este cevaasemănător unei subrutine, cu diferenţa că ea returnează o valoare.

Programatorul poate comunica informaţii unei proceduri prin intermediulargumentelor . Acestea sunt variabile ale căror valori au fost deja stabilite şi caretransmit procedurilor datele necesare efectuării operaţiilor specifice.

Chiar dacă pe moment lucrurile nu sunt foarte clare, este important săînţelegeţi faptul că o procedură este un mod de a aduna mai multe linii de cod laolaltă,astfel încât de câte ori veţi dori să efectuaţi o anumită operaţie, să nu trebuiască săscrieţi decât o singură linie de cod, conţinând numele procedurii.

7.2.1 Declararea procedurilorDeclararea unei proceduri trebuie să conţină următoarele informaţii: tipul

 procedurii (subrutină sau funcţie), numele procedurii, numele şi tipul argumentelor (dacă acestea există), tipul informaţiei returnate (dacă procedura este o funcţie).

De exemplu, iată cum ar putea să arate (schematic) declararea unei subrutinecare tipăreşte un şir de caractere:

 Sub Tiparire(strText As String)

Pag. 99

Page 95: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 95/295

Debug.Print strTextEnd Sub

 Numele subrutinei este Tiparire şi ea are un singur argument, strText, de tipString (şir de caractere). Subrutina va putea fi apelată astfel:

Call Tiparire (“Salut!”)

Iată acum declararea unei funcţii care returnează rezultatul împărţirii a douănumere reale:

Function Cat (db1Nr1 As Double, db1Nr2 As Double) As DoubleIf db1Nr2 = 0 Then Cat = 0Else Cat = db1Nr1 / db1Nr2

End If  End Function

Pentru a apela funcţia, vom scrie:

db1Rez = Cat (n1, n2)unde n1 şi n2 sunt variabile ale căror valori au fost stabilite anterior. Observaţi facptulcă, pentru ca rezultatul să fie corect, este importantă ordinea în care sunt dateargumentele. Există şi o modalitate de a furniza argumentele unei funcţii în altă ordinedecât cea în care acestea au fost date la declararea funcţiei: în faţa argumentuluiefectiv, specificaţi numele argumentului din declaraţie, urmat de două puncte şi egal,ca în exemplul de mai jos.

db1Rez = Cat (db1Nr2:= n2, db1Nr1:= n1)

În general, pentru ca apelul unei proceduri să se poată compila, trebuie să fifost furnizate toate argumentele din declaraţie. Puteţi însă modifica acestcomportament, dacă în cadrul declaraţiei veţi specifica înaintea numelui unuiargument cuvântul cheie Optional. Astfel, la apelul procedurii, nu va mai trebuineapărat să daţi valoarea efectivă a acelui argument. De exemplu, funcţia Cat poate fideclarată ca:

Function Cat (Optional db1Nr1 As Double, db1Nr2 As Double) As Double

şi apoi apelată astfel:

Pag. 100

Page 96: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 96/295

db1Rez = Cat (, n2)sau

db1Rez = Cat (db1Nr2:= n2)

Atunci când apelaţi o procedură fără să furnizaţi unele dintre argumentele

opţionale, trebuie ca în locul lor să puneţi o virgulă sau să specificaţi pentruargumente neopţionale, numele acestora din declaraţie. De aceea, este bine ca ladeclararea unei proceduri să lăsaţi la urmă argumentele opţionale, pentru ca la apelaresă nu mai trebuiască să includeţi virgule sau nume. Astfel, putem să declarăm funcţiaCat aşa:

Function Cat (db1Nr2 As Double, Optional db1Nr1 As Double) As Doubleşi o putem apela:

db1Rez = Cat (n2)

 Notă:  Atât folosirea argumentelor opţionale cât şi a celor complet specificate (cuajutorul numelui din declaraţie) este recomandată mai ales atunci când proceduraare un număr mare de argumente.

7.2.2. Lucrul cu argumente opţionaleCum putem afla dacă un argument declarat ca opţional a fost sau nu furnizat la

apelul procedurii? Pentru aceasta există o funcţie Access predefinită, IsMissing, care

returnează valoarea True dacă argumentul lipseşte şi False dacă acesta a fost furnizat.Putem rescrie funcţia Cat astfel încât, dacă deîmpărţitul lipseşte, să returneze valoareazero:

Function Cat (db1Nr1 As Double, Optional db1Nr1 As Double) As DoubleIf IsMissing (db1Nr1) Then Cat = 0Else If db1Nr2 = 0 Then Cat = 0

Else Cat = db1Nr1 / db1Nr2End If 

End If  End Function

7.2.3. Funcţii predefiniteIsMissing este una dintre funcţiile predefinite pe care Access vi le pune la

dispoziţie. Există funcţii predefinite pentru toate tipurile de activităţi: lucrul cu texte şidate numerice, comunicarea cu alte aplicaţii, lucrul cu fişiere şi directoare, cu date şiore etc. Puteţi faceţi cunoştinţă cu funcţiile predefinite dacă lucraţi cu ExpressionBuilder. Pentru a vă bucura de facilităţile oferite de aceste funcţii, nu trebuie decât săle apelaţi în codul dumneavoastră.

Pag. 101

Page 97: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 97/295

7.3. VariabileVariabilele sunt utilizate pentru a stoca date folosite în subrutine sau funcţii

(asemeni unor containere). Puteţi atribui o valoarea unei variabile şi apoi să efectuaţicalcule cu valoarea respectivă prin intermediul variabilei. Folosind variabila şi nudirect valoarea, daţi flexibilitate codului pe care îl veţi putea apoi refolosi şi pentru

alte valori.Spuneam mai înainte că variabilele sunt nişte “containere” folosite pentru astoca date. Însă, până acum, aţi văzut că în Access datele sunt stocate în tabele, deci cenevoie mai avem de variabile? Există o diferenţă esenţială între aceste două mijloacede stocare a datelor: spre deosebire de tabele, variabilele  sunt folosite pentru a stoca oinformaţie temporară, ce ne ajută să obţinem un anumit rezultat şi apoi va fi uitată.Tabelele sunt folosite pentru a stoca informaţii pentru o perioadă mai lungă de timp.

7.3.1 Tipuri de dateTipurile de date sunt folosite pentru a specifica ce fel de informaţie va fi

  păstrată într-o variabilă astfel încât Access să ştie cum să stocheze şi cum sămanipuleze această informaţie. Tabelul 7.2 prezintă toate tipurile de date pe careAccess 97 vi le pune la dispoziţie.

Tipul dedate

Domeniul Exemplu

String Şir de caractere Dim strText As StringDim strText$

Integer Numere întregi între –32768 şi 32767 Dim intNr As Integer  Dim intNr%

Long Numere întregi între –2147483648 şi2147483647

Dim lngNr As LongDim lngNr&

Single Numere reale pozitive sau negative cumaximum 7 zecimale, cu valoare absolutăîntre 1.401298*10-45 şi 3.402823*1038

Dim sngNr As Single

Dim sngNr!Double Numerele reale pozitive sau negative cu

maximum 15 zecimale, cu valoare absolutăîntre 4.94065645842147*10-324 şi1.79769313486231*10308

Dim db1Nr As Double

Dim db1Nr#

Currency Număr cu 4 zecimale între – 922337203685477.5808 şi

922337203685477.5807, folosit mai ales îndomeniul bancar 

Dim crnNr AsCurrency

Dim crnNr@Boolean Pentru variabile care pot avea numai valorea Dim bNr As Boolean

Pag. 102

Page 98: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 98/295

True sau FalseDate Date între 1 Jan 100 şi 31 Dec 9999 şi ore

între 00:00:00 şi 23:59:59Dim datData As Date

Byte Valori întregi între 0 şi 25 Dim bytNr As ByteObject Orice tip de obiecte, nu numai obiecte Access

97

Dim objObiect As

ObjectVariant Folosit pentru a stoca diferite tipuri de date Dim varOrice AsVariant

Hyperlink 

Stochează date de tip text ce reprezintăadrese de hiperlegături

Dim hypPag AsHyperlink 

Tabelul 7.2

7.3.2 Declararea variabilelorDacă la secţiunea (General) (Declarations) a unui modul aţi stabilit opţiunea

Option Explicit, înainte de aputea atribui o valoare unei variabile, trebuie să-I indicaţilui Access două lucruri: numele variabilei şi tipul datelor pe care aceasta le va stoca;cu alte cuvinte, trebuie să declaraţi variabila. Acest lucru îl veţi face prin intermediulinstrucţiunii Dim şi a clauzei As Type:

 Dim intNumar   As Integer

Prin linia de cod de mai sus am declarat variabila intNumăr de tip Integer.Atunci când alegeţi numele pentru o variabilă, trebuie să ţineţi cont de următoarelereguli:

• Trebuie să înceapă cu o literă• Poate să conţină doar litere, cifre şi caracterul underscore (_)• Poate avea cel mult 40 de caractere•  Nu poate fi un cuvânt rezervat

Dacă nu v-aţi hotărât de la început ce tip de date va stoca variabiladumneavoastră, o puteţi face ulterior folosind tipul de date Variant.

7.3.2.1 Tipul VariantÎntr-o variabilă de acest tip puteţi stoca text, date numerice sau orice alt tip de

date predefinit în Access. Spre exemplu:

 Dim varOrice As VariantVarOrice = 32VarOrice = varOrice & “ este un numar intreg”

În prima linie de cod declarăm variabila varOrice ca fiind de tipul Variant,apoi îi atribuim valoarea 32. În cea de-a 3-a linie de cod am folosit caracterul & pentrua concatena 32 cu un şir de caractere. Astfel, variabila noastră conţine şirul de

Pag. 103

Page 99: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 99/295

caractere “32 este un numar intreg”. Access a făcut implicit conversia de la tipulîntreg la şir de caractere. Iată un alt exemplu:

varOrice = “2.5”varOrice = varOrice + 10

Cea de-a doua linie de cod va face ca valoarea lui varOrice să fie 12.5, princonversia şirului de caractere “2.5” la numărul real 2.5. Acelaşi efect îl vor avea şiurmătoarele linii de cod:

varOrice = 2.5varOrice = varOrice + “10”

De această dată, şirul “10” va fi convertit la numărul întreg 10.

Atunci când lucraţi cu variabile de tipul Variant, este bine să ştiţiurmătoarele:• Access va converti variabila la tipul de date corespunzător valoriiatribuite;• Atunci când doriţi să concatenaţi două şiruri de caractere, folosiţioperatorul & în loc de +;

Când folosiţi operatorul + pentru lucrul cu variabile de tip Variant, Access va acţionaastfel:

• Dacă ambele valori sunt numerice, se va efectua o adunare;

• Dacă ambele conţin şiruri de caractere, ele vor fi concatenate;

• Dacă una este o valoare numerică şi cealaltă este un şir de caractere,Access va încerca s-o convertească în valoare numerică şi să facăadunarea. Dacă nu reuşeşte, va rezulta o eroare.

Pentru a determina ce tip de date conţine o variabilă de tip Variant la unmoment dat, apelaţi la funcţia predefinită VarType. Aceasta va returna una dintrevalorile prezentate în tabelul 7.3.

Valoareareturnată

Tipul de date Constanta intrinsecă

0 vid (variabila este neiniţializată) vbEmpty1 Null vbNull2 Integer vbInteger  

3 Long vbLong4 Single vbSingle5 Double vbDouble

Pag. 104

Page 100: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 100/295

6 Currency vbCurrency7 Date vbDate8 String vbString9 Object vbObject10 eroare vbError  

11 Boolean vbBoolean12 Variant (numai pentru matrice) vbVariant13 obiect DAO vbDataObject14 Decimal vbDecimal17 Byte vbByte8192 matrice vbArray

Tabelul 7.3

 Notă:  În ultima coloană a tabelului am specificat constanta intrinsecă ce corespunde

valorii returnate. Despre constante intrinseci vom vorbi în secţiunea 7.3.3.

Atunci când o variabilă este declarată, ei i se atribuie valoarea iniţială 0 dacăvariabila e de tip numeric sau “ “ (şirul vid) dacă e de tip şir de caractere. Variabilelor de tip Variant  însă, nu li se atribuie la declarare nici o valoare, cu alte cuvinte sunt“vide” (a nu se confunda aceasta cu valoarea 0 sau “ “ şi nici cu valoarea Null).Aceste variabile rămân vide până în momentul când li se atribuie o valoare. Puteţitesta dacă o variabilă de tip Variant a fost sau nu iniţializată cu ajutorul funcţieiIsEmpty, care returnează valoarea True dacăn variabila este “vidă”. Pentru a “vida”

din nou o variabilă, trebuie să-i atribuiţi ca valoare o altă variabilă de tip Variant carenu a fost încă iniţializată:

 Dim varOrice As Variant‘ acum varOrice este vidavarOrice = 0 ‘s-a atribuit valoarea 0 variabileiIf IsEmpty(varOrice) Then …

‘ am testat daca varOrice este vida (si nu este)Dim VarCeva As VariantvarOrice = varCeva‘ acum varOrice este vida din nou

Notă: În Access, caracterul apostrof (‘) introduce un comentariu într-un modul.

O altă valoare specială pe care o poate avea o variabilă de tip Variant este Null(dacă veţi încerca să atribuiţi valoarea Null unei variabile de orice alt tip decât

Variant, veţi obţine o eroare). Dacă folosiţi valoarea Null într-o expresie, întreagaexpresie va avea valoarea Null. De exemplu:

Pag. 105

Page 101: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 101/295

 Dim varOrice As VariantvarOrice = NullvarOrice = varOrice + 2.5

După cea de-a treia linie de cod, varOrice va avea tot valoarea Null. Dacă

înlocuiţi această linie cu:varOrice = varOrice & “ceva”

varOrice va avea valoarea “ceva”. Deci, operatorul & este singurul care nu propagă valoarea Null într-o expresie.

Puteţi testa dacă o variabilă are valoarea Null cu ajutorul funcţiei IsNull.Variabilele de tip Variant sunt foarte utile, deoarece, pe lângă faptul că nu

trebuie să vă mai bateţi capul cu alegerea unui tip de date, sunt singurul tip de

variabile cărora li se poate atribui valoarea Null. Astfel, dacă unei anumite variabile îiveţi atribui valori dintr-un câmp al unei tabele care poate conţine şi valoarea Null,acea variabilă trebuie să fie de tip Variant. Folosirea acestui tip de variabile are însă şidezavantaje, printre care încetinirea execuţiei aplicaţiei şi chiar posibila apariţiei aunor erori.

7.3.2.2 Option ExplicitSă revenim acum la opţiunea Option Explicit şi să vedem ce se poate întâmpla

în cazul în care nu am stabilit această opţiune în cadrul secţiunii (General) a unui

modul. Pentru aceasta, vom considera următoarea subrutină: Sub AriaCercului (db1Raza As Double)

Dim db1Aria As Doubledb1Aria = 3.14 * db1Raza * db1RazaDebug.Print “Aria = ” & db1Aria

 End Sub

Pentru a rula această subrutină, deschideţi fereastra Debug, apăsând butonulDebug Window de pe bara cu instrumente (fereastra Debug vă va permite să apelaţi procedurile direct, pentru a le putea testa). Scrieţi în partea de jos a ferestrei Debuglinia:

Call AriaCercului (5)

După aceasta, apăsaţi pe Enter şi veţi vedea rezultatul: 0 (figura 7.4). Este clar că acest rezultat este eronat. Motivul este acela că în codul subrutinei s-a strecurat ogreşeală: în loc de db1Raza am scris, într-un loc, db1Rsza. Opţiunea Option Explicitnefiind stabilită, şi deci nefiind necesar ca variabila să fie declarată înainte de a fifolosită, Access a atribuit variabilei db1Raza valoarea implicită 0, care a dus la acestrezultat eronat.

Pag. 106

Page 102: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 102/295

Fig. 7.4

7.3.3 Constante

Constantele sunt tot un fel de variabile, cu deosebirea că nu le puteţi schimbavaloarea. În Access există trei tipuri de constante:• Constante simbolice, create cu ajutorul instrucţiunii Const,• Constante intrinsece,• Constante de sistem: True, False şi Null.

Cu ajutorul constantelor simbolice puteţi da un nume unei valori. Astfel, coduldumneavoastră va fi mai uşor de citit şi de întreţinut. Prin următoarea linie de cod:

Const csPi = 3.14

am definit constanta csPi, a cărei valoare este 3.14. Constantele pot fi folosite oriunde pot fi folosite şi variabilele. Mai mult, ele pot fi folosite la definirea unor constante:

Pag. 107

Page 103: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 103/295

Const csMinut=60

Const csOra=csMinut * 60

Putem atribui şi tipuri de date constantelor, astfel încât Access să le poată

recunoaşte şi să putem efectua diferite operaţii cu ele:Const csPi As Double = 3.14

Constantele intrinsece sunt constnte definite în Access. În tabelul 7.2 aminclus şi coloana “Constanta intrinsecă”, ce conţine numele constantelor ale căror valori sunt returnate de funcţia VarType. Astfel, putem scrie în codul nostru ori:

If VarType (avrOrice) = 2 Then …

Ori

If VarType (avrOrice) = vbInteger Then …

Rămâne la alegerea dumneavoastră care dintre liniile de mai sus este maiclară. În tabelul 7.2 sunt enumerate doar câteva dintre constantele intrinsece definiteîn Access.

7.3.4 Vizibilitatea şi durata de viaţă a variabilelorVizibilitatea unei variabile este dată de porţiunea de cod în care ea poate fifolosită şi depinde de locul în care a fost declarată. Vizibilitatea unei variabile createîn cadrul unei proceduri se reduce doar la acea procedură. O variabilă poate fideclarată şi în afara oricărei proceduri, în cadrul secţiunii (General) (Declarations) aunui modul. În acest caz, ea poate fi folosită de către toate procedurile din

modulul respectiv (şi, uneori, şi din alte module) şi spunem că vizibilitatea sa este publică.

 Durata de viaţă a unei variabilee dată de perioada în care ea va putea

conţine o valoare. Astfel, o variabilă locală a unei proceduri “trăieşte” atâta timp câtse rulează procedura respectivă şi este recreată la următorul apel al procedurii. Dacădoriţi ca o variabilă locală să existe şi după terminarea procedurii, folosiţi cuvântulcheie Static la declararea ei. Putem declara şi o procedură ca fiind statică, astfel încâttoate variabilele sale locale să fie statice.

Variabilele publice există atâta timp cât este deschisă baza de date.În Access 97 puteţi stabili şi vizibilitatea procedurilor, folosind cuvintele cheie

 Public şi Private. O procedură având specificatorul Private poate fi apelată numai dininteriorul modulului în care este declarată, în timp ce o procedură cu specificatorul Public poate fi apelată din orice alt modul.Pentru a putea apela o procedură din fereastra Debug, aceasta trebuie să fie publică.

Pag. 108

Page 104: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 104/295

În exemplele de proceduri pe care le-am prezentat până acum, toate variabileleerau locale şi deci valorile lor se pierdeau după terminarea rulării procedurilor în careerau declarate. În continuare, ne vom ocupa de variabilele statice şi publice.

7.3.4.1 Variabile statice

Pentru ca o variabilă declarată într-o procedură să-şi păstreze valoarea şi întredouă apeluri ale procedurii, ea trebuie să fie declarată folosind cuvântul cheie  Static,în locul lui Dim. O astfel de variabilă va fi iniţializată o singură dată: la primul apel al  procedurii. Pentru a studia mai bine variabilele statice, să considerăm următorulexemplu:

 Sub VarStatic()Static intVar As Integer 

intVar = intVar + 1Debug.Print intVar  End Sub

Pag. 109

Page 105: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 105/295

Rulaţi subrutina de mai multe ori. Rezultatele vor fi cele din figura 7.5.

Fig. 7.5

Dacă intVar nu ar fi fost declarată ca statică, subrutina ar fi tipărit de fiecare datăaceeaşi valoare: 1. Pentru ca toate variabilele unei proceduri să fie statice, folosiţicuvântul cheie Static înaintea declaraţiei procedurii:

Static Sub VarStatic()

7.3.4.2 Variabile publiceExistă două tipuri de variabile publice în Access:

• Variabile publice în cadrul unui modul• Variabile publice în cadrul aplicaţiei

Variabilele publice în cadrul unui modul se declară cu ajutorul instrucţiuniiDim la secţiunea (General) (Declarations) a modulului şi pot fi folosite de către toate procedurile modulului. Următorul exemplu foloseşte astfel de variabile.

1. La secţiunea (Declarations) a unui modul declaraţi variabila intVarModulastfel:

 Dim intVarModul As Integer 

Pag. 110

Page 106: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 106/295

2. Creaţi următoarele două subrutine: Sub Incrementare ()

intVarModul = intVarModul + 1 End Sub

Şi  Sub Tiparire () Debug.Print intVarModul

 End Sub

3. Apelaţi de mai multe ori ambele subrutine din fereastra Debug . Figura 7.6 prezintă rezultatele.

Fig. 7.6

4. Creaţi o a 3-a procedură, în acelaşi modul: Sub LocalVar() Dim intVarModul As Integer IntVarModul = 50 Debug.Print intVarModul End Sub

2. Apelaţi acum subrutina LocalVar şi apoi, din nou, pe Tiparire. În figura7.7 puteţi vedea ce se întâmplă.

 LocalVar lucrează cu variabila intVarModul declarată în interiorul său fără amodifica sau a fi afectată de variabila publică intVarModul, chiar dacă acestea auacelaşi nume.

Pag. 111

Page 107: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 107/295

Fig. 7.7

 Notă:  Pentru a evita confuziile este bine, totuşi, să alegeţi pentru variabilele localenume diferite de cele ale variabilelor publice. 

Variabilele publice în cadrul aplicaţiei pot fi accesate din toate moduleleaplicaţiei, dar pot fi declarate numai în cadrul secţiunii (General) (Declarations) a unuimodul standard. Aceste variabile se declară înlocuind instrucţiunea Dim cuinstrucţiunea Public:

 Public intVarPublic As Integer 

 Nu puteţi declara variabile publice în cadrul procedurilor.

 Notă: Folosiţi variabile publice în cadrul aplicaţiei numai dacă este neapărat nevoie. Astfel vă puteţi feri de erorişi codul dumneavoastră va fi mai uşor de întreţinut şi derefolosit. Dacă veţi dori ca mai multe proceduri să folosească o anumită valoare,daţi-o ca parametru sau ca valoare de retur.

Pag. 112

Page 108: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 108/295

7.4. Instrucţiuni de control

VBA vă oferă posibilitatea de a testa în cadrul procedurilor anumite condiţii şide a efectua operaţii diferite în funcţie de rezultatele testelor. În continuare, vomstudia instrucţiunile VBA care vă permit luarea de decizii în urma unor astfel de teste.

7.4.1 Instrucţiunea If…ThenVeţi folosi această instrucţiune în cazul în care veţi dori să executaţi anumite

operaţii doar dacă o condiţie este adevărată. Ea are două sintaxe. Dacă instrucţiuneaeste folosită pe o singură linie de cod, sintaxa este:

 If conditie Then instructiune

Altfel, dacă instrucţiunea e compusă din mai multe linii de cod:

 If conditie Then  Instructiuni

 End If 

Cea de-a doua variantă este utilă atunci când doriţi să se execute mai multeinstrucţiuni în cazul în care condiţia este adevărată.

Următorul exemplu ilustrează folosirea ambelor variante ale instrucţiunii If…Then:

 Sub TestIfThen (strDat As String, strCautat As String) Dim strRezultat As String If strDat = “” Then strRezultat = “Sirul dat este vid” If InStr (strDat, strCautat) Then

strRezultat = strCautatstrRezultat = strRezultat & “ se afla in “ & strDat

 End If  Debug.Print strRezultat End Sub

Figura 7.8 prezintă două exemple de execuţie a subrutinei TestIfThen.

Pag. 113

Page 109: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 109/295

Fig 7.8

În cadrul subrutinei TestIfThen am folosit o funcţie predefinită în Access, InStr , care verifică dacă un şir de caractere se regăseşte în alt şir şi returnează poziţiala care apare şirul căutat în şirul sursă sau 0 dacă şirul căutat nu se regăseşte în şirulsursă.

Orice expresie poate apărea în cadrul clauzei If . Dacă expresia se evaluează laceva diferit de 0, ea e considerată a fi adevărată, şi falsă dacă valoarea ei este zero.

7.4.2 Instrucţiunea If…Then…ElsePentru a specifica ce operaţii trebuie efectuate în cazul în care condiţia e falsă,

folosiţi aceasta instrucţiune. De exemplu:

 If InStr (strDat, strCautat) Then

strRezultat = strCautat & “ se afla in “ & strDat ElsestrRezultat = strCautat & “ nu se afla in “ & strDat

Pag. 114

Page 110: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 110/295

 End If 

7.4.3 Instrucţiunea ElseIf Puteţi privi această instrucţiune ca pe un mijloc de a imbrica mai multe

instrucţiuni If…Then…Else şi deci, de a verifica mai multe condiţii. Iată un exemplu: If strDat = “” ThenstrRezultat = “Sirul dat este vid”

   ElseIf InStr(strDat, strCautat) ThenstrRezultat = strCautat & “ se afla in “ & strDat ElsestrRezultat = strCautat & “ nu se afla in “ & strDat

 End If 

Astfel, dacă prima condiţie nu e adevărată, se verifică cea de-a doua şi, dacănici aceasta nu e adevărată, se execută instrucţiunea din cadrul clauzei Else. În acestmod puteţi folosi oricâte instrucţiuni EndIf .

7.4.4 Instrucţiunea Select CaseAtunci când trebuie să testaţi mai multe condiţii şi să efectuaţi pentru fiecare

un anumit set de operaţii, folosirea instrucţiunilor  ElseIf  poate să devină greoaie.

Puteţi folosi, în schimb, o instrucţiune Select Case care să facă acelaşi lucru. Astfel,următoarele două secvenţe de cod duc la acelaşi rezultat:

If intVarsta<=18 Then…ElseIf intVarsta>=19 And intVarsta<=25 Then…ElseIf intVarsta>=26 And intVarsta<=40 Then…Else…End If 

Şi

Select Case intVarstaCase Is <=18…Case 19 To 25…Case 26 To 40…

Pag. 115

Page 111: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 111/295

Case Else…End Select

Se poate observa că cea de-a doua variantă este mult mai uşor lizibilă.

Expresiile clauzelor Case se testează în ordinea în care sunt date şi, în momentul încare este întâlnită o expresie adevărată, se vor executa instrucţiunile corespunzătoareşi se va ieşi din instrucţiunea   Select Case. Astfel, dacă expresiile a două dintreclauzele Case sunt adevărate, va fi executat numai codul corespunzător primeia dintreele, nemaifăcându-se apoi nici o verificare.

Instrucţiunea Select Case de mai sus poate fi scrisă şi astfel:

Select Case intVarstaCase Is <=18

…Case 19, 20, 21, 22, 23, 24, 25…Case 26 To 40…Case Else…End Select

Existenţa clauzei Case Else în cadrul unei instrucţiuni  Select Case nu esteobligatorie. Ea poate fi însă utilă în cazul în care variabila testată poate avea şi altăvaloare decât cele cuprinse în clauzele Case.

 Notă: Variabila testată poate conţine atât valori numerice, cât şi şiruri de caractere saudate.

7.4.5 Instrucţiunea IIf (Immediate If)Această instrucţiune este aproape echivalentă cu instrucţiunea  If…Then…

 Else. Spunem “aproape” pentru că există o diferenţă în modul în care sunt executate

cele două instrucţiuni. Iată mai întâi care este sintaxa instrucţiunii IIf : IIf (conditie, valoarea1, valoarea2)Unde:

conditie este condiţia care trebuie să fie testată;valoarea1 este valoarea returnată în cazul în care condiţia e adevărată;valoarea2 este valoarea returnată când condiţia e falsă.

Să considerăm acum următoarele două funcţii:

Function Impartire(intImpartitor As Integer, intDeimp As Integer) As_ Double If intImpartitor = 0 Then

Pag. 116

Page 112: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 112/295

Impartire = 0 ElseImpartire = intDeimp /intImpartitor  End If  End Function

Şi

Function Impartire(intImpartitor As Integer,intDeimp As Integer) As_ DoubleImpartire = IIf (intImpartor = 0, 0, intDeimp /intImpartitor) End Function

Aparent, cele două funcţii fac acelaşi lucru. Diferenţa constă în faptul că în prima funcţie, dacă este îndeplinită condiţia instrucţiunii IIf , se execută instrucţiuneaImpartire = 0 şi se iese din instrucţiunea If…Then…Else fără alte verificări. Îninstrucţiunea IIf din cea de-a doua funcţie se evaluează însă toate argumentele. Astfel,dacă intImpartitor = 0, la evaluarea lui intDeimp /intImpartitor va rezulta o eroare.

Faptul că în instrucţiunea IIf  se evaluează toate argumentele, nu numai căîncetineşte execuţia procedurii, dar poate duce şi la erori.

7.5 Instrucţiuni iterativeExistă situaţii, foarte des întâlnite în programare, când un anumit bloc deinstrucţiuni trebuie să fie executat de mai multe ori. Pentru astfel de operaţii, VBA vă pune la dipoziţie instrucţiunile For…Next  şi  Do…Loop, despre care vom vorbi încontinuare.

7.5.1 Instrucţiunea For…NextAceastă instrucţiune este utilă atunci când ştiţi precis câte iteraţii aveţi de

efectuat. Sintaxa ei este:

For contor = val_initiala To val_finala [Step pasul]… Next [contor]

Unde:

Pag. 117

Page 113: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 113/295

• contor – este variabila care se incrementează la fiecare iteraţie• val_initiala – valoarea iniţială a variabilei contor • val_finala – valoarea finala a variabilei contor • pasul – valoarea cu care se incrementează variabila contor la fiecareiteraţie.

Valoarea implicită a pasului este 1. Pasul poate fi şi negativ, caz în carevariabila contor va descreşte la fiecare iteraţie cu valoarea absolută a pasului.

For intCont = 1 To intTotal Step2 Debug.Print intCont Next 

În exemplul de mai sus, valoarea iniţială a contorului intCont este 1 şi la

fiecare pas această valoare creşte cu două unităţi, până când se egalează valoareavariabilei intTotal. De asemenea, la fiecare iteraţie se va afişa valoare lui intCont.

7.5.2 Instrucţiunea Do…LoopPentru cazurile în care cunoaşteţi dinainte numărul de iteraţii ce trebuie

efectuate, instrucţiunea For…Next este ideală. Sunt însă şi situaţii în care un set deinstrucţiuni trebuie să se execute până când sau atâta timp cât o anumită condiţie estesatisfăcută. În astfel de cazuri, veţi folosi instrucţiunea  Do…Loop, care are

următoarele sintaxe: Do Until conditie

 bloc de instructiuni Loop

Sau:

 Do bloc de instructiuni

 Loop Until  conditie

Sau:

 Do While conditie bloc de instructiuni

 Loop

Sau:

Pag. 118

Page 114: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 114/295

 Do bloc de instructiuni

 Loop While conditie

Primele variante ale instrucţiunii Do…Loop

execută blocul de instrucţiuni până când condiţia va deveni adevărată (adică atâta timp cât ea este falsă). Deosebireadintre ele este aceea că în cea de-a doua variantă blocul de instrucţiuni se execută cel puţin o dată. Ultimele două variante execută blocul de instrucţiuni

atâta timp cât condiţia e adevărată, cu deosebirea că, în cazul ultimei variante, bloculde instrucţiuni se execută cel puţin o dată.

7.5.3 Întreruperea iterăriiAtât în cazul instrucţiunii For…Next , cât şi în cel al instrucţiunii  Do…Loop,

ştim când anume se va opri procesul iterativ. VBA vă dă însă şi posibilitatea de aîntrerupe acest proces la o anumită iteraţie, cu ajutorul instrucţiunii Exit . De exemplu:

For intCont = 1 To intTotal   If intStop Then

Exit For End If 

 Debug.Print intCont Next 

Dacă intStop este diferit de zero, procesul iterativ se opreşte, indiferent devaloarea lui intCont.

În mod asemănător, pentru a părăsi o subrutină sau o funcţie, puteţi folosiinstrucţiunile Exit Sub sau Exit Function.

7.6 MatriceO matrice poate fi privită ca o mulţime de variabile de acelaşi tip, având

aceleaşi nume şi care stochează informaţii similare. Fiecărei variabile ce compunematricea îi corespunde un indice (un număr de ordine). Dacă numărul de elemente alematricei a fost specificat la declarare, matricea se numeşte  statică; altfel, ea senumeşte dinamică.

7.6.1 Matrice staticeDupă ce aţi fixat un număr de elemente la declararea matricei, acesta nu mai

 poate fi schimbat pe parcurs. Matricele statice se declară astfel:

Pag. 119

Page 115: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 115/295

 Dim nume_matrice (ip To iu) As tip_de_date

Unde:nume_matrice – este identificatorul (numele) matriceiip – este indicele primului element

iu – este indicele ultimului elementtip_de_date – este tipul datelor stocate în matrice.

 Notă: Nu confundaţi matricele statice cu variabilele statice. Repetăm faptul că ovariabilă statică e o variabilă declarată cu ajutorul cuvântului cheie Static şi îşi păstrează valoarea şi după terminarea procedurii în care a fost declarată, iar o

matrice statică este o matrice al cărei număr de elemente a fost specificat ladeclarare.La rândul lor, matricele statice pot fi declarate, asemeni variabilelor, cu

ajutorul instrucţiunilor  Dim, Static, Private sau Public.În continuare, vă prezentăm o subrutină ce ilustrează folosirea matricelor 

statice:

 Sub MatriceStat () Dim i As Integer 

 Dim iMatrice (1 To 5) As Integer iMatrice (1) = InputBox (“Introduceti primul element”, “Matrice”)For i = 2 To 5iMatrice (i) = InputBox (“Introduceti al “ & i & ”-lea element”, “Matrice”) Next i Debug.Print “Primul element este “ & iMatrice(1)For i = 2 To 5 Debug.Print “All “ & i & “-lea element este “ & iMatrice(i) Next i

 End SubRulaţi subrutina (apelând-o de la fereastra Debug). Vor apărea întâi cinci cutii

de dialog care vă vor cere să introduceţi câte un element, apoi elementele introdusevor fi afişate ca în figura 7.9.

Pag. 120

Page 116: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 116/295

Fig 7.9

Observaţi că am folosit funcţia predefinită InputBox, care afişează o cutie dedialog ce permite utilizatorului să introducă o valoare, pe care funcţi o returnează.

Pag. 121

Page 117: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 117/295

Astfel, după ce fiecare element al matricei a primit câte o valoare introdusă deutilizator, matricea este parcursă cu ajutorul instrucţiunii iterative For…Next, pentru aafişa valorile stocate.

Indici

 Nu este obligatoriu ca indicele primului element al unei matrici să fie 1; el poate fi orice număr întreg, de exemplu:

 Dim iMatrice(5 To 14) As Integer 

este declaraţia unei matrice de 10 elemente numere întregi.Dacă nu specificaţi indicele primului element al unei matrici, Access va

considera în mod implicit că acesta e zero. Astfel, următoarele două declaraţii suntechivalente:

 Dim iMatrice(9) As Integer şi Dim iMatrice(0 To 9) As Integer 

Dacă veţi dori ca indicele implicit al primului element să nu fie 0, ci un altul(1, de exemplu), introduceţi la secţiunea (Declarations) a modulului următoarea liniede cod:

Option Base 1

7.6.2 Matrice dinamiceDacă nu cunoaşteţi de la început numărul de elemente pe care trebuie să le

aibă o matrice, puteţi să o declaraţi ca fiind dinamică. Astfel de matrice se declară totcu ajutorul instrucţiunilor Dim, Static, Private sau Public, dar punând două parantezerotunde după numerele matricei. Apoi, cu ajutorul instrucţiunii ReDim, puteţi fixaindicii primului şi ultimului element al matricei.

În continuare, vom modifica exemplul anterior astfel încât utilizatorul să poatăintroduce numărul de elemente ale matricei.

 Sub MatriceDin() Dim i As Integer  Dim iTot As Integer  Dim iMatrice() As Integer ITot = InputBox (“Introduceti numarul total de elemente”) ReDim iMatrice(1 To iTot)iMatrice(1) = InputBox (“Introduceti primul element”, “Matrice”)For i = 2 To iTotiMatrice(1) = InputBox (“Introduceti al “ & i & “-lea element”, “Matrice”) Next i Debug.Print “Primul element este “ & iMatrice(1)

Pag. 122

Page 118: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 118/295

For i = 2 To iTot Debug.Print “Al “ & i & “-lea element este “ & iMatrice(i) Next i End Sub

După ce aţi specificat, cu ajutorul instrucţiunii  ReDim, indecşii primului şiultimului element al matricei, puteţi folosi din nou instrucţiunea  ReDim pentru amodifica aceşti indecşi (şi deci, dimensiunea totală a matricei). În mod normal,modificând aceşti indecşi se vor pierde valorile stocate de elementele matricei. Pentrua preveni acest lucru, folosiţi cuvântul cheie  Preserve. Astfel, dacă declarămurmătoarea matrice:

 Dim iMatrice () As Integer …

 ReDim iMatrice (1 To 10)şi dorim ulterior să reducem la cinci elemente fără a pierde valorile primelor 5, vomscrie:

 ReDim Preserve iMatrice (1 To 5)

7.6.3 Detectarea matricelor

Există trei funcţii care ne ajută să aflăm dacă o variabilă este simplă sau este omatrice: IsArray, VarType şi TypeName.Funcţia IsArray returnează valoarea True dacă variabila care îi este dată drept

argument este o matrice şi False dacă nu.Despre funcţia VarType am mai vorbit şi în secţiunea 7.3.2, unde am dat şi

tabelul cu valorile pe care aceasta le poate returna. Aţi putut observa în acel tabel căunei variabile de tip matrice îi corespunde valoarea de retur 8192 (sau constantaintrinsecă vbArray). Astfel, dacă variabila dată ca argument funcţiei VarType este omatrice, funcţia va avea ca valoare de retur 8192 plus valoarea corespunzătoare tipuluivariabilelor ce compun matricea.

 Sub TestMatrice() Dim iNum As Integer  Dim iMatrice (1 To 10) As Integer  Debug.Print “iNum: “ & VarType(iNum) Debug.Print “iMatrice: “ & VarType(iMatrice) End Sub

Pag. 123

Page 119: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 119/295

Dacă veţi rula subrutina Test Matrice, în fereastra Debug vor apărea valorile 2şi 8194, ca în figura 7.10.

Fig 7.10

Observaţi că pentru variabila iMatrice, funcţia VarType a returnat valoarea8194, adică 8192 pentru matrice, plus 2 pentru tipul Integer (care e tipul elementelor matricei).

Funcţia TypeName se aseamănă cu VarType, cu diferenţa că în locul valorii

corespunzătoare unui tip de date, ea returnează chiar numele tipului respectiv. Spreexemplu, următoarea subrutină:

 Sub TestMatrice1 () Dim iNum As Integer  Dim iMatrice (1 To 10) As Integer  Debug.Print “iNum: “ & TypeName (iNum) Debug.Print “iMatrice: “ & TypeName (iMatrice)

 End Subva da rezultatele din figura 7.11.

Pag. 124

Page 120: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 120/295

Figura 7.11

7.6.4 Matrice multidimensionalePână acum am vorbit numai despre matrice unidimensionale, numite şi

vectori. Matricele pot avea însă şi două, trei sau mai multe dimensiuni.Pentru a declara o matrice multidimensională, trebuie să specificaţi marginile

inferioare şi superioare ale indicilor pentru fiecare dimensiune, separate prin virgulă.Astfel, pentru a declara o matrice bidimensională cu 6 elemente şi cu indicii începândde la 1, scrieţi:

 Dim iMatrice(1 To 2, 1 To 3) As Integer 

sau, pentru o matrice de aceeaşi dimensiune dar cu indicii începând de la 0(presupunând că nu s-a specificat opţiunea Option Base 1):

 Dim iMatrice(1, 2 ) As Integer 

 Notă: Teoretic, numărul maxim de dimensiuni ale unei matrici este 60. Practic, însănu veţi folosi matrice cu mai mult de patru dimensiuni, deoarece ar fi foarte greu delucrat cu ele.

7.6.4.1 Matrice multidimensionale dinamice

Ca şi cele unidimensionale, matricele multidimensionale pot fi declarate cafiind dinamice, pentru ca numărul dimensiunilor şi marginile fiecărei dimensiuni să poată fi stabilite ulterior. Sintaxa este următoarea:

Pag. 125

Page 121: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 121/295

 Dim iMatrice() As Integer … ReDim iMatrice(1 To 2, 1 To 3)

Sau, pentru ca indicii matricei să înceapă de la 0: Dim iMatrice() As Integer … ReDim iMatrice(1, 2)

O astfel de matrice are 2x3 = 6 elemente. Similar, prin instrucţiuneaurmătoare:

 ReDim iMatrice(1, 2, 3)matricea va fi tridimensională şi va conţine2x3x4=24 de elemente.

7.6.4.2 Accesarea componentelor unei matrice multidimensionalePentru a accesa un element al unei matrice multidimensionale, trebuie să

specificaţi indicii corespunzători fiecărei dimensiuni a matricei, ce caracterizeazăelementul respectiv. Următoarea subrutină declară o matrice bidimensională şi o

umple cu anumite valori, pe care apoi le afişează. Fiecărui element al matricii îi vomda ca valoare suma indicilor care îi corespund.

 Sub Matrice() Dim i As Integer  Dim j As Integer ‘ crearea matricei dinamice Dim iMat() As Integer ‘ redimensionarea matricei ReDim iMat(1 To 2, 1 To 3)For i = 1 To 2

For j = 1 To 3

iMat (i, j) = i+jNext 

 Next For i = 1 To 2  For j = 1 To 3

 Debug.Print  i & “ + “ & j & “ = “ & iMat(i, j)

Pag. 126

Page 122: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 122/295

Next  Next  End Sub

Rulând subrutina de mai sus, veţi obţine rezultatele din figura 7.12.

Fig. 7.12

7.6.5 Ştergerea matricelor dinamiceO matrice ocupă în memorie 20 de octeţi, plus câte 4 octeţi pentru fiecare

dimensiune, plus numărul de octeţi necesari datelor stocate, adică numărul deelemente ale matricei înmulţit cu numărul de octeţi ocupaţi de tipul respectiv de date.

Astfel, matricea iMatrice (1, 2, 3) ocupă în memorie:

20 octeţi + 3x4 octeţi + (2x3x4)x2 octeţi = 80 octeţi.Pag. 127

Page 123: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 123/295

Pentru a elibera memoria ocupată de o matrice dinamică, puteţi folosiinstrucţiunea Erase astfel:

Erase iMatrice

Folosită pentru matrice statice, instrucţiunea Erase le va reiniţializa, fără săelibereze memoria ocupată de acestea.

7.6.6 Folosirea matricelor ca parametri pentru proceduriAccess vă permite să daţi şi matrice ca parametri funcţiilor şi subrutinelor. Un

 paametru-matrice (sau matrice de parametri) vă dă posibilitatea de a crea proceduri cuun număr variabil de parametri.

De exemplu, următoarea funcţie calculează media aritmetică a numerelor ce îi

sunt date ca parametri:Function Media (ParamArray aNum() ) As Double Dim valCrt Dim dblSuma As DoubleFor Each valCrt In aNum

dblSuma = dblSuma + valCrt Next  Media = dblSuma / (UnBound (aNum) + 1)

 End FunctionDacă în fereastra Debug scrieţi:

?Media (1,2,3,4,5)

şi apăsaţi tasta Enter, veţi obţine rezultatul 3.

Iată trei lucruri esenţiale pe care trebuie să le aveţi în vedere când lucraţi cu parametri de tip matrice:

• Pentru a declara o matrice ca parametru al unei proceduri, precedaţi-ocu cuvântul cheie ParamArray.• Un parametru de tip matrice poate apărea doar pe ultima poziţie în listade parametri ai unei proceduri.• Matricele de parametri pot fi numai de tipul Variant.

Funcţia  Media calculează întâi suma tuturor elementelor matricei de parametri, pe care o împarte apoi la numărul total de elemente.

 Notă: Indicii matricelor de parametri încep întotdeauna de la zero, indiferent dacă înmodulul ce conţine procedura aţi specificat sau nu opţiunea Option Base 1.

Pag. 128

Page 124: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 124/295

Funcţia predefinită Ubound returnează valoarea celui mai mare indice al uneimatrice. Cum indicii matricei de parametri aNum încep de la 0, numărul total deelemente este Ubound(aNum) + 1.

7.7 Lucrul cu biblioteci DLL şi cu funcţii Windows APIVom vorbi în continuare despre una dintre cele mai importante

facilităţi oferite de VBA: posibilitatea de a apela un DLL (Dynamic Link Library)dintr-o procedură VBA. Astfel, puteţi realiza mai mult decât vă permit funcţiile predefinite şi instrucţiunile VBA: puteţi controla sistemul de operare Windows.

Windows vine cu mai multe biblioteci DLL, ce conţin sute de funcţiiutile pentru programatori. Aceste funcţii formează ceea ce poartă numele de WindowsAPI (prescurtarea API vine de la Application Programming Interface, adică interfaţa

de programare a aplicaţiilor Windows).Dar ce este, de fapt, un DLL? Este un fişier sursă ce conţine un număr mare de funcţii (o bibliotecă de funcţii). Programatorul poate folosi o funcţie DLLîntr-un program de-al său fără ca acel program să conţină o copie a funcţiei respective.Indiferent de numărul aplicaţiilor ce apelează funcţii dintr-un DLL la un moment dat, biblioteca DLL se încarcă în memorie o singură dată, şi anume, prima oară când s-aapelat o funcţie din el. Apoi, după ce aplicaţiile nu mai au nevoie de funcţiile sale, biblioteca DLL este descărcată din memorie.

7.7.1 Declararea funcţiilor APIÎnainte de a putea apela o funcţie dintr-un DLL, trebuie să-I daţi indicaţii lui

Access unde se află funcţia şi cum anume să o apeleze. Acest lucru îl realizaţi cuajutorul instrucţiunii  Declare, incluzând practic o declarare a funcţiei la secţiunea(General) (Declarations) a modului în care se face apelul. Printr-o astfel de declaraţie,VBA primeşte şase informaţii:

• Domeniul de vizibilitate al funcţiei;•  Numele pe care îl veţi folosi în codul dumneavoastră pentru a apela

funcţia;•  Numele şi calea bibliotecii DLL care o conţine;•  Numele funcţiei, aşa cum este ea definită în DLL;•  Numele şi tipul argumentelor;• Tipul valorii returnate (dacă aceasta există).

Dacă funcţia returnează o valoare, sintaxa instrucţiunii Declare este:

[Public | Private] Declare Function denumireaFunctiei_ Lib “numeleBibliotecii” [Alias “numeleDinDLLAlFunctiei”]_ 

Pag. 129

Page 125: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 125/295

[([argumente])] [As tip]

iar dacă funcţia nu returnează nici o valoare:

[Public | Private] Declare Sub denumireaFunctiei_ Lib “numeleBibliotecii” [Alias “numeleDinDLLAlFunctiei”]_ [([argumente])]

7.7.1.1 Domeniul de vizibilitate al funcţiei APICa şi în cazul unei proceduri VBA obişnuite, puteţi stabili vizibilitatea

funcţiilor declarate prin intermediul instrucţiunii  Declare. Astfel, dacă instrucţiunea Declare e precedată de cuvântul cheie Private, funcţia API nu va fi apelată decât dinmodulul în care a fost declarată. Dacă folosiţi cuvântul cheie Public (care e şiimplicit), funcţia va putea fi apelată din orice modul.

7.7.1.2 Denumirea funcţiei APIÎn cadrul instrucţiunii Declare trebuie să specificaţi şi denumirea pe care o veţi

folosi în codul dumneavoastră pentru a apela funcţia API respectivă. Aceastădenumire trebuie să respecte regulile impuse pentru orice procedură VBA: să înceapăcu o literă, să conţină numai caractere alfanumerice sau caracterul underscore(_), săfie unicîn cadrul domeniului său de vizibilitate, să conţină maximum 255 de caractereşi să nu fie un cuvânt cheie VBA. Dacă nu folosiţi clauza Alias pentru a specificanumele din DLL al funcţiei, denumirea trebuie să fie exact aceeaşi cu acest nume dinDLL.

7.7.1.3 Specificarea bibliotecii DLLÎn cadrul clauzei Lib a instrucţiunii Declare trebuie să specificaţi, între

ghilimele, numele bibliotecii DLL şi, eventual, locaţia sa pe disc. Dacă bibliotecaDLL este una dintre principalele biblioteci DLL din Windows, puteţi omiteextensia .DLL (de exemplu, “User32”, “GDI32” sau “Kernel32”). Dacă nu specificaţicalea completă pentru DLL, Windows îl va căuta în ordine:

1. în directorul în care se află Access;2. în directorul curent;3. numai pentru Windows NT: în directorul Windows\System32;4. în directorul Windows\System;5. în directorul Windows;6. în directoarele din PATH.

7.7.1.4 Clauza AliasClauza Alias a instrucţiunii Declare că permite să schimbaţi numele unei

funcţii API din cel specificat în DLL într-unul permis în VBA. Astfel, dacă aţispecificat o altă denumire pentru funcţie decât cea dată în DLL, trebuie să includeţi în

Pag. 130

Page 126: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 126/295

instrucţiunea Declare şi clauza Alias, care să conţină numele exact al funcţiei. Deexemplu, pentru a declara funcţia API_lwrite(), trebuie să folosiţi un alias, deoarece înVBA numele funcţiilor nu pot începe cu caracterul underscore(_):

Declare Function lwrite Lib “Kernel32” Alias “_lwrite” _ 

(ByVal hFile As Integer, ByVal lpBuffer As String, ByVal intBytes_ As Integer) As Integer

Astfel, pentru a apela în codul dumneavoastră funcţia_lwrite() dinKernel32.DLL, veţi folosi denumirea lwrite().

7.7.1.5 ArgumenteÎn mod implicit, Access dă unei proceduri, ca argumente, pointeri la adresa de

memorie a variabilelor şi nu valorile explicite ale acestora. Cu toate acestea, multefuncţii API aşteaptă să primească drept argumente valorile variabilelor şi nu pointerila adresele lor. În acest caz, trebuie să daţi şi dumneavoastră acestor funcţii, caargumente, tot valori şi acest lucru îl realizaţi plasând cuvântul cheie ByVal în faţanumelor argumentelor funcţiei din cadrul instrucţiunii Declare:

Declare Function GetSystemMetrics Lib “user32” (ByVal nIndex_ As Long) As Long

Şiruri de caractere ca argumenteMulte funcţii API primesc ca argumente şiruri de caractere ce se termină cucaracterul ‘\0’ (al cărui cod ASCII este 0). VBA nu lucrează cu astfel de şiruri decaractere. De aceea, pentru a putea da un şir VBA ca argument unei funcţii dintr-unDLL, trebuie întâi să-l transformaţi într-un şir de caractere ce se termină cu ‘\0’. Totcuvântul cheie ByVal vă ajută şi de această dată. Astfel, dacă folosiţi acest cuvântcheie pentru un argument de tip String, VBA îl converteşte într-un şir terminat cu ‘\0’şi apoi îi dă funcţiei API respective un pointer la adresa de memorie a şirului. Deşiacest fapt vine în contradicţie cu ce am spus până acum, el se aplică totuşi şirurilor înVBA.

Dacă o funcţie dintr-un DLL primeşte ca argument valoarea unei variabile, eanu va putea modifica efectiv această valoare. Dacă însă funcţia primeşte adresa dememorie a variabilei, atunci ea îi poate modifica valoarea. Cum aceasta se întâmplă şiîn cazul şirurilor de caractere, pot apărea probleme. Dacă funcţia din DLL modificăvaloarea şirului de caractere primit ca argument şi noua valoare conţine mai multecaractere, funcţia nu modifică şi dimensiunea şirului. Ea scrie noul şir la adresarespectivă, suprascriind caracterul ‘\0’ şi ocupând în continuare locaţii de memorieadiacente. Acest fapt poate duce la blocarea aplicaţiei şi chiar a sistemului. Pentru a-levita, trebuie să vă asiguraţi că şirul pe care-l daţi funcţiei ca

Pag. 131

Page 127: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 127/295

argument este suficient de mare pentru a putea păstra valorile pe care aceasta i le vaatribui. Puteţi folosi în acest scop un şir de caractere de lungime fixă, suficient demare:

Dim strSir As String* 255

Matrice ca argumentePuteţi da ca argumente unei funcţii API elementele unei matrici aşa cum i-aţi

da orice altă variabilă. Pentru a face acest lucru, pur şi simplu daţi funcţiei caargument primul element al matricei. Funcţia va şti să regăsească şi celelalteelemente. Deoarece elementele unei matrice se află la locaţii consecutive de memorie,este suficient ca funcţia să ştie unde începe matricea şi dimensiunea ei. Nu puteţi da caargument unei funcţii dintr-un DLL.

Transformarea tipurilor de date ale argumentelorDeoarece majoritatea bibliotecilor DLL sun scrise în C sau C++, tipurile dedate ale argumentelor funcţiilor pe care acestea le conţin nu sunt aceleaşi cu tipurilede date VBA. De aceea, e necesar să folosim în instrucţiunea Declare tipul de dateVBA corespunzător tipului C al argumentului funcţiei din DLL. Tabelul 7.13 aratăcorespondenţele dintre tipurile date din limbajul C şi tipurile VBA.

Tip de date în C Corespondent în VBAATOM, BOOL, HFILE, int, UINT, WORD,

WPARAM

ByVal i As Integer 

int FAR*, UINT FAR* i As Integer  BYTE ByVal byt As ByteBYTE* byt As ByteCALLBACK, DWORD, FARPROC,HACCEL, HANDLE, HBITMAP,HBRUSH, HGLOBAL, HICON,HINSTANCE, HLOCAL, HMENU,HMETAFILE, HMODULE, HPALETTE,

HPEN, HRGN, HRSRC, HTASK, HWND,LONG, LPARAM, LRESULT

ByVal adr As Long

Char*, LPSTR, LPCSTR ByVal str As StringTabelul 7.13

Tipuri-utilizatorMulte funcţii API primesc argumente ce au ca tip de date alte tipuri decât cele

 predefinite. Acestea se numesc tipuri de date definite de utilizator sau tipuri-utilizator.Un tip-utilizator poate fi o structură în C, adică un mod de a grupa variabile de tipuridiferite şi care împreună definesc un nou concept. Una dintre structurile cel mai des

Pag. 132

Page 128: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 128/295

folosite în bibliotecile DLL este structura RECT, ce reprezintă un dreptunghi prindistanţele laturilor sale faţă de marginea din stânga şi, respectiv, de sus a ecranului.

Type RECTleft As Long

top As Longright As Longbottom As Long

 End Typeeste tipul VBA corespunzător structurii RECT în C.

Argumentele ce au ca tip de date un tip-utilizator sunt date prin referinţă (adică prin intermediul unui pointer la adresa din memorie a unei variabile de acel tip).

Pointeri nuliExistă şi cazuri când o funcţie API aşteaptă ca argument pointerul nul, care în

VBA este dat ca:ByVal 0&

unde caracterul & arată faptul că pointerul este pe 32 de biţi (adică Long). Observaţifaptul că pointerul nul trebuie dat ca argument prin valoare.De exemplu, funcţia API ClipCursor (pe care o vom folosi în Exemplul 2) are

argumentul: lpRect As AnyDacă ea primeşte ca argument un pointer la o variabilă de tip RECT, atunci

cursorul va fi capturat în dreptunghiul definit de acea variabilă. Dacă primeşte caargument pointerul nul, ea eliberează cursorul.

Tipul Any este folosit pentru a dezactiva mecanismul Access de verificare acorespondenţei dintre tipurile argumentelor din declaraţia unei funcţii şi tipurileargumentelor efective, astfel încât funcţia poate primi orice tip de date pentru unargument de tip Any.

Notă: Atunci când lucraţi cu funcţii DLL, este bine să faceţi regulat copii ale bazei dedate. Este de asemenea bine să salvaţi orice alte informaţii din alte aplicaţii Windowsdeschise, deoarece este posibil ca, din cauza unor erori generate de aceste funcţii, sistemul să se blocheze şi să pierdeţi informaţiile nesalvate.

Pag. 133

Page 129: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 129/295

CAP:8. Lucrul cu obiecte

Unul dintre motivele principale ale apariţiei programării orientate pe obiecteeste nevoia de a modela cât mai bine fenomenele şi entităţile din lumeaînconjurătoare. O maşină, o casă, un calculator – toate acestea sunt obiecte, care larândul lor conţin diferite părţi componente – obiecte şi ele. Caracteristica cea maiimportantă a obiectelor este aceea că ele conţin toate informaţiile necesare pentru a

funcţiona. În Access 97, un formular este un obiect. El ştie tot ce trebuie pentru a-şiface datoria. De exemplu, dacă apăsaţi butonul Cnacel, formularul se închide; dacăapăsaţi butonul Minimize din bara de titlu, formularul se minimizează etc.

Astăzi întâlnim obiecte în mai toate domeniile programării: programareobiectuală sistem, sisteme de gestiune a bazelor de date orientate pe obiecte,  programare obiectuală în proiectare, jocuri orientate obiectual, peste tot, numai programare obiectuală. Şi toate acestea se datorează avantajelor pe care aceasta leoferă faţă de limbajele procedurale tradiţionale:• Eficienţă mai mare datorată posibilităţii de a refolosi cantităţi însemnate de cod

din alte aplicaţii, de unde rezultă şi creşterea complexităţii şi calităţii aplicaţiilor;• Posibilitatea de a accesa date stocate pe platforme şi sisteme diferite;• Posibilitatea de a oferi utilizatorilor metode grafice intuitive şi prietenoase de

comunicare cu sistemul.În continuare, vom explica termenii cheie ce apar atunci când vorbim de

obiecte.

ProprietăţiToate obiectele au ca proprietăţi ce le caracterizează. Aşa cum o maşină se

caracterizează prin marcă, model, culoare şi o groază de caracteristici tehnice, înAccess 97 un formular are şi el o mulţime de proprietăţi, cum ar fi: titlul (Caption),filtrul (Filter) etc.

Proprietăţile unui obiect pot fi modificate fie cu ajutorul paginii de proprietăţiîn modul Design View, fie prin intermediul limbajului VBA.

MetodeMetodele reprezintă modul în care un obiect efectuează diferite acţiuni. Aşa

cum o maşină ştie ce metodă să aplice pentru a frâna atunci când şoferul apasă pedala

de frână, în Access 97 obiectul bază de date ( Database) are o metodă pentru a crea unnou set de înregistrări (OpenRecordset ).

Pag. 134

Page 130: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 130/295

ClaseO clasă reprezintă mulţimea tuturor obiectelor care au aceleaşi proprietăţi şi

metode. Un obiect al unei clase poartă numele de instanţă a clasei respective. O clasă poate avea mai multe subclase (sau clase derivate) care moştenesc proprietăţile şimetodele clasei de bază dar, pe lângă acestea, mai au şi propriile lor proprietăţi şi

metode, ce le particularizează.

8.1 Obiectele din Access 97În Access există două seturi de obiecte: obiectele Access generale (prezentate

în tabelul 8.1) şi obiecte pentru accesarea datelor (Data Access Objects sau, pe scurt,DAO), prezentate în tabelul 8.2.

Obiect Access DescriereApplication Obiectul Microsoft AccessControl  Un control de pe un formular sau raport DoCmd  Acţiuni în VBA Debug  Fereastra Debug Form Un formular sau subformular deschis Module Un modul Report  Un raport sau subraport deschisScreen Ecranul

Section O secţiune a unui formular sau raport Pages Paginile unui control References Referinţe la alte biblioteci de obiecte

Tabelul 8.1

Obiect DAO DescriereContainer Un obiect care conţine informaţii despre alte obiecte

 Database O bază de date deschisă

 DBEngine Motorul bazei de date Document  Informaţii pe care motorul bazei de date le

administrează, despre alte obiecte Error  Erori generate de accesarea datelor Group Un cont al unui grup de utilizatori Index Un index pe o tabelă Parameter  Un parametru al unei interogări Property Proprietatea unui obiectQueryDef  O interogare salvată Recordset  Un set de înregistrări definit de o tabelă sau

interogare

Pag. 135

Page 131: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 131/295

 Relation O relaţie între două tabele sau interogăriTableDef  O tabelă salvatăUser  Contul unui utilizator Workspace O sesiune de lucru cu o bază de date

Tabelul 8.2

În continuare, vom vorbi mai pe larg despre obiectele DAO şi despre cum se folosescele.

8.1.1 ColecţiiÎn tabelul 8.2 aţi văzut că o bază de date este un obiect care conţine, la rândul

său, alte obiecte. În mod asemănător, formularele conţin controale, iar tabelele,câmpuri. Obiectele care sunt conţinute într-un alt obiect sunt grupate în colecţii.

Colecţiile pot fi formate numai din obiectele aceleiaşi clase. Astfel, dacă un obiectconţine mai multe formulare, acestea vor forma colecţia Forms (formulare) aobiectului respectiv. O colecţie poate fi deci considerată ca fiind un vector. Figura 8.3 prezintă obiectele DAO sub forma unei diagrame ierarhice ce arată legăturile dintreobiecte şi colecţiile lor.

Figura 8.3

Pag. 136

Page 132: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 132/295

În vârful ierarhiei se află DBEngine (motorul bazei de date). El conţine douăcolecţii: Errors şi Workspaces (erori şi sesiuni de lucru). În Workspace este ca un birou al unei clădiri, clădirea fiind motorul DBEngine. Colecţia Errors conţine o listăcu erorile apărute în DBEngine.

Aproape toate acţiunile dumneavoastră sunt procesate de motorul DBEngine şi

sunt efectuate asupra unui obiect DAO. De aceea, este foarte important să înţelegeţi cesunt obiectele pentru accesarea datelor şi care sunt relaţiile dintre ele. Pentru aceasta,vom folosi în continuare fereastra Debug care ne va ajuta să vedem obiectele stocateîn baza noastră de date şi cum sunt ele organizate în ierarhia DAO.

1. Creaţi un nou modul standard în baza de date curentă (CursuriOptionale.mdb). Deschideţi fereastra Debug şi scrieţi în ea:

?DBEngine.Workspaces(0).NameDupă ce aţi apăsat tasta Enter, veţi primi următorul rezultat:

#Default Workspace# (adică sesiunea de lucru implicită).

Prin linia de cod scrisă mai sus aţi cerut numele unei sesiuni de lucru. Obiectul

 DBEngine, care se află în vârful ierarhiei DAO, conţine două colecţii: Workspaces şiErrors. Colecţia Workspaces este, de fapt, o matrice ale cărei elemente sunt obiecte detip Workspace. Astfel, DBEngine.Workspaces(0).Name înseamnă “proprietatea Name(nume) a elementului cu indicele 0 al colecţiei Workspaces a obiectului DBEngine”.

2. Să coborâm pe o treaptă inferioară a ierarhiei, cerând numele bazei de datecurente. Pentru aceasta, introduceţi în fereastra Debug:

?DBEngine.Workspaces(0) . Databases(0) .Name

Pag. 137

Page 133: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 133/295

După ce apăsaţi tasta Enter, rezultatul va fi calea completă şi numele fişieruluiîn care se află baza de date curentă.

Fiecare obiect de tip Workspace conţine trei colecţii: Users (utilizatori), Gorups(grupuri) şi Databases (baze de date) care, la rândul lor pot fi privite ca matrice(vectori). Prin linia de cod de mai sus aţi cerut, aşadar numele obiectului de tipDatabase cu indicele 0 din cadrul colecţiei Databases a obiectului Workspaces(0) alobiectului DBEngine.

3. Mai coborâm o treaptă a ierarhiei şi cerem numele unui obiect al uneicolecţii a obiectului, DBEngine.Workspaces(0) .Databases(0), şi anume:

?DBEngine.Workspaces(0).Databases(0).TableDefs(0).Name

TableDefs(0) e obiectul cu indicele 0 din matricea TableDefs (tabelesalvate). După ce apăsaţi pe Enter, rezultatul va fi numele unei tabele din  baza de date curentă, şi anume, Curs. Dacă înlocuiţi TableDefs(0) cuTableDefs(3), veţi obţine un rezultat mai neobişnuit: MSysACEs. Aceastadeoarece tabelele sunt stocate în ordine alfabetică în cadrul matriceiTableDefs, astfel încât tabelei sistem MSysACEs (folosită de Access) îicorespunde indicele 3 (primele trei tabele sunt, în ordine alfabetică: Curs,Curs_Prof şi Curs_Student).

Pag. 138

Page 134: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 134/295

Observaţi că între obiectele de pe trepte consecutive ale ierarhiei şi întreobiecte şi proprietăţile lor se pune un punct. Continuând ca mai sus, puteţi găsiinformaţii despre toate obiectele stocate într-o bază de date.

În continuare, ne vom ocupa în detaliu cu obiectele şi colecţiile ierarhiei DAO.

Notă: E important să sesizaţi diferenţa dintre o colecţie şi tipul elementelor ce ocompun. Spre exemplu, Workspaces (la plural) este numele colecţiei, iar Workspace(la singular) este tipul elementelor pe care ea le conţine.

Obiectul DBEngine (motorul Jet Engine)Este obiectul aflat în vârful ierarhiei DAO, este un obiect predefinit ce nu

 poate fi creat. Există un singur obiect DBEngine pentru o aplicaţie. El nu face partedin nici o colecţie şi conţine toate celelalte obiecte. El poate fi folosit pentru acompacta sau repara o bază de date, pentru a înregistra baze de date ODBC,

  pentru a obţine versiunea motorului Jet şi pentru a stabili timpul maxim necesar deschiderii sesiunii unui utilizator.

Colecţia Errors (Erori)Un obiect de tip Error primeşte toate erorile apărute în urma eşuării unei

acţiuni efectuate asupra unui obiect DAO. Erorile sunt ordonate în cadrul colecţiei în

funcţie de codul lor.Colecţia Workspaces (Sesiuni de lucru)Un obiect de tip Workspace defineşte o sesiune de lucru pentru un utilizator.

Acest obiect conţine toate bazele de date deschise de acel utilizator. Tranzacţiileefectuate în cadrul unei sesiuni (obiect de tip Workspace) sunt globale tuturor bazelor de date ale sesiunii respective. Access creează implicit obiectul Workspaces(0). Dacănu au fost impuse măsuri de securitate asupra bazei de date curente, proprietăţii Name(nume) a acestui obiect i se dă valoarea #Default Workspace#, iar proprietăţii

UserName(numele utilizatorului) i se dă valoarea

 Admin(administrator). Acest obiect

implicit nu poate fi şters sau închis şi este deci disponibil tot timpul.

Colecţia Databases (Baze de date)Un obiect de tip Database reprezintă o bază de date deschisă sau creată cu

DAO. Cu ajutorul metodei CreateDatabase a unui obiect Workspace, adăugaţiautomat o bază de date la colecţia Database a sesiunii respective. O bază de date poatefi închisă cu ajutorul metodei Close, ceea ce o va şterge din cadrul colecţiei. ColecţiaDatabases conţine toate bazele de date deschise DAO, plus baza de date curentă,deschisă în Access (care este obiectul   DBEngine.Workspaces(0). Databases(0) sauCurrentDB).

Pag. 139

Page 135: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 135/295

Colecţia Users (Utilizatori)Un obiect de tip User reprezintă contul unui utilizator. Vom reveni cum mai

multe detalii despre utilizatori, conturi şi grupuri, când vom vorbi despre aplicaţiimultiuser şi securitate.

Colecţia Groups (Grupuri)Un obiect de tip Group (grup) reprezintă grupuri de utilizatori şi drepturileacestora. Fiecare utilizator dintr-un grup e reprezentat printr-un obiect de tip User dincolecţia Users a grupului.

Colecţia QueryDefs (Interogări)Fiecare interogare salvată în Access sau creată cu ajutorul metodei

CreateQueryDef este reprezentată printr-un obiect de tip QueryDef din colecţiaQueryDefs. Obiectele de tip QueryDef sunt deci instrucţiuni SQL precompilate. Cu

ajutorul unui obiect de tip QueryDef puteţi crea seturi de înregistrări, îi puteţi regăsi

instrucţiunea SQL, puteţi afla dacă returnează sau nu înregistrări sau puteţi executainterogarea.

Colecţia TableDefs (Tabele)Un obiect de tip TableDef reprezintă o tabelă stocată într-o bază de date.

Tabela se poate afla în baza de date curentă sau poate fi ataşată dintr-o bază de date

externă. Cu ajutorul unui obiect de tip TableDef puteţi afla dacă tabela e ataşată, îi puteţi afla regulile de validare, dacă poate fi sau nu actualizată sau numărul deînregistrări.

Colecţia Indexes (Indecşi)Un obiect de tip index reprezintă un index al unei tabele sau al unui set de

înregistrări.

Colecţia Fields (Câmpuri)Un obiect de tip Field reprezintă o coloană. Obiectele de tip Relation (relaţie),

Recorset, TableDef, QueryDef şi Index conţin câte o colecţie Fields. Atributele unuicâmp pot fi aflate şi modificate prin intermediul proprietăţilor obiectului Fieldcorespunzător.

Colecţia Recordsets (Seturi de înregistrări)Obiectele de tip Recordset (set de înregistrări) sunt cel mai des folosite şi deci,

 poate, cele mai importante obiecte DAO. Aceste obiecte sunt temporare (nu suntsalvate pe disc).

Pag. 140

Page 136: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 136/295

Colecţia Relations (Relaţii)Fiecare relaţie dintre două sau mai multe tabele ale unei baze de date Access e

reprezentată printr-un obiect de tip Relation. Colecţia Relations a unui obiect de tipDatabase conţine toate relaţiile definite în baza de ate respectivă.

Colecţia Parameters (Parametri)Aţi văzut că în Access puteţi crea interogări cu parametri. Parametrii declaraţicu ajutorul cuvântului cheie PARAMETERS în instrucţiunea SQL a unei interogări senumesc parametri formali. Colecţia Parameters a unui obiect de tip QueryDef eformată din toţi parametri formali definiţi pentru interogarea respectivă. Nu puteţişterge sau adăuga obiecte la colecţia Parameters.

Colecţia Properties (Proprietăţi)Un obiect de tip Property reprezintă o caracteristică a unui obiect. Fiecare

obiect DAO are o colecţie Properties. Un obiect de tip Properties poate fi o proprietate predefinită sau una definită de utilizator. Programatorul poate adăuga proprietăţi (cuajutorul metodei CreateProperty) unui anumit obiect şi este responsabil pentrustabilirea şi modificarea valorilor acestor proprietăţi. Proprietăţile definite de utilizator sunt singurele care pot fi şterse din colecţia Properties a unui obiect; proprietăţile predefinite nu pot fi şterse.

8.1.2 Containere şi documente

Un container este o colecţie de obiecte salvate în Access: baze de date,formulare, rapoarte, module, tabele, relaţii. Termenul “document” este o descrieregenerică pentru un obiect stocat într-un container. Pentru a înţelege mai bine cereprezintă containerele şi documentele, gândiţi-vă la fereastra Database. Fiecare pagină a acestei ferestre reprezintă un container, iar fiecare obiect dintr-o pagină esteun document.

Pentru a examina containerele şi documentele bazei de date “CursuriOptionale.mdb”, vom scrie o subrutină care le va afişa pe ecran.

 Sub Containere_Documente()

 Dim dbCrt As Database Dim conCrt As Container  Dim docCrt As Document Set dbCrt = DBEngine.Workspaces(0) .Databases (0)For Each conCrt In DbCrt.Containers   Debug.Print “Container: “ & conCrt.Name  For Each docCrt In conCrt.Documents

 Debug.Print “Document: “ & docCrt.NameNext 

 Next  End Sub

Pag. 141

Page 137: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 137/295

Întâi am definit trei variabile: una de tip Database, care indică baza de datecurentă, una de tip container care indică fiecare element din colecţia Containers şi unade tip Document, ce indică fiecare document dintr-un container.

Apoi, pentru a itera printre elementele colecţiilor Containers, am folosit

instrucţiunea For Each, ce se aseamănă cu instrucţiunea For…Next, cu deosebirea căeste creată special pentru parcurgerea colecţiilor 

8.2 Lucrul cu variabile de tip obiect

Când declaraţi o variabilă obişnuită, practic îi cereţi lui Access să aloce spaţiulnecesar stocării unei informaţii pentru care aţi specificat un tip de date (dacă nuspecificaţi nici un tip de date, Access va considera în mod implicit că tipul e variant).

Lucrurile sunt puţin diferite la declararea unei variabile de tip obiect. În acest caz,Access creează numai un pointer la obiect. De exemplu, nici una din declaraţiile demai jos:

 Dim db As Database Dim form As Form Dim ctl As Control

nu stochează informaţii şi, deocamdată, nu indică vreun obiect existent. Pentru a le

face să indice un obiect, trebuie să folosim cuvântul cheie Set , ca mai jos: Set dbCrt = DBEngine.Workspaces(0) .Databases(0) Set form = dbForms!DetaliiProf  Set ctl = frm.Controls!Nume

Legătura dintre variabile şi obiectul spre care acestea indică este distrusă (şimemoria necesară este eliberată) o dată cu expirarea duratei de viaţă a variabilei. Dacădoriţi să faceţi dumneavoastră, explicit, acest lucru, puteţi folosi valoarea predefinită

 Nothing :

Set frm = Nothing

După cum aţi mai văzut şi în exemplele anterioare, pentru a accesa un anumitobiect DAO trebuie să parcurgeţi ierarhia în sens descrescător, până la acel obiect:

DBEngine.ColectieParinte.ColectieCopil (“ObiectCopil”)

Tabelul 8.5 prezintă cele patru metode prin care puteţi accesa un element alunei colecţii.

Pag. 142

Page 138: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 138/295

Sintaxa Exemplu Explicaţiicolectie(“nume”)

DBEngine.Workspaces(0).Databases_ (“CursuriOptionale”)

colectie (var) StrBazaDate = “Cursuri

Optionale”

DBEngine.Workspaces(0).Databases_ 

(strBazaDate)

var e o variabilă de tip şir de

caractere sau Variant

colectie(indice)

DBEngine.Workspaces(0).Databases(0)

indice reprezintă poziţiaobiectului în cadrul colecţiei

colectie!numeSaucolectie![nume]

DBEngine.Workspaces(0).Databases!_ [Cursuri Optionale]

Parantezele drepte suntnecesare numai dacă numelecolecţiei conţine caracterespeciale (de exemplu, spaţii)

Tabelul 8.5

Astfel, dacă vreţi să accesaţi un obiect al cărui nume îl cunoaşteţi, puteţi folosiacest nume ca mai jos:

Debug.Print Current.TableDefs(“Profesor”).RecordCount

Aţi văzut că pentru a obţine baza de date curentă, trebuie să scrieţi:

DBEngine.Workspaces(0) .Databases(0) Sau, pe scurt, DBEngine(0) (0)

Access vă mai pune însă la dispoziţie şi funcţia CurrentDB(), pentru a obţineun pointer la baza de date curentă. Dacă doriţi să accesaţi o bază de date din afara

sistemului Access (prin OLE), trebuie să folosiţi varianta   DBEngine(0) (0). Altfel,dacă lucraţi în Access, puteţi folosi ambele variante, cu observaţia că funcţiaCurrentDB() este mai rapidă. Atenţie, însă, la următorul aspect: nu puteţi folosi un pointer la un obiect pe care l-aţi obţinut apelând funcţia CurrentDB() într-o linieurmătoare de cod. Cu alte cuvinte, următoarea procedură:

 Sub Test1 () Dim doc As Document Set doc = CurrentDb.Containers!Forms.Documents(0)

 Debug.Print doc.Name

Pag. 143

Page 139: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 139/295

va eşua când va încerca să tipărească doc.Name deoarece, în acel punct, doc este un pointer invalid. Următoarea procedură, în schimb, va rula corect:

 Sub Test2 () Dim doc As Database

 Dim doc As Document Set db = CurrentDb() Set doc = db.Containers!Forms.Documents(0) Debug.Print doc.Name End Sub

Când folosim semnul exclamării (!) şi când punctul (.)Atât operatorul (!), cât şi operatorul (.) sunt folosiţi pentru a descrie relaţiile de

apartenenţă dintre colecţii, obiecte şi proprietăţi.

În general, după (!) urmează numele unui obiect creat de dumenavoastră: unformular, un raport sau un control (deci un element al unei colecţii). Astfel, operatorul(!) separă un obiect de colecţia din care face parte. Operatorul (.) este folosit, îngeneral, pentru a separa un obiect de o colecţie, proprietate sau metodă a sa.

8.3 Colecţii impliciteAţi putut observa din exemplele de până acum că adesea, pentru a obţine un

 pointer la un obiect, trebuie să scrieţi o linie de cod destul de lungă. În Access însă,aproape orice tip de obiect are o colecţie implicită, care va fi luată în considerare dacă

nu specificaţi nici o colecţie. De aceea,DBEngine.Workspaces(0) .Databases(0) .TableDefs(0)

se mai poate scrie prescurtat ca: DBEngine(0) (0) (0)

Aceasta pentru că, după cum puteţi vedea şi în tabelul 8.6, TableDefs ecolecţia implicită a unui obiect de tip Database, Databases e colecţia implicită a unuiobiect de tip Workspace, iar Workspaces e colecţia implicită a obiectului DBEngine.

Obiect Colecţia implicităContainer  Documents

Database TableDefsDBEngine WorkspacesGroup UsersIndex FieldsQueryDef ParametersRecordset Fields

Relation FieldsTableDef FieldsUser Groups

Pag. 144

Page 140: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 140/295

Workspace DatabasesTabelul 8.6

8.4 Lucrul cu proprietăţile obiectelor

Fiecare obiect DAO are o colecţie de proprietăţi. Unele obiecte au şi proprietăţi care nu există până în momentul în care li se dă o valoare. De aceea, esteimportant să înţelegeţi diferenţele dintre tipurile de proprietăţi ale obiectelor DAO.

8.4.1 Tipuri de proprietăţiExistă două tipuri de proprietăţi DAO: predefinite şi definite de utilizator. Proprietăţile predefinite ale unui obiect reprezintă caracteristicile de bază ale

acestuia. Ele există încă de la crearea obiectului şi sunt disponibile pentru oriceaplicaţie ce foloseşte motorul Jet. De exemplu, pentru un obiect de tip Field (câmp),

 proprietăţile Name(nume) şi Type(tip) sunt predefinite. Proprietăţile definite de utilizator nu există până când nu sunt adăugate lacolecţia Properties a obiectului. De exemplu, proprietatea  Description (descriere) aunui câmp nu este predefinită şi nu există până când nu introduceţi descrierea. Dacăîncercaţi să regăsiţi proprietatea Description a unui obiect ce încă nu o are, veţi obţineo eroare.

 8.4.2. Accesul la proprietăţi

Pentru a regăsi o proprietate predefinită a unui obiect, puteţi folosi sintaxa:obiect.proprietate

Pe de altă parte, nu puteţi regăsi o proprietate definită de utilizator decât prinintermediul colecţiei Properties a obiectului:

Obiect.Properties(“proprietar”)sau

Obiect.Properties!proprietateAceastă din urmă sintaxă funcţionează şi pentru proprietăţi predefinite.

8.4.3. Stabilirea proprietăţilorCu ajutorul instrucţiunii With   puteţi stabili mai multe proprietăţi ale unui

obiect, fără a mai fi necesar să specificaţi obiectul pentru fiecare proprietate în parte:

 Private Sub Set_Form_Prop()With txtCtl.Text = “Acesta este un control de tip text”

Pag. 145

Page 141: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 141/295

.ForeColor = RGB(0, 255, 0) ‘verde

.BackColor = 0 End With

 End Sub

8.5. Crearea şi manipularea obiectelor cu DAOÎn exemplele de până acum, nu am făcut altceva decât să folosim DAO pentru

a accesa obiecte existente şi proprietăţile acestora. O mare parte a facilităţilor oferitede DAO constă însă în posibilitatea de a crea şi de a modifica obiecte.

8.5.1. Crearea obiectelorPentru a crea un obiect nou, procedaţi astfel:

1. Folosiţi una dintre metodele Create…(CreateTable, CreateIndex  etc.) pentru a crea obiectul dorit (tabelă, index etc.).2. Stabiliţi proprietăţile obiectului creat. Unele proprietăţi (cum ar fi numele)

sunt esenţiale şi trebuie specificate la crearea obiectului. Altele pot fistabilite şi ulterior.

3. Adăugaţi obiectul la colecţia corespunzătoare, pentru ca ele să facă partedin baza de date.

Dacă obiectul nou creat conţine alte obiecte (aşa cum o tabelă conţine

câmpuri), trebuie să creaţi întâi obiectul principal şi pe urmă cele subordonate, pe carele adăugaţi la colecţiile corespunzătoare ale obiectului principal. Apoi, îl adăgaţi şi peacesta la colecţia sa.

Tabelul 8.7 prezintă în detaliu metodele Create…cu argumentele acestora şicu descrierile de rigoare.

Obiect Metoda ArgumenteTip dedate

Descriere

Tabela CreateTableDef Name String Numele tabeleiAttributes Integer Stabilire valori pentrutabele ataşate, sistem sauascunse

Source String Informaţii despre tipultabelei de bază a uneitabele ataşate

Connect String Calea şi numele fişieruluiunei tabele ataşate

Câmp CreateField Name String Numele câmpuluiType Integer Tipul de dateSize Integer Dimensiunea (pentru

Pag. 146

Page 142: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 142/295

câmpuri de tip text)Index CreateIndex Name String Numele indexuluiInterogare CreateQueryDef Name String Numele interogării

SQL String Şir de caractere ce conţineinstrucţiunea SQL pe care

se bazează interogareaRelaţie CreateRelation Name String Numele relaţieiTable String Numele tabelei primareForeignTable String Numele tabelei ce conţine

cheia străinăAttributes Integer Atributele relaţiei: tipul

relaţiei, integritateareferenţială, actualizări şiştergeri în cascadă

Workspace Create Workspace Name String Numele sesiunii de lucruUser String Numele utilizatoruluiPassword String Parola pentru sesiune

Bază dedate

CreateDatabase DatabaseName String Numele fişierului ceconţine baza de date

Locale String Expresie ce specificălimba pentru noua bază dedate (pentru sortări şicomparaţii între variabile

de tip text)Options Integer O constantă sau o

combinaţie de constantece arată dacă baza de dateeste criptată sau versiuneamotorului Jet

Grup CreateGroup Name String Numele grupului deutilizatori

PID String Identificatorul grupului

Utilizator CreateUser Name String Numele utilizatoruluiPID String Identificatorul

utilizatoruluiTabelul 8.7

În continuare, vom ilustra crearea unor astfel de obiecte complexe.

Pag. 147

Page 143: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 143/295

8.5.1.1. Crearea unei tabeleFuncţia următoare creează tabela Profesor1 şi îi adaugă doar două coloane:

IdProf şi Nume.

Function CreeazaTabProf () Dim db As Database Dim tdProf  As TableDef  Dim fd1 As Field Dim fd2 As Field Set db = CurrentDb ()‘Crearea tabelei si a coloanelor  Set tdProf = db.CreateTableDef ()tdProf.Name = “Profesor1”

 Set fd1 = tdProf.CreateField (“IdProf”, dbLong) Set fd2 = tdProf.CreateField (“Nume”, dbText, 60)‘Adaugarea la colectiiWith tdProf.Fields

.Append fd1

.Append fd2 End WithWith db.TableDefs

.Append tdProf 

‘Actualizarea colectiei TableDefs.Refresh End With End Function

Este să folosiţi metoda Refresh (actualizare) pentru a vă asigura că noileobiecte au fost adăugate (acest lucru e recomandat mai ales în cazul unei aplicaţiimultiuser).

Notă: Această funcţie nu tratează nici o eroare şi, de aceea, va eşua dacă o veţi rulade două ori consecutiv. Pentru a o putea rula cu succes a doua oară, ştergeţi întâitabela creată.

8.5.1.2 Crearea unui indexIată care sunt paşii pe care trebuie să-i urmaţi pentru a crea un index folosind

DAO:1. Folosiţi metoda CreateIndex a unui obiect de tip TableDef pentru a crea

indexul şi stabiliţi-i proprietatea Name (nume).2. Atribuiţi valorile dorite proprietăţilor noului index (cele mai importante

 proprietăţi sunt Name, Primary, Unique şi Required). După ce aţi adăugatindexul la colecţia sa, nu-i veţi mai putea modifica proprietăţile.

Pag. 148

Page 144: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 144/295

3. Pentru aceasta, va trebui să ştergeţi obiectul şi să creaţi unul nou, cu proprietăţile dorite.

4. Folosiţi metoda CreateField a indexului pentru a crea câte un obiect de tip

Field pentru fiecare câmp ce face parte din index. Adăugaţi-le apoi lacolecţia Fields a indexului.5. Folosiţi metoda Append a obiectului de tip TableDef pentru a adăuga

indexul la colecţia Indexes.Funcţia CreareCheiePrimara() pe care o dăm mai jos ca exemplu, creează o

cheie primară pentru o tabelă. Ea primeşte ca argumente numele tabelei, numeleindexului şi coloanele ce vor compune cheia primară. Argumentul varColoane fiind detip Variant, poate conţine fie o matrice, dacă vor fi mai multe coloane în componenţacheii primare, fie un singur nume. Pentru a testa dacă nu există deja o cheie primară

 pentru tabela respectivă, funcţia CreareCheiePrimara() apelează funcţia ExistaCP(),care returnează numele indexului corespunzător cheii primare, dacă acesta există, sauvaloarea Null, dacă nu există. De asemenea, pentru a adăuga un obiect de tip Field lacolecţia Fields a unui index, funcţia CreareCheiePrimara() apelează funcţiaAdaugareCamp(), ce returnează valoarea True în caz de reuşită şi False în caz de eşec.Pentru a testa funcţia CreareCheiePrimara() am creat şi subrutina TestCP, ce listează pentru tabela Curs_Prof cheia primară formată din coloanele IdCurs şi IdProf.

Function CreareCheiePrimara(strTabela As String, strCP As

String,_ varColoane As Variant) As Boolean Dim db As Database Dim td As TableDef  Dim idxs As Indexes Dim idx As Index Dim fd As Field Dim varCP As Variant Dim varIdx As VariantOn Error GoTo CreareCheiePrimara_Err 

 Set db = CurrentDb()

 Set td = db.TableDefs(strTabela) Set idxs = td.Indexes‘daca exista o cheie primara, o stergemvarCP = ExistaCP(td) If Not IsNull (varCP) Then

Idxs.Delete varCP End If ‘cream noul index Set idx = td.CreateIndex (strCP)‘facem ca indexul sa fie cheie primara. Astfel, stabilim automat proprietatile:‘IgnoreNulls = False; Required = True; Unique = True; idx.Primary = True

Pag. 149

Page 145: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 145/295

‘cream campurile si le adaugam la colectia Fields‘daca avem mai multe coloane: If IsArray (varColoane) Then  For Each varIdx In varColoane 

Call AdaugareCamp (idx, varIdx)   Next varIdx Else‘daca avem o singura coloana:

Call AdaugareCamp (idx, varColoane) End If ‘adaugam indexul la colectia Indexesidexs.Append idx

CreareCheiePrimara = TrueCreareCheiePrimara_Exit:Exit Function

CreareCheiePrimara_Err:MsgBox “Crearea indexului a esuat”CreareCheiePrimara = False

Resume CreareCheiePrimara_Exit End Function

 Private Function ExistaCP(td As TableDef) As Variant Dim idx As IndexFor Each idx In td.Indexes

If idx.Primary ThenExistaCP = idx.NameExit Function

End If  Next idxExistaCP = Null

 End Function Private Function AdaugareCamp (idx As Index, varIdx As Variant)_ 

As Boolean Dim fd As FieldOn Error GoTo AdaugareCamp_Err  If Len(varIdx & “ “) > 0 Then

 Set fd = idx.CreateField(varIdx)Idx.Fields.Append fd

 End If AdaugareCamp = True

Pag. 150

Page 146: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 146/295

 AdaugareCamp_Exit:Exit Function

 AdaugareCamp_Err:AdaugareCamp = FalseResume AdaugareCamp_Exit

 End Function

 Sub TestCP() Debug.Print CreareCheiePrimara(“Curs_Prof”, “PrimaryKey”,_ 

Array(“IdCurs”, “IdProf”)) End Sub

8.5.1.3 Crearea unei relaţiiPentru a crea o relaţie folosind DAO, trebuie să efectuaţi următorii paşi:

1. Verificaţi dacă tabela primară (tabela din partea 1 a relaţiei) are definită ocheie primară.

2. Folosiţi metoda CreateRelation a obiectului bază de date pentru a crearelaţia. Proprietăţile relaţiei le puteţi stabili fie la crearea ei, fie ulterior,una câte una (Table, ForeignTable şi Attributes sunt printre cele mai

importante).3. Creaţi câte un obiect de tip Field (câmp) pentru fiecare coloană din cheia  primară a tabelei primare. Pentru fiecare dintre acestea, stabiliţi proprietatea ForeignName, ce reprezintă numele coloanei corespunzătoaredin tabela din partea (many) a relaţiei. Adăugaţia apoi obiectele de tipField la colecţia Fields a relaţiei.

4. Folosiţi metoda Append a obiectului de bază de date pentru a adăugarelaţia la colecţia Relations.

Funcţia CreareRel , prezentă mai jos, creează o asociere left outer join întretabelele

 Profesor şi

Titluşi permite actualizările în cascadă. Dacă relaţia există deja,

funcţia CreareRel o şterge şi o creează din nou.

Function CreareRel()  As Boolean Dim db As Database Dim rel As Relation Dim fd As FieldOn Error GoTo CreareRel_Err  Set db = CurrentDb()‘cream obiectul relatie Set rel = db.CreateRelation()‘stabilim proprietatile relatiei

Pag. 151

Page 147: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 147/295

With rel.Name = “RelProfTitlu”.Table = “Titlu”.ForeignTable = “Profesor”

‘left outer join, modificari in cascada

.Attributes = dbRelationLeft Or dbRelationDeleteCascade End With‘cream campurile Set fd = rel.CreateField(“IdTitlu”)fd.ForeignName = “IdTitlu”rel.Fields.Append fd‘adaugam relatia la colectia Relations

CreareRel = TrueCreareRel_Exit:Exit Function

CreareRel_Err:Select Case Err.Number 

Case 3012 ‘daca relatia exista dejaDb.Relations.Delete rel.NameResume

 Case Else

MsgBox “Relatia nu a putut fi creata”CreareRel = FalseResume CreareRel_Exit 

End Select  End Function

8.5.1.4. Crearea proprietăţilor-utilizatorDAO vă dă posibilitatea să creaţi noi proprietăţi pentru un obiect, pe care să le

adăugaţi apoi la colecţia Properties a obiectului respectiv. Paşii pe care trebuie să-iurmaţi sunt cei de mai jos:

1. Folosiţi metoda CreateProperty a obiectului respectiv pentru a crea proprietatea.

2. Definiţi caracteristicile proprietăţii.3. Adăugaţi proprietatea la colecţia Properties a obiectului.Subrutina de mai jos creează o nouă proprietate pentru o tabelă:

UltimaModificare. Ea păstrează data ultimei modificări a tabelei.

 Sub UltimaModif (strTab As String) Dim db As Database

Pag. 152

Page 148: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 148/295

 Dim tb As TableDef  Dim prUltMod As Property Set db = CurrentDb() Set tb = db.TableDefs(strTab)‘cream noua proprietate

 Set prUltMod = td.CreateProperty(“UltimaModificare”, dbDate, Now)‘adaugam UltimaModificare la colectia Properties‘ignoram posibilele eroriOn error Resume Next td.Properties.Append prUltMod‘afisam valoarea proprietatii Debug.Print td.Properties(“UltimaModificare”).Value End Sub

Deoarece metoda Append dă o eroare dacă proprietatea există deja, pentru ascăpa de probleme am dezactivat detectarea erorilor.

8.5.2. Modificarea obiectelorPuteţi modifica un obiect existent fără a-l deschide în modul  Design View, ci

numai folosind proprietăţile şi metodele furnizate de DAO. Trebuie totuşi să ţineţicont de anumite restricţii atunci când stabiliţi proprietăţile unui obiect DAO. Unele proprietăţi pot fi stabilite numai la crearea obiectului şi nu mai pot fi modificate după

ce acesta a fost adăugat la colecţia corespunzătoare (proprietatea Attributes a unuiobiect de tip TableDef e un exemplu în acest sens). Pentru a modifica o astfel de proprietate, trebuie să creaţi un nou obiect, să copiaţi în el toată informaţia conţinutăîn cel vechi, să stabiliţi proprietatea respectivă, să adăugaţi noul obiect la colecţia sa şiapoi să ştergeţi vechiul obiect. De asemenea, trebuie să ţineţi cont de faptul că unele proprietăţi ale unui obiect DAO nu există decât din momentul în care li s-a dat ovaloare, astfel încât încercarea de a regăsi o astfel de proprietate s-ar putea solda cu oeroare.

8.6. Obiecte definite de utilizator

În Access 97 puteţi crea propriile dumneavoastră obiecte, cu proprietăţile şimetodele lor, în cadrul modulelor pentru clase. Pe parcursul acestui subcapitol, ne-am propus să creăm un obiect care să poată fi accesat prin VBA şi care să ofere diferiteinformaţii despre sistem.

8.6.1. Proprietăţile şi metodele obiectuluiPrimul lucru pe care trebuie să-l facem atunci când creăm un obiect este să

stabilim care sunt informaţiile pe care acesta le va oferi. Cu alte cuvinte, trebuie sădeterminăm caracteristicile şi comportamentul lui. Tabelul 8.8 conţine proprietăţileobiectului Calculator, pe care îl vom crea.

Pag. 153

Page 149: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 149/295

Proprietate DescriereCalculator.Nume Şir de caractere ce conţine numele calculatoruluiCalculator.PornireWindows Proprietate de tip Date/Time, ce arată când a fost

 pornit ultima oară sistemul de operare Windows

Calculator.DirAccess Şir de caractere ce conţine directorul în care seaflă msaccess.exeTabelul 8.8

În plus faţă de aceste proprietăţi, obiectul Calculator trebuie să-i ofereutilizatorului posibilitatea de a efectua diferite acţiuni, cum ar fi, de exemplu,ştergerea unui director gol sau redarea unui fişier de sunet wave. Pentru aceasta, vomimplementa metodele

Calculator.StergeDir şi Calculator.RedareWave

Ceea ce vom face pe parcursul acestui capitol este să definim o clasă (clasaCalculator), cu ajutorul unui modul pentru clase (class module). Apoi, prin VBA,vom putea crea şi folosi obiecte ale acestei clase.

Deschideţi fereastra  Database şi alegeţi comanda Class Module din meniul Insert  pentru a crea un nou modul pentru clase. Salvaţi acest modul cu numele

Calculator (numele clasei pe care dorim să o implementăm). Observaţi că modulele pentru clase sunt foarte asemănătoare cu modulele standard. Una dintre diferenţe esteaceea că ele pot conţine două proceduri speciale, Class_Initialize() şiClass_Terminate(). Procedura Class_Initialize() se apelează automat la creareainstanţelor unui obiect al clasei definite în modulul respectiv. De aceea, în cadrulacestei proceduri se efectuează, de obicei, iniţializări ale proprietăţilor obiectului.Procedura Class_Terminate() este apelată ori de câte ori este distrusă o instanţă a unuiobiect bazat pe modulul respectiv.

Declaraţi întâi la secţiunea (General)(Declarations) a modulului o variabilă

globală în cadrul modulului Calculator:

Private strDirAccess As String

Creaţi subrutina Calss_Initialize(), selectând din caseta combinată Object(aflată în partea din stânga-sus a ferestrei modulului) secţiunea Class, iar din casetacombinată  Procedure (din partea dreapta-sus a ferestrei modulului), evenimentul Initialize (iniţializare). În cadrul acestei subrutine vom iniţializa variabila globalădeclarată anterior. Ea va păstra directorul (cu calea completă) în care este instalată

aplicaţia Access (în care se află fişierul Msaccess.exe). Pentru a obţine o informaţie,vom apela funcţia VBA SysCmd. Scrieţi deci, în cadrul subrutinei Class_Initialize(),următoarea linie de cod:

Pag. 154

Page 150: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 150/295

StrDirAccess = SysCmd(acSysCmdAccessDir)

Funcţia SysCmd() poate fi folosită pentru a efectua diferite acţiuni în Access.Dacă îi dăm ca parametru constanta intrinsecă acSysCmdAccessDir , ea va returna un

şir de caractere ce reprezintă directorul în care se află Msaccess.exe. Faptul că amobţinut această informaţie nu este suficient. Mai trebuie să ne asigurăm că ea poate fiaccesată prin intermediul proprietăţii Calculator.DirAccess. Procedura Property Getcreează o proprietate şi stabileşte modul în care sunt regăsite valorile acestei proprietăţi. Ea are următoarea sintaxă:

[Public | Private] [Static] Property Get NumeProprietate _ [( ListaArgumente)] As TipDate

unde:

 Public – indică faptul că procedura  Property Get  poate fi apelată de orice altă procedură din orice alt modul; Private  – indică faptul că procedura Property Get poate fi apelată numai de către procedurile din modulul în care a fost declarată; Static  – indică faptul că valorile variabilelor locale ale procedurii se păstrează întreapeluri;

 NumeProprietate – numele proprietăţii ale cărei valori le regăseşte procedura; ListaArgumente – lista argumentelor procedurii;

TipDate – tipul de date al proprietăţii.Procedura Property Get ce regăseşte valoarea proprietăţii DirAccess este:

 Public  Property Get DirAccess() As StringDirAccess = strDirAccess End Property

Proprietatea Calculator.dirAccess este read-only, adică valoarea ei nu poate fimodificată. Totuşi, majoritatea proprietăţilor unui obiect (formular, raport, controletc.) îşi pot schimba valoarea. O astfel de proprietate este şi Calculator.Nume. pentrua regăsi şi modifica valoarea acestei proprietăţi, vom folosi două funcţii API,GetComputerName şi, respectiv, SetComputerName, ale căror declaraţii:

Private Declare Function GetComputerName Lib “kernel132” Alias_ “GetComputerNameA” (ByVal lpBuffer As String, nsize As Long) As LongPrivate Declare Function SetComputerName Lib “kernel132” Alias_ “SetComputerNameA” (ByVal lpComputerName As String) As Long

trebuie să le includeţi la secţiunea (General)(Declarations) a modulului.

Pag. 155

Page 151: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 151/295

Funcţia SetComputerName primeşte ca argument un şir de caractere cereprezintă noul nume pe care doriţi să i-l daţi calculatorului dumneavoastră.Modificarea nu devine efectivă însă decât după ce aţi închis şi pornit din noucalculatorul. Astfel, dacă apelaţi funcţia SetComputerName cu argumentul“NumeNou” şi apoi apelaţi funcţia GetComputerName fără a fi iniţializat între timp

calculatorul, aceasta din urmă va returna vechiul nume al calculatorului şi nu şirul decaractere “NumeNou”, cum ar fi de aşteptat. De aceea, ne propunem ca proprietateaCalculator.Nume să păstreze ultimul nume pe care l-am dat calculatorului în cadrulunei instanţe a obiectului Calculator şi nu rezultatul returnat de funcţiaGetComputerName.

Deoarece proprietatea Nume poate fi modificată, în plus faţă de o procedură Property Get , trebuie să scriem şi o procedură Property Let pentru aceasta proprietate,care să ne ajute să-i modificăm valoarea prin intermediul unei simple atribuiri, sintaxainstrucţiunii Property Let este următoarea:

[Public | Private] [Static] Property Let NumeProprietate _ ( ListaArgumente) 

unde cuvintele cheie   Public, Private, Static şi  NumeProprietate au aceleaşisemnificaţii ca şi pentru instrucţiunea   Property Get , iar ListaArgumente reprezintăargumentele procedurii. Numele şi tipul fiecărui argument (cu execepţia ultimului)

trebuie să corespundă exact numelui şi tipului argumentelor procedurii Property Get aaceleiaşi proprietăţi. Ultimul argument reprezintă noua valoare ce va fi atribuită proprietăţii şi deci trebuie să aibă acelaşi tip de date ca şi cel returnat de procedura Property Get. Iată care sunt cele două proceduri pentru regăsirea şi modificareavalorilor proprietăţii Calculator.Nume:

 Public Property Get Nume () As String Nume = strNume End Property

 Public Property Let Nume (strNumeNou As String)Call SetComputerName (strNumeNou)strNume = strNumeNou

Variabila  strNume este globală în cadrul modulului şi trebuie deci să fiedeclarată la secţiunea (General)(Declarations) a acestuia:

Private strNume As String * 255

Ea trebuie să fie iniţializată în cadrul funcţiei Class_Initialize():

Call GetComputerName(strNume, 255)

Pag. 156

Page 152: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 152/295

Până acum am vorbit numai despre proprietăţile obiectului Calculator.Metodele unui obiect sunt mult mai simplu de implementat: ele sunt subrutine saufuncţii publice obişnuite. Iată care sunt cele două metode ale obiectului Calculator:

 Public Function StergeDir(strDir As String)StergeDir = RemoveDirectory(strDir) End Function

 Public Sub PlayWave(strWave As String)Call PlaySound(strWave, 0, 0) End Sub

Pentru a putea apela funcţiile API  RemoveDirectory şi  PlaySound, trebuie să

includeţi la secţiunea (General)(Declarations) a modulului declaraţiile lor:Private Declare Function RemoveDirectory Lib “kernel132” Alias_ “RemoveDirectoryA” (ByVal lpPathName As String) As LongPrivate Declare Function PlaySound Lib “winmm.dll” Alias_ “PlaySoundA” (ByVal lpszName As String, ByVal hModule As Long,ByVal_ dwFlags As Long) As Long

8.6.2 Crearea instanţelor obiectuluiPrimul lucru pe care trebuie să-l subliniem este acela că există o diferenţă între

crearea unei variabile de tip obiect şi crearea unui obiect. Prin următoarea lini de cod:

Dim comp As New Calculator

nu se creează o nouă instanţă a obiectului Calculator , ci doar se alocă resurselenecesare creării unui nou obiect de acest tip. Obiectul în sine nu este creat până cânduna dintre proprietăţile sau metodele sale nu este folosită sau apelată. Cu alte cuvinte,dacă după declaraţia de mai sus am dori să afişăm proprietatea DirAccess şi am scrie:

MsgBox comp.DirAccess

această instrucţiune este cea care declanşează crearea obiectului, apelarea procedurilor:

Class_Initialize şi Prop Get DirAccess

Instrucţiunea folosită pentru alocarea resurselor poate fi înlocuită cu:

Set comp = New Calculator

Pag. 157

Page 153: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 153/295

În acest caz, instrucţiunea  Dim alocă spaţiul necesar creării obiectului, iar instrucţiunea Set determină crearea obiectului şi apelarea procedurii Class_Initialize.

Observaţi utilizarea cuvântului cheie New în ambele variante folosite pentrucrearea instanţelor. Acesta trebuie folosit pentru orice obiect.

Pentru a testa funcţionalitatea unui obiect de tip Calculator, creţi un nou modulstandard în care scrieţi următoarea subrutină:

 Sub testCalculator() Dim comp As New Calculator  MsgBox comp.DirAccess MsgBox comp.NumeComp.Nume = “CalculatorulMeu” End Sub

8.6.3. Durata de viaţă a obiectelorÎn situaţia în care avem mai multe variabile care fac referire la acelaşi obiect,

acesta nu poate fi distrus şi deci, resursele ocupate de el nu pot fi eliberate decât dupăce au fost distruse toate variabilele ce fac referire la el. Acest lucru se întâmplă oricând o variabilă îşi încheie durata de viaţă (scopul), ori când ea primeşte valoarea Nothing :

Set comp = Nothing

8.7 Lucrul cu obiecte de tip RecordsetAdevărata putere a unei baze de date constă în modul în care putem să regăsim

informaţia, să manipulăm înregistrările şi seturile de înregistrări. Ce este un set deînregsitrări? Atunci când deschideţi o tabelă în modul Datasheet View, vedeţi un setde înregistrări. De aceea, dacă vă decideţi să programaţi în VBA, veţi lucra foartemult cu obiecte de tip Recordset. Iată un prim exemplu de subrutină ce foloseşte unastfel de obiect pentru a găsi numărul de înregistrări dintr-o tabelă a bazei de dateCursuri Opţionale.mdb:

 Public Function NrInregistr(strTabela As string) Dim db As Database Dim rst As Recorset Dim iNrInregistrari Set db = CurrentDb() Set rst = db.OpenRecordset(strTabela)iNrInregistrari = rst.RecordCount Debug.Print “Tabela “ & strTabela & “ contine “ & iNrInregistrari &“ inregistrări”

Pag. 158

Page 154: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 154/295

rst.close End Function

Deschideţi fereastra Debug şi scrieţi:

?NrInregistr(“Student”)după care apăsaţi pe Enter. Figura 8.9 prezintă rezultatul obţinut.

Pag. 159

Page 155: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 155/295

Figura 8.9

Atâta timp cât un set de înregistrări este deschis (între apelul metodeiOpenRecordset şi al metodei Close), puteţi face orice doriţi cu înregistrările sale: le

 puteţi edita, şterge sau puteţi chiar adăuga înregistrări noi. Este important să închideţiun set de înregistrări (apelând metoda Close) pentru a elibera resursele pe care Accessi le-a alocat.

8.7.1. Tipuri de seturi de înregistrăriÎn VBA există nu mai puţin de cinci feluri de obiecte de tip Recordset:

• Obiecte Recordset de tip tabelă;• Obiecte Recordset de tip dynaset;• Obiecte Recordset de tip snapshot;• Obiecte Recordset de tip forward-only;• Obiecte Recordset de tip dinamic.

În funcţie de următorii factori, decideţi pe care dintre aceste tipuri îl veţi folosila un moment dat:

• Dacă doriţi să şi actualizaţi înregistrările, nu numai să le vedeţi;• Dacă tabelele se află într-o bază de date Access sau de alt tip;• Câte înregsitrări conţine setul de înregistrări.

În cadrul acestui capitol ne vom ocupa numai de primele trei tipuri de seturi deînregistrare.

Pag. 160

Page 156: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 156/295

După cum aţi observat şi din exemplul anterior, pentru a crea un set deînregistrări, folosiţi expresia:

Set rst = db.OpenRecordset (Sursa[, tip[, optiuni[, blocaje]]])Sau

Set rst = obiect.OpenRecordset ([tip[, optiuni[, blocaje]]])

Unde:• db – este un obiect de tip Database;•  sursa – este o tabelă, o interogare sau o instrucţiune SQL ce returneazăînregistrări;• obiect  – un obiect al unei baze de date deschis anterior: tabelă,interogare sau un alt set de înregistrări;•

tip – specifică tipul setului de înregistrări şi poate fi una dintreurmătoarele constante predefinite:• dbOpenTable – set de înregistrări de tip tabelă• dbOpenDynaset – dynaset• dbOpenSnapshot – snapshot• dbOpenForwarsOnly – set de înregistrări de tip forward-only• dbOpenDynamic – set de înregistrări de tip dinamic;

• opţiuni – combinaţie de constante ce definesc caracteristicile noului setde înregistrări;

• blocaje – constantă ce specifică tipul de blocaj aplicat setului deînregistrări (pentru aplicaţii multiuser).Notă:  Access97 vă permite să creaţi un obiect de tip recordset printr-o singură liniede cod, de exemplu:

Set rst = CurrentDb.OpenRecordset(“Profesor”, dbOpenTable) 

ceea ce în Access 95 nu era posibil. Metoda compusă din doi paşi este totuşi preferabilă, dacă veţi folosi obiectul de tip Database în cadrul procedurii şi pentru alteacţiuni.

8.7.1.1. Seturi de înregistrări de tip tabelăAcesta este tipul implicit de set de înregistrări pe care Access îl creează dacă

nu specificaţi alt tip ca argument al metodei OpenRecordset şi dacă sursa deînregistrări este o tabelă din baza de date curentă. Unul dintre avantajele unui astfel deset de înregistrări este acela că puteţi folosi indecşi pentru a accelera căutările.

8.7.1.2. Seturi de înregistrări de tip dynasetUn astfel de set de înregistrări poate conţine date din mai multe tabele locale

sau ataşate. Puteţi edita datele dintr-un dynaset şi modificările vor fi efectuate şi în

Pag. 161

Page 157: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 157/295

tabelele de bază. În cazul unei aplicaţii multiuser, Access va actualiza datele dintr-undynaset deschis pentru a reflecta modificările efectuate dealţi utilizatori asupra tabelelor de bază. Iată câteva situaţii în care ar trebui să optaţi pentru crearea unui dynaset:

• când doriţi să puteţi modifica înregistrările;

• când obiectul de tip Recordset are dimensiuni foarte mari;• când obiectul de tip Recordset conţine obiecte OLE.

Acesta este tipul implicit de set de înregistrări pe care Access îl creează dacăsursa de înregistrări este o interogare, o instrucţiune SQL SELECT sau o tabelă carenu se află într-o bază de date Access. Iată câteva exemple de creare a unui dynaset:

 Set db = CurrentDb() Set rst = db.OpenRcordset(“IntProfCurs”, dbOpenDynaset)

unde IntProfCurs este o interogare;

 Set db = CurrentDb() Set rst = db.OpenRecordset(“SELECT * FROM Student”,

dbOpenDynaset)

unde sursa de înregistrări este o instrucţiune SELECT.

8.7.1.3. Seturi de înregistrări de tip snapshotSeturile de înregistrări de tip snashot nu permit modificarea datelor şi nici nureflectă modificările efectuate de alţi utilizatori asupra tabelelor de bază. Elereprezintă instantanee ale datelor la un moment dat. Avantajul lor este acela că suntmai rapide decât cele dynaset, dar numai atunci când numărul de înregistrări nu estemai mare de 500.

8.7.2. Actualizarea datelor unui set de înregistrări

Pentru a vă asigura că datele unui set de înregistrări sunt actualizate, puteţiexecuta din nou interogarea care stă la baza setului, apelând metoda  Requery(reinterogare) a obiectului. Nu orice obiect de tip Recordset suportă însă reinterogarea.De aceea, pentru a afla acest lucru, trebuie ca înainte de a apela metoda  Requery săverificaţi dacă proprietatea Restartable a obiectului are valoarea True (altfel,reinterogarea va genera o eroare):

If rst.Restartable = True Then rst.Requery

Pag. 162

Page 158: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 158/295

8.7.3. Parcurgerea seturilor de înregistrăriDupă ce aţi creat un obiect de tip Recorset, înregistrarea curentă va fi prima

înregistrare a setului. Dacă nu aţi specificat nici o regulă de sortare a înregistrărilor,acestea se pot afla în orice ordine.

Access vă pune la dispoziţie cinci metode pentru a parcurge înregistrările unuiset de înregistrări:

Metoda Descriere MoveNext  Înregistrarea următoare devine cea curentă MovePrevious Înregistrarea precedentă devine cea curentă MoveFirst  Prima înregistrare devine cea curentă MoveLast  Ultima înregistrare devine cea curentă

 Move n[, start] Înregistrarea curentă devine cea care se află la nînregistrări distanţă (înainte sau înapoi) de cea curentăsau de o anumită poziţie ( start ).

Parametrul n al metodei Move indică numărul de înregistrări care trebuie să fie parcurse pentru a ajunge la cea dorită. Dacă n>0, parcurgerea se face înainte, dacăn<0, înapoi. Parametrul opţional start reprezintă un semn de carte, adică o anumită poziţie de la care începe deplasarea cu n înregistrări. Dacă acest parametru nu estespecificat, se porneşte de la înregistrarea curentă. (Despre semne de carte vom vorbi

mai târziu, în cadrul acestui subcapitol.)8.7.4. Regăsirea numărului de înregistrări ale unui set de înregistrăriÎn exemplul pe care l-am dat la începutul acestui subcapitol, am folosit

 proprietatea  RecordCount a unui obiect de tip Recordset pentru a-i afla numărul deînregistrări. După cum v-aţi putut da seama ulterior, setul respectiv era de tip tabelă.Pentru acest tip, Access cunoaşte numărul de înregistrări şi dă proprietăţii RecordCount valoarea corespunzătoare. Lucrurile nu sunt însă la fel de simple şi încazul altor tipuri de seturi de înregistrări.

Pentru a mări performanţele aplicaţiei dumneavoastră, atunci când creează unobiect Recordset de tip dynaset sau snapshot, Access trece la executarea liniei de codurmătoare celei ce apelează metoda OpenRecordset  imediat după ce a fost regăsită prima înregistrare. De aceea, Access nu cunoaşte imediat numărul de înregistrări alunui astfel de set. Pentru ca acest număr să fie calculat corect, trebuie să apelaţimetoda MoveLast, pentru a vă asigura că au fost regăsite toate înregsitrările şi apoi săfolosiţi proprietatea RecordCount:

 Set rst = db.OpenRecordset(“IntProfCurs”, dbOpenDynaset)

 Rst.MoveLast  Debug.Print  rst.RecordCount

Pag. 163

Page 159: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 159/295

 Notă: În cazul în care vreţi să aflaţi numai dacă setul de înregistrări conţine măcar oînregistrare, nu trebuie să mai apelaţi metoda MoveLast, pentru că Access nu trece laurmătoarea linie până când nu a fost returnată prima înregistrare a setului. Deaceea, dacă proprietatea RecordCount are valoarea zero, e clar că setul nu conţineînregistrări.

Dacă adăugaţi sau ştergeţi înregistrări dintr-un dynaset, proprietatea RecordCount a obiectului respectiv se modifică în consecinţă. În cazul unei aplicaţiimultiuser, dacă aţi utilizatori adaugă sau şterg înregistrări din tabela din care îşi iausetul datele, aceste modificări nu sunt reflectate imediat, astfel încât va trebui să-lreinterogaţi şi să apelaţi MoveLast înainte de a folosi proprietatea RecordCount.

8.7.5. Poziţia absolută şi poziţia procentualăPentru a parcurge un set de înregistrări sau pentru a afla poziţia înregistrăriicurente, puteţi folosi proprietăţile  AbsolutePosition (poziţia absolută) şi PercentPosition (poziţia procentuală) a obiectului de tip Recordset.

Proprietatea AbsolutePosition reprezintă poziţia înregistrării curente în cadrulsetului (faţă de zero), iar dacă nu există o înregistrare curentă, valoarea ei este –1. Eaeste disponibilă numai pentru seturi de tip dynaset sau snapshot. Spre exemplu, pentruca înregistrarea curentă să devină cea de-a 4-a înregistrare din set, scrieţi:

rst.AbsolutePosition = 3Proprietatea  PercentPosition indică poziţia înregistrării curente ca procentaj

din numărul total de înregistrări ale setului şi poate avea valori între 0.0 şi 100.00.Astfel, pentru a vă deplasa până la jumătatea setului, puteţi scrie:

rst.PercentPosition = 50

Pentru a vă asigura că proprietatea  PercentPosition  returnează o valoarecorectă, trebuie să reinterogaţi setul şi apoi să apelaţi metoda

 MoveLast,din aceleaşi

motive prezentate anterior pentru proprietatea RecordCount.

8.7.6. Poziţiile de început şi de sfârşit ale setului de înregistrări (BOF şi EOF)Orice set de înregistrări are două proprietăţi (BOF şi EOF) care arată dacă

înregistrarea curentă se află la începutul setului (BOF) sau la sfârşitul lui (EOF).Dacă prima înegistrare este cea curentă şi apelaţi metoda  MovePrevious,

 proprietatea BOF ia valoarea True şi înregistrarea curentă nu mai există. Dacă maiapelaţi încă o dată metoda  MovePrevious, valoarea lui BOF rămâne True, dar va figenerată o eroare.

Pag. 164

Page 160: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 160/295

Dacă ultima înregistrare este cea curentă şi apelaţi metoda  MoveNext , proprietatea EOF ia valoarea True şi nu mai există o înregistrare curentă. Dacă apelaţidin nou metoda MoveNext , valoarea lui EOF rămâne True, dar va fi generată o eroare.

8.7.7. Regăsirea valorilor câmpurilor unui set de înregistrăriPentru a afla valorile diferitelor câmpuri ale unui set de înregistrări,

corespunzătoare înregistrării curente, puteţi folosi una dintre următoarele trei variantede sintaxă:

Sintaxa Exemplurst!camp rst!Numerst(“camp”) rst(“Nume”)

rst(indice) rst(1)Reţineţi faptul că, într-un set de înregistrări, primul câmp are întotdeauna

indicele 0, indiferent de opţiunea Option Base pe care aţi specificat-o. Astfel, rst(1) sereferă la cea de-a doua coloană a setului rst .

Să presupunem că dorim să afişăm numele şi catedra tuturor profesorilor dintabela Profesor. Pentru aceasta, putem scrie următoarea procedură:

 Public Sub Nume_Student()

 Dim db As Database Dim rst As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset(“Profesor”)With rst

‘verificam daca rst contine inregistrariIf .RecordCount Then

.MoveLast ‘parcurgem setul de la ultima catre prima inregistrare

  Do Until .BOF    Debug.Print ![Nume], ![Catedra]

.MovePreviousLoop

End If .Close

 End With End Sub

Dacă veţi rula această subrutină, rezultatele din fereastra Debug vor fiasemănătoare cu cele din figura 8.10:

Pag. 165

Page 161: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 161/295

Fig 8.10

De multe ori, veţi dori să aveţi un acces mai rapid la un set de date pe care nudoriţi să le modificaţi, ci numai să le vizualizaţi. Pentru aceasta, puteţi crea un set detip snapshot cu opţiunea dbForwardOnly, care este foarte rapid, dar nu permite decât parcurgerea înainte a setului. O modalitate de a vă bucura de rapiditatea unui astfel deset de înregistrări şi de a putea, în acelaşi timp, să accesaţi în orice ordine datele pecare acesta le conţine, este să copiaţi datele într-o matrice. Dumneavoastră nu trebuiedecât să declaraţi o variabilă de tip Variant şi să apelaţi metoda GetRows() a setului.

Access va crea o matrice bidimensională, pe care o va dimensiona corespunzător.Putem deci rescrie procedura Nume_Student astfel încât să folosim un snapshot şi omatrice:

 Public Sub Nume_Student_1() Dim db As Database Dim rst As Recordset Dim varDate As Variant Dim iNrInreg As Integer 

 Dim i As Integer  Set db = CurrentDb() Set rst = db.OpenRecordset(“Student”, dbOpenSnashot, dbForwardOnly)

Pag. 166

Page 162: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 162/295

‘alegem un numar suficient de mare de inregistrarivarDate = rst.GetRows(1000)‘aflam indicele ultimei linii a matriceiiNrInreg = Ubound(varDate, 2)

‘tiparim datela coloanei 1-a (Nr_matr) si a 2-a (Nume)For i = iNrInreg To 0 Step –1Debug.Print varDate(1, i), varDate(2, i)

 Next irst.Close End Sub 

Rezultatele vor fi tot cele din figura 8.10, dar, pentru un set cu multeînregistrări, procedura se va executa mult mai repede.

8.7.8. Căutarea înregistrărilorAtunci când doriţi să regăsiţi numai o anumită înregistrare (sau un set de

înregistrări ce satisfac un anumit criteriu), veţi folosi una dintre metodele Seek  sau Find ale setului respectiv. Despre acestea vom vorbi în cadrul secţiunilor următoare.

8.7.8.1. Căutări în seturi de înregistrări de tip tabelă

După ce aţi creat un obiect Recordset de tip tabelă, cea mai rapidă modalitatede a regăsi anumite înregistrări este apelarea metodei Seek . (Apelarea acestei metode pentru un set de înregistrări care nu este de tip tabelă va genera o eroare). Pentruaceasta, trebuie să efectuaţi doi paşi:

1. Stabiliţi valoarea proprietăţii Index a setului, deoarece căutările cu metoda Seek se fac numai pe indecşi.

2. Apelaţi metoda  Seek  dându-i ca argumente un operator de comparaţie(<,<=,>= sau >) şi una sau mai multe valori care să reprezinte criteriile decăutare (în funcţie de numărul coloanelor ce intră în componenţaidexului). Valorile trebuie să corespundă tipurilor de date ale coloanelor indexului.

După ce aţi folosit metoda Seek pentru a căuta o înregistrare, trebuie săverificaţi dacă aţi găsit ceva. Pentru aceasta, veţi verifica valoarea proprietăţii NoMatch a setului de instrucţiuni.Mai reţineţi faptul că metoda Seek returnează numai prima înregistrare care satisfacecriteriul specificat, chiar dacă aceasta nu e singura.Să presupunem că dorim să aflăm nota obţinută de un student la o anumită materie.Pentru aceasta, vom crea un set de înregistrări bazat pe tabela Curs_Student şi vomapela metoda Seek pentru el. În acest scop, vom folosi drept index cheia primară atabelei, care e formată din coloanele NrMatricol şi IdCurs.

Pag. 167

Page 163: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 163/295

 Public Sub SeekStud_Curs(iNrMat As Integer, iIdCurs As Integer) Dim db As Database

 Dim rst As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset(“Curs_Student”)‘stabilim proprietatea Index a setuluirst.Index = “PrimaryKey”‘cautam inregistrarea pentru. care IdCurs=iIdCurs si NrMatricol=iNrMat Rst.Seek “=”, iIdCurs, iNrMat If rst.NoMatch = True Then

‘nu a fost gasita o astfel de inregistrare

   Debug.Print “Studentul cu nr. matricol “ & iNrMat & vbCrLf & _ “nu s-a inscris la cursul “ & iIdCurs Else

Debug.Print “Nota “ & rst!Nota End If rst.Close End Sub

8.7.8.2. Căutări în seturi de înregistrări de tip dynaset şi snapshotSpre deosebire de seturile de tip tabelă, cele dynaset şi snapshot nu pot folosimetoda Seek pentru căutări. Atât pentru acestea din urmă, cât şi pentru căutări dupăcoloane neindexate, Access vă pune la dispoziţie patru metode de căutare a datelor:

Metoda Descriere FindFirst  Începând cu prima înregistrare a setului de înregistrări, caută o

înregistrare ce verifică un criteriu dat. Dacă există, înregistrareagăsită devine cea curentă.

 FindLast  Începând cu ultima înregistrare a setului de înregistrări, caută oînregistrare ce verifică un criteriu dat. Dacă există, înregistrareagăsită devine cea curentă.

 FindNext  Începând cu înregistrarea curentă, caută următoarea înregistrare ceverifică un criteriu dat. Dacă există, înregistrarea găsită devine ceacurentă.

 FindPrevious Începând cu înregistrarea curentă, caută precedenta înregistrare ceverifică un criteriu dat. Dacă există, înregistrarea găsită devine ceacurentă.

Pag. 168

Page 164: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 164/295

Dacă oricare dintre aceste metode nu reuşeşte să găsească o înregistrare caresă verifice criteriul respectiv, setul de înregistrări nu va mai avea o înregistrare curentăşi orice operaţie ulterioară asupra înregistrării curente va genera o eroare.Sintaxa acestor metode va fi următoarea:

rst. {FindFirst|FindPrevious|FindNext|FindLast} criteriu

unde rst este un obiect de tip dynaset sau snapshot, iar criteriu este un şir de caracterece conţine o expresie de genul celor din clauza WHERE a unei instrucţiuni SQL:

rst..FindFirst “NrMatricol = “ & nMatr & “ AND Nota >=5”

Subrutina FindCursuriPromovate() caută toate cursurile la care un student a obţinut

o notă mai mare sau egală cu 5. Dacă nu există nici o înregistrare care să întruneascăacest crietriu, vom afişa un mesaj. Cu ajutorul variabilei nRez  ţinem minte dacă aufost găsite 0, una sau mai multe înregistrări, pentru a afişa un mesaj potrivit pentrufiecare situaţie.

 Public Sub FindCursuriPromovate(nMatr As Integer) Dim db As Database Dim rst As Recordset Dim nPromovate As Integer 

 Dim strRez As String Set db = CurrentDb() Set rst = db.OpenRecordset(“Curs_Student”, dbOpenSnapshot)rst.FindFirst “NrMatricol = “ & nMatr & “AND Nota >=5” Do While rst.NoMatch = False

nPromovate = nPromovate + 1strRez = strRez & vbCrLf & rst!IdCursrst.FindNext “NrMatricol = ” & nMatr & “AND Nota >=5”

 Loop Select Case nPromovateCase 0   Debug.Print “Studentul cu nr. matricol “ & nMatr & vbCrLf & _ 

“nu a promovat nici un curs“Case 1   Debug.Print “Studentul cu nr. matricol “ & nMatr & vbCrLf & _ 

“a promovat cursul: “ & rst!IdCursCase Else   Debug.Print “Studentul cu nr. matricol “ & nMatr & vbCrLf & _ 

“a promovat cursurile “ & strRez End Select 

Pag. 169

Page 165: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 165/295

rst.Close End Sub

8.7.8.3. Criterii ce conţin şiruri de caractere şi dateAtunci când doriţi să creaţi criterii pentru una dintre metodele Find sau atunci

când creaţi în VBA şiruri de caractere ce conţin instrucţiuni SQL, va trebui de multeori să introduceţi într-un asemenea şir valoarea unei variabile. Access cere ca aceastăvariabilă să fie inclusă în şir între separatori ((“) pentru şiruri de caractere şi (#) pentru

date). De exemplu, să presupunem că avem o variabilă, strNume, de tip String, careconţine un nume pe care să-l căutăm într-un set de înregistrări cu ajutorul metodei FindFirst  şi, la un moment dat, valoare ei este “Popescu”. Şirul de caractere careconstituie crietriul de căutare este:

[Nume] = “Popescu”

Pentru a introduce caracterul (“) într-un şir de caractere, trebuie să îl dublăm.

Ţinând cont de aceasta, şirul de caractere care ne dă crietriul de mai sus este:“[Nume] = ““Popescu”””

Separând şirul “Popescu”, care este aici doar un caz particular, vom scrie:

“[Nume] = “”“ & “Popescu” & “”””

Înlocuind acum valoarea “Popescu” cu variabila strNume, obţinem şirul decaractere care ne dă criteriul dorit:

“[Nume] = “”“ & strNume & “”””

Acelaşi lucru este valabil şi pentru date. Astfel, pentru a specifica următorulcriteriu:

[Data Angajarii] = varData

unde varData este o variabilă de tip Date, vom construi următorul şir de caractere:

“[Data Angajarii = #” & varData & “#”

Pag. 170

Page 166: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 166/295

Data pe care o conţine variabila varData trebuie să fie în formatul mm/dd/yy,altfel, nu veţi obţine rezultatul dori. Vă reamintim că pentru a converti o dată laformatul mm/dd/yy, puteţi folosi funcţia Format :

Format (varData, “mm/dd/yy”)Pentru criterii ce conţin valori numerice, totul este mult mai simplu, astfel că

 pentru a avea următorul criteriu:

[IdCurs] = nCurs

vom scrie şirul de caractere:

“[IdCurs] = “ & nCurs

8.7.9 Semne de carteÎn plus faţă de metodele pentru parcurgerea unui set de înregistrări, Access vă

mai pune la dispoziţie şi proprietatea  Bookmark  (semn de carte) a unui astfel deobiect. După cum aţi văzut, fiecare set are o singură înregistrare curentă. UnBookmark este o proprietate a cărei valoare identifică unic înregistrarea curentă a

setului la un moment dat. Puteţi atribui această valoare unei variabile de tip String sauVariant pentru a o folosi ulterior la regăsirea înregistrării respective. Mai exact:1. Regăsiţi valoarea proprietăţii Bookmark a înregistrării curente şi o stocaţi

într-o variabilă de tip String sau Variant.2. Pentru a vă întoarce ulterior la acea înregistrare, daţi proprietăţii

 Bookmark valoarea stocată anterior.Astfel, puteţi păstra oricâte semne de carte doriţi pentru un anumit set de

înregistrări. Lucrul cu semne de carte este metoda cea mai simplă de deplasare întreînregistrările unui set.

În mare, iată cum veţi folosi în codul dumneavoastră proprietatea Bookmark aunui set de înregistrări:

 Dim strBM As StringstrBM = rst.Bookmark ‘ne deplasam la ultima inregistrarerst.MoveLast ‘…efectuam diferite operatii si apoi revenim de unde am plecat rst.Bookmark = strBM 

De multe ori veţi dori, poate, să comparaţi două semne de carte pentru a vedeadacă înregistrarea curentă este aceeaşi cu cea pentru care aţi salvat un semn de carte.

Pag. 171

Page 167: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 167/295

Pentru aceasta, trebuie să ştiţi că, deşi puteţi stoca un semn de carte într-o variantă detip String sau Variant, ea este reprezentată intern ca o matrice de biţi. De aceea, atuncicând comparăm două semne de carte, comparaţia trebuie să fie făcută pe biţi. Pentruaceasta, puteţi folosi funcţia predefinită StrComp, care returnează valoarea 0 dacă celedouă variabile comparate sunt egale şi care primeşte un al treilea argument (primele

două sunt variabile de comparat), ce specifică modul în care se va face comparaţia: 0 pentru compraţie pe biţi, 1 pentru comparaţia obişnuită (care nu e case-senzitivă, adicănu ţine cont de majuscule/minuscule), 2 pentru a folosi tipul de comparaţie specificatde opţiunea Option Compare de la secţiunea (General)(Declarations) a modulului.De exemplu, dacă strBM1 şi strBM2 sunt două semne stocate anterior,

NRez = StrComp(strBM1, strBM2, 0)

 NRez va avea valoarea 0 dacă cele două semne de carte coincidşi o valoare diferite dezero, altfel.Seturile de înregistrări bazate pe tabele native Access acceptă proprietatea

 Bookmark , spre deosebire de cele bazate pe tabele din alte baze de date (Paradox, deexemplu). De aceea, înainte de a folosi semne de carte pentru un obiect de tipRecordset, este bine să testaţi dacă el acceptă această proprietate. În acest scop,verificaţi dacă proprietatea Bookmarkable a setului are valoarea True.

8.7.10 Metoda Clone (clonare)Orice set de înregistrări are o singură înregistrare curentă. Dacă doriţi sălucraţi cu două înregistrări curente pe acelaşi set de date, puteţi folosi metoda clone pentru a crea o clonă a setului. Astfel, vom avea două obiecte de tip Recordsetindicând spre acelaşi set de înregistrări. Această metodă este mult mai rapidă decâtdacă am crea un al doilea set bazat pe aceleaşi date. Atunci când lucraţi cu clone,ţineţi cont de următoarele două probleme:

1. Un set de înregistrări creat cu metoda Clone nu are de la început oînregistrare curentă. Pentru că o înregistrare a sa să devină curentă, apelaţiuna dintre metodele  Find  sau Move sau daţi proprietăţii  Bookmark  ovaloare regăsită din setul original.

2. Folosirea ulterioară a metodei Clonei pentru setul original sau pentru celclonat nu îl afectează pe cel clonat sau, respectiv, pe cel original.

8.7.11 Proprietatea RecordsetCloneDacă metoda Clone este folosită mai ales pentru a lucra cu două înregistrări

curente ale aceluiaşi set de date, vom folosi proprietatea RecordsetClone pentru a aveaacces la setul de înregistrări al unui formular. Acest lucru este util atunci când dorimsă manipulăm setul de date pe care se bazează un formular, fără ca acţiunile noastre săfie vizibile pe formular.

Pag. 172

Page 168: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 168/295

Pentru a ilustra cum se lucrează cu metoda Clone şi cu proprietatea RecordsetClone, vom scrie funcţia ComparaInreg() ce verifică dacă două înregistrărisuccesive ale unui set de înregistrări au aceeaşi valoare pentru un anumit câmp.Funcţia primeşte ca argumente variabila frm de tip Form (ce va identifica formularul)şi variabila strCamp de tip String (ce conţine numele câmpului respectiv) şi returnează

valoarea True dacă înregistrarea curentă şi cea anterioară conţin aceeaşi valoare acâmpului identificat de argumentul strColoana şi False, altfel.

Function ComparaInreg(frm As Form, strCamp as string) As Boolean Dim rst As Recordset Dim rstClona As Recordset‘obtinem un pointer la setul de inregistrari al formularului

 Set rst = frm.RecordsetClone

‘sincronizam setul astfel obtinut cu originalul rst.Bookmark = frm.Bookmark ‘pentru a putea lucra cu doua inregistrari curente,‘clonam setul obtinut anterior si le sincronizam Set rstClona = rst.ClonerstClona.Bookmark = rst.Bookmark ‘daca inregistrarea curenta este prima, returnam valoarea FalserstClona.MovePrevious If rstClona.BOF Then

ComparaInreg = False Else‘daca inregistrarea curenta nu este prima,‘efectuam comparatia cu cea precedenta ei‘si returnam rezultatul ComparaInreg = (rst(strCamp) = rstClona(strCamp))

 End If rstClona.Close End Function

Înregistrarea curentă a setului de înregistrări clonat (rstClona) va fiîntotdeauna cea precedentă înregistrării curente a setului rst . Iată deci, cum putemlucra cu două înregistrări curente pentru a compara valorile câmpurilor unui set, fără aavea nevoie de variabile în care să păstrăm valorile regăsite. Această funcţie poate fi,de exemplu, apelată din cadrul procedurii de tratare a evenimentului Current a unuiformular, pentru a afişa un anumit mesaj sau pentru a efectua diferite alte acţiuni înfuncţie de valoarea returnată.

8.7.12 Sortarea şi filtrarea unui set de înregistrăriPentru a sorta un set de înregistrări de tip tabelă, nu trebuie decât să-i stabiliţi

 proprietatea  Index. Vă reamintim că atunci când creaţi un index pe o tabelă, puteţi

Pag. 173

Page 169: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 169/295

specifica ordinea de sortare crescătoare sau descrescătoare pentru indexul respectiv.Setul va fi sortat exact după ordinea specificată de index.

Pentru a crea un set de înregistrări sortat de tip dynaset sau snapshot, puteţi proceda în două moduri:

1. Să creaţi setul pe baza unei instrucţiuni SQL ce conţine clauza ORDER 

BY:Set rst = db.OpenRecordset(“SELECT * FROM Profesor ORDER BY Nume;”)

2. Să stabiliţi proprietatea Sort pentru dynaset sau snapshot şi apoi să creaţiun nou set pe baza celui sortat.

Valoarea proprietăţii Sort este un şir de caractere conţinând coloana după carese va face sortarea şi, opţional, ordinea de sortare (ordinea ascendentă este implicită):

rst.Sort = “[Nume]”rst.Sort = “[Nume] Asc” ‘ascendentrst.Sort = “[Nume] Desc” ‘descendent

Iată un exemplu în care creăm un set de înregistrări (rst), îl sortăm şi apoicreăm unul nou (rstSortat ) pe baza lui:

 Dim db As Database Dim rst As Recordset Dim rstSortat As Recordset Set db = CurrentDb() Set rst = db.OpenRecordset(“Profesor”, dbOpenDynaset)rst.Sort = “[Nume]” Set rstSortat = rst.OpenRecordset()‘…efectuam diferite operatii cu rstSortat rst.CloserstSortat.Close

Pentru a filtra un set de înregistrări,aveţi de asemenea la dispoziţie două posibilităţi:

• Să creaţi setul pe baza unei instrucţiuni SQL ce conţine clauzaWHERE. Această metodă poate fi folosită numai pentru a creaseturi pe baza unui obiect din baza de date.• Să stabiliţi proprietatea Filter a unui dynaset sau snapshot pentru a-i restrânge numărul de înregistrări şi apoi să creaţi un nou

set pe baza acestuia.Valoarea proprietăţii Filter trebuie să fie un şir de caractere asemănător unei expresiidin clauza WHERE a unei instrucţiuni SELECT.

Pag. 174

Page 170: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 170/295

Iată un exemplu ce creează câte un set de înregistrări folosind cele două metode maisus amintite:

 Dim db As Database Dim rst As Recordset

 Dim rstSQL As Recordset Dim rstFiltrat As Recordset Set db = CurrentDb()

‘folosim prima metoda Set rstSQL = db.OpenRecordset(“SELECT FROM Profesor WHERE[Catedra]_ = “”Matematici””;”)

‘folosim a doua metoda

 Set rst = db.OpenRecordset(“Profesor”, dbOpenDynaset)rst.Filter = “[Catedra] = “”Matematici””” Set rstFiltrat = rst.OpenRecordset()…

Atunci când folosiţi proprietatea Sort sau Filter a unui set de înregistrări, ţineţicont de următoarele:

•  Ele nu se aplică seturilor de tip tabelă;• Sortarea sau filtrarea sunt vizibile numai pentru setul creat pe baza

celui sortat sau filtrat;• Crearea seturilor pe baza instrucţiunilor SQL poate fi mai rapidădecât folosirea proprietăţilor  Sort   şi  Filter .

8.7.13 Editarea înregistrărilor unui set de înregistrăriPentru a putea modifica datele unui set de înregistrări trebuie, mai întâi, să

aveţi dreptul să faceţi asta. Seturile de tip tabelă sau dynaset pot fi modificate numaidacă altcineva nu a blocat tabela respectivă (în cazul aplicaţiilor multiuser). Seturile

snapshot şi seturile bazate pe interogări de tip Crosstab sau Union nu permitmodificarea datelor. Pentru a vă asigua că puteţi modifica datele unui set deînregistrări, verificaţi dacă proprietatea sa Updatable are valoarea True.

Access vă pune la dispoziţie cinci metode pentru editarea datelor dintr-un setde înregistrări:

Metoda Descriere Edit  Copiază înregistrarea curentă dintr-un buffer pentru a permite

editarea.

 AddNew Creează o nouă înregistrare dintr-un buffer.Update Salvează modificările din buffer.CancelUpdate Goleşte bufferul fără a salva modificările.

Pag. 175

Page 171: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 171/295

 Delete Şterge înregistrarea curentă.

Pentru a vedea dacă în buffer există vreo înregistrare care nu a fost salvată, puteţi verifica valoarea proprietăţii EditMode, care poate fi:

Valoarea Constantaintrinsecă Descriere

0 dbEditNone Bufferul e gol1 dbEditInProgress Bufferul conţine înregistrarea curentă (s-a apelat

metoda Edit )2 dbEditAdd  Bufferul conţine o înregistrare nouă (s-a apelat

metoda AddNew)

8.7.13.1. Modificarea înregistrării curentePentru a edita înregistrarea curentă a unui set de înregistrări (presupunând că puteţi face acest lucru), trebuie să efectuaţi următoarele operaţii:

1. Apelaţi metoda Edit pentru a copia înregistrarea curentă în buffer.2. Efectuaţi modificările dorite.3. Apelaţi metoda Update pentru a salva modificările.

Să presupunem că în tabela Profesor s-a introdus greşit numele unui profesor: în loc

de “Popescu Marian” s-a introdus “Popescu Marin”. Pentru a rectifica din programaceastă eroare, creaţi setul rst   bazat pe tabela Profesor şi scrieţi:

With rst‘cautam inregistrarea pe care dorim s-o editam.FindFirst “[Nume] = “”Popescu Marin”””‘daca nu o gasim, afisam un mesaj If .NoMatch Then

MsgBox “Popescu Marin nu se afla in tabela Profesor”

‘altfel, o editam Else.Edit![Nume] = “Popescu Marian”.Update

 End If  End With

8.7.13.2 Adăugarea unei noi înregistrări la un set de înregistrăriPentru a adăuga o nouă înregistrare la un set (presupunând că puteţi face acest

lucru), procedaţi astfel:1. Apelaţi metoda  AddNew pentru a adăuga o nouă înregistrare (valorilecâmpurilor vor fi cele implicite, dacă există valori implicite).

Pag. 176

Page 172: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 172/295

2. Introduceţi valorile câmpurilor.3. Apelaţi metoda Update pentru a salva înregistrarea.Înregistrarea curentă, după ce aţi adăugat o nouă înregistrare, va fi tot cea

dinainte acestei operaţii. De aceea, pentru ca înregistrarea să fie curentă să fie ceanouă, apelaţi metoda  Move cu valoarea proprietăţii  LastModified  a setului ca

argument.Următorul exemplu adaugă o nouă înregistrare la un set bazat pe tabelaProfesor şi face ca înregistrarea curentă să fie cea nouă.

With .rst.AddNew

![Nume] = “Toma Dorel”![Catedra] = “Fizica”![IdTitlu] = 2

.Update.Move 0, .LastModified End With

8.7.13.3 Ştergerea unei înregistrări a unui set de înregistrăriPentru a şterge înregistrarea curentă a unui set nu trebuie decât să apelaţi

metoda  Delete. După ce aţi şters o înregistrare, ea continuă să fie cea curentă. MovePrevious pentru ca înregistrarea precedentă să fie cea curentă.

Pentru a şterge înregistrarea corespunzătoare profesorului cu numele “PopescuMarin” dintr-un set bazat pe tabela Profesor, scrieţi:

With .rst.FindFirst “[Nume] = “”Popescu Marin”””If .NoMatch Then

MsgBox “Popescu Marin nu se afla in tabela Profesor”   Else

.Delete

.MovePreviousEnd If 

 End With

8.8. Obiecte specialeExistă anumite proprietăţi ale unor obiecte care reprezintă, la rândul lor, alte

obiecte. Aţi făcut deja cunoştinţă cu proprietăţile Me şi RecordsetClone. Tabelul 8.16vă prezintă alte proprietăţi ce reprezintă obiecte.

Proprietatea A cui este Ce reprezintă ActiveControl  Ecran (Screen) Controlul care are focusul.

Pag. 177

Page 173: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 173/295

 ActiveForm Ecran (Screen) Formularul care are focusul sau care conţinecontrolul cu focus.

 ActiveReport  Ecran (Screen) Raportul care are focusul sau care conţinecontrolul cu focus.

 Form Subformular,

formular saucontrol

Pentru un control de tip Subform, reprezintă

subformularul găzduit. Pentru un formular,reprezintă formularul însuşi. Me Formular sau

raportÎnsuşi formularul sau raportul respectiv.

 Module Formular sauraport

Modulul asociat formularului sau raportuluirespectiv.

 Parent  Control Formularul sau raportul ce conţine controlulrespectiv.

 PreviousControl  Formular Controlul care a avut anterior focusul.

 RecordsetClone Subraport,raport saucontrol

Setul de înregistrări pe care se bazeazăformularul.

 Report  Pentru un control de tip Subreport, reprezintăsubraportul găzduit. Pentru un raport, reprezintăraportul însuşi.

Section Control Secţiunea formularului sau raportului în care seaflă controlul.

Tabelul 8.16

CAP:9. Crearea şi lucrul cu rapoartele

Rapoartele reprezintă o metodă prin care datele pot fi prezentate într-un modintuitiv şi plăcut. Ele pot fi tipărite, vizualizate sau exportate într-un alt format. Deşiîntre formulare şi rapoarte există multe asemănări, una dintre deosebiri este aceea cărapoartele nu pot fi folosite pentru introducerea datelor. Raportele pot să conţinăaproape toate elementele unui formular, cu excepţia controalelor care presupun acţiuni

ale utilizatorului, cum ar fi cele de tip Comba box. Puteţi să convertiţi formularele înrapoarte şi vice-versa făcând clic dreapta pe numele formularului sau al raportului în

Pag. 178

Page 174: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 174/295

fereastra Database şi alegând opţiunea Save As Report (sau Save As Form) din meniulderulant.

Datele unui raport pot proveni dintr-o tabelă, o interogare sau o instrucţiuneSQL.

9.1 Crearea unui raportPentru a crea un nou raport, Access vă pune la dispoziţie două programe

wizard, Auto Report şi Report Wizard . Acestea sunt utile mai ales atunci când sursade date a raportului este simplă sau pentru a crea un raport de pornire pe care să îl perfecţionaţi ulterior, manual.

9.1.1. Crearea rapoartelor cu ajutorul programelor WizardPentru a crea un formular în mai puţin de un minut, nu trebuie decât să apăsaţi

 butonul New din pagina Reports a ferestrei Database şi să alegeţi din cutia de dialog  New Report una dintre opţiunile  AutoReport  (Columnar, pentru ca datele să fie prezentate pe o singură coloană sau Tabular, pentru prezentarea datelor sub formă detabel). În plus, mai trebuie să selectaţi numele unei tabele sau interogări din casetacombinată a acestei cutii de dialog. După ce aţi apăsat butonul OK, raportul creat va fiafişat pe ecran în modul Print Preview.

Pentru a crea însă un raport mai elaborat, vom folosi  Report Wizard . Să presupunem că dorim să creăm un raport care să prezinte, pentru fiecare student,cursurile opţionale la care s-a înscris. Vom crea raportul pe baza interogării

Student_Cursuri, din figura 9.1:

Fig. 9.1

Pag. 179

Page 175: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 175/295

De data aceasta, alegeţi din cutia de dialog New Report opţiunea ReportWizard. În prima cutie de dialog, alegeţi din caseta combinată Tables/Queriesinterogarea Student_Cursuri şi apăsaţi butonul (>>) pentru a selecta toate câmpurileacestei interogări, prezentate în lista Available Fields.

Fig. 9.2

Cea de-a doua cutie de dialog din wizard vă întreabă în funcţie de care date săse facă gruparea: de cele din tabela Curs, de cele din tabela Curs_Student sau de celedin tabela Student. Deoarece dorim să vedem cursurile la care s-a înscris fiecarestudent şi nu studenţii care s-au înscris la fiecare curs, vom alege ca gruparea să se

facă în funcţie de tabele Student.

Fig. 9.3

Următoarea cutie de dialog vă permite să stabiliţi şi alte niveluri de grupare a

datelor. După cum puteţi vedea, deja există două niveluri: primul conţine informaţiidespre un student: NrMatricol, NumeSt, PrenumeSt, Grupa, iar al doilea, desprecursurile la care acesta s-a înscris: Denumire şi Nota. Să zicem că am dori

Pag. 180

Page 176: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 176/295

ca, la rândul lor studenţii să fie grupaţi în funcţie de grupa în care se află. Pentruaceasta, selectaţi coloana Grupa din lista din stânga cutiei de dialog şi apăsaţi butonul(>).

Fig. 9.4

 Nu este prea târziu încă să vă răzgândiţi asupra ordinii în care vor fi grupate

datele. Pentru aceasta puteţi folosi butoanele Priority (↑ şi ↓). Pentru acest exemplu păstraţi totuşi ordinea din figura 9.5 şi apăsaţi butonul Next.

Fig. 9.5

Dacă la pasul anterior am stabilit după care coloane se va face grupareadatelor, în această cutie de dialog putem stabili ordinea în care vor fi afişate datele de pe ultimul nivel: Denumire şi Nota. Să zicem că preferăm să afişăm cursurile în

Pag. 181

Page 177: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 177/295

ordinea alfabetică a denumirii lor. Pentru aceasta, va trebuie să alegeţi în prima casetăcombinată coloana Denumire. Dacă doriţi să schimbaţi ordinea de sortare, apăsaţi pe butonul din dreapta casetei combinate. Tot în această cutie de dialog există şi butonulSummary Options, care deschide o altă cutie de dialog. Aici puteţi alege ca pentru o

coloană de pe ultimul nivel să se afişeze şi suma, media, minimul sau maximul.

Fig. 9.6

Următoarele două cutii de dialog vă prezintă câteva variante de aliniere adatelor şi, respectiv, câteva stiluri de fonturi folosite pentru afişarea lor (pentru acest

exemplu vom alege alinierea în trepte (Stepped) şi stilul Compact). În ultima cutie dedialog din wizard introduceţi numele raportului (Student_Cursuri) şi apăsaţi butonulFinish. Raportul se va deschide în modul Print Preview şi va arăta în genul celui dinfigura 9.7.

Fig. 9.7

Pag. 182

Page 178: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 178/295

9.1.2. Crearea manuală a rapoartelorDacă vă decideţi să creaţi manual un raport, pornind de la zero, alegeţi în cutia

de dialog New Report opţiunea Design View. Se va deschide în modul Design Viewun raport fără nici un control pe el. Dacă aţi învăţat cum să proiectaţi un formular,

crearea manuală a unui raport o să vi se pară foarte uşoară. Vom avea de-a face cuaceleaşi categorii de secţiuni, aceleaşi tipuri de controale şi aceleaşi ferestre suport:ToolBox (cutia cu instrumente), Field List (lista câmpurilor) şi Properties (pagina de proprietăţi). Singurul element nou îl constituie fereastra Sorting and Grouping (sortareşi grupare) care vă va ajuta să stabiliţi nivelurile de grupare şi ordinea în care vor fiafişate datele. Figura 9.8 prezintă formularul Student_Cursuri în modul Design View.

Fig. 9.8

9.2. Sursa de date a raportului

Atunci când creaţi un nou raport în Access, aveţi posibilitatea de a alege sursade date a acestuia din caseta combinată a cutiei de dialog New Report. Această sursăde date poate fi tabelă sau interogare salvată. Pentru raportul pe care l-am creatanaterior, sursa de date este interogarea Student_Cursuri. Ca şi în cazul formularelor,

sursa de date este specificată de proprietatea Record Source, după cum puteţi vedea şidin pagina de proprietăţi a raportului Student_Cursuri (figura 9.9).

Pag. 183

Page 179: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 179/295

Fig. 9.9

Puteţi schimba ulterior sursa de date a unui raport, modificând valoarea acestei proprietăţi.

Pentru ca informaţiile stocate într-un câmp al sursei de date să poată fi afişate

în raport, trebuie ca grila în QBE proprietatea Show a câmpului respectiv şă fieactivată. Dacă interogarea pe care se bazează raportul are parametri, pentru a puteavizualiza sau tipări raportul, utilizatorul trebuie să furnizeze valorile parametrilor respectivi.

9.3. Secţiunile unui raport

În figura 9.10 puteţi vedea secţiunile raportului Student_Curs şi, după cum

v-aţi dat seama, ele nu sunt cu mult diferite de secţiunile unui formular.

Fig. 9.10

• Report Header  – Apare numai pe prima pagină, ca un titlu pentruîntregul raport. Dacă doriţi să creaţi o pagina separată numai pentru titlulraportului, alegeţi ca valoare a proprietăţii ForceNewPage a acesteisecţiuni opţiunea After Section (după secţiune).

• Page Header – Apare în partea de sus a fiecărei pagini, cu excepţia  primeia, unde apare după antetul raportului. Cel mai adesea, conţinetitlurile câmpurilor afişate.

Pag. 184

Page 180: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 180/295

• Detail – Se repetă pantru fiecare înregistrare la vizualizarea sau latipărirea raportului. S-ar putea ca la proiectarea raportului să nu ştiţi exactcât de înaltă trebuie să fie secţiunea Detail. De exemplu, este foarte posibilca o înregistrare să nu aibă nimic într-un câmp de tip memo, în timp ce altăînregistrare să ocupe o jumătate de pagină sau chiar mai mult. Proprietăţile

Can Grow (poate creşte) şi Can Shrink (se poate micşora) ale secţiuniiDetail determină pentru aceasta o înălţime variabilă, în funcţie de fiecareînregistrare în parte.• Page Footer – Apare în partea de jos a fiecărei pagini a raportului. Celmai adesea conţine data şi ora şi, eventual, numărul paginii. Observaţi, dinfigura 9.10, că secţiunea Page Footer a raportului Student_Cursuri conţinedouă casete de text, ce au ca surse de date expresiile: Now () şi

=”Page “ & [Page] & “ of “ & [Pages]Prima afişează data curentă, iar cea de-a doua, pagina curentă din

numărul total de pagini ale raportului. Variabila [Page] are ca valoare numărul paginii curente, iar variabila [Pages], numărul total de pagini. Pentru a tipăriaceste informaţii în subsolul de pagină al unui raport, alegeţi opţiunile Page Numbers şi, respectiv, Date and Time din meniul Insert.

Report Footer – Apare numai pe ultima şi poate conţine totaluri ale datelor diverselor secţiuni ale raportului. Pentru a afişa totalul unui control numeric, adăugaţi la aceastăsecţiune o casetă text, a cărei proprietate Control Source să aibă valoarea:=Sum([Nume_Control]). Dacă doriţi ca totalurile să fie afişate pe o pagină separată lasfârşitul raportului, daţi proprietăţii ForceNewPage a acestei secţiuni valoarea Before

Section (înaintea secţiunii).În plus, faţă de aceste secţiuni pe care le-am întâlnit şi la crearea formularelor,un raport poate avea un număr de antete şi subsoluri de grup, care să afişeze titlurilecâmpurilor ce definesc grupul respectiv şi totaluri în cadrul grupului.

9.4. Proprietăţile unui raport

Pentru a deschide pagina de proprietăţi a unui raport, procedaţi exact ca încazul formularelor: faceţi clic pe careul negru din colţul din stânga-sus al raportului înmodul Design View şi alegeţi comanda Properties din meniul View. În continuare, vă prezentăm câteva dintre proprietăţile cu care veţi lucra cel mai des pentru a determinacomportamentul raportului.

• Record Source  – Sursa de date a raportului poate fi o tabelă, o

interogare sau o instrucţiune SQL.

Pag. 185

Page 181: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 181/295

• Filter: - Numele unei interogări (sau al unei instrucţiuni SQL) carelimitează numărul de înregistrări din tabela de bază ce vor fi afişate înraport.

• Filter On: - Dacă are valoarea Yes, filtrul definit de proprietatea Filter se va aplica.

• Order By: - Un câmp sau o listă de câmpuri separate prin virgule, dinsursa de date a raportului în funcţie de care va fi stabilită ordinea în carevor fi afişate datele.

• Order By On: - Dacă are valoarea Yes, se va face sortarea stabilită de proprietatea Order By.

• Caption: - Numele care apare în bara de titlu a formularului în modulPrint Preview.

• Record Locks: - Dacă are valoarea All Records (toate înregistrările),

alţi utilizatori nu vor putea modifica datele din tabelele de bază aleraportului atâta timp cât acesta nu este vizualizat sau tipărit (pentru aplicaţimultiuser).

• Page Header şi Page Footer: - Stabileşte dacă antetul şi/sau subsolulde pagină va fi tipărit şi pe paginile în care apare antetul şi/sau subsolulraportului.

• Picture: - Dacă doriţi ca pe fundalul raportului să apară o imagine, aici puteţi introduce numele şi calea unui fişier cu extensia .bmp, .dib, .wmf sau .emf.

• Picture Type: - Determină dacă imaginea specificată de proprietateaPicture va fi salvată în baza de date sau va fi păstrată într-un fişier separat.

• Picture Size Mode: - Determină în ce mod imaginea specificată de proprietatea Picture va fi micşorată în cazul în care nu încape în pagină.

• Picture Alignment: - Arată dacă imaginea specificată de proprietatea picture va fi centrată sau aliniată la stânga sau dreapta paginii.

• Picture Tiling: - Dacă imaginea specificată de proprietatea Pictureeste mai mică decât pagina, ea se va repeta pe toată pagina.

• Picture Pages: - Determină dacă imaginea specificată de proprietateaPicture va fi tipărită pe toate paginile, numai pe prima, sau pe nici una.

• Layout for Print: - Dacă are valoarea Yes, la proiectarea raportului nuveţi putea folosi decât fonturile native ale imprimantei şi pe cele TrueType.

Cea mai bună cale de a descoperi cum lucrează proprietăţile unui raport estetotuşi să le testaţi cu diferite valori pe care le pot lua.

9.5. Sortarea şi gruparea datelor

Pag. 186

Page 182: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 182/295

Dacă veţi alege comanda Sorting and Grouping din meniul View, întimp ce raportul Student_Cursuri este deschis în modul Design View, se va deschidecutia de dialog prezentată în figura 9.11.

Fig. 9.11

Posibilitatea de grupa şi de a sorta înregistrările este ceea cedeosebeşte rapoartele de formulare. Cutia de dialog din figura 9.11. vă permite săstabiliţi ordinea de sortare a înregistrărilor. Cheia de sortare cea mai semnificativă seaflă pe prima poziţie din lista Field/Expression (Grupa, în acest exemplu). Urmeazăapoi coloanele NrMatricol şi, respectiv, Denumire. Cu alte cuvinte, pentru fiecaregrupă, se vor afişa toţi studenţii, în ordinea crescătoare a numerelor lor matricole şi,  pentru fiecare student, se vor afişa cursurile la care acesta s-a înscris, în ordineaalfabetică a denumirilor lor. Dacă veţi dori să inversaţi ordinea de sortare pentru unanumit câmp din această listă, alegeţi în câmpul corespunzător din coloana Sort Order cealaltă opţiune (Descending (descendentă) dacă iniţial ordinea era Ascending(ascendentă) şi invers). Pentru fiecare câmp din listă puteţi stabili cinci proprietăţi:

• Group Header: Dacă are valoarea Yes, Access va crea pentru acest

câmp o secţiune antet, în care puteţi include ce controale doriţi. Deexemplu, pentru coloana Grupa, acest antet conţine o casetă de text careare ca sursă de date chiar această coloană.

• Group Footer: Dacă are valoarea Yes, Access va crea pentru acestcâmp o secţiune subsol, unde aţi putea include controale care să afişezediferite totaluri pentru grupul respectiv. Deocamdată, nici unul dintregrupurile definite nu are subsol, dar în cadrul acestui capitol, vom adăugaunul.

• Group On: Dacă valoarea sa este Each Value, Access va considera ca

făcând parte din acelaşi grup doar înregistrările pentru care valorile

Pag. 187

Page 183: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 183/295

câmpului respectiv sunt egale. Cu alte cuvinte, pentru fiecare valoare acâmpului, Access va crea un grup separat care, eventual, va avea un antetşi/sau un subsol. Dacă valoarea sa este Interval (pentru câmpuri numerice),grupurile se vor extinde la toate înregistrările pentru care valoarea câmpuluirespectiv se află într-un interval specificat. Pentru câmpuri de tip text, avem

opţiunea Prefix Characters care va considera ca făcând parte din acelaşi gruptoate înregistrările pentru care valoarea câmpului respectiv începe cu aceleaşin caractere, unde n este valoarea proprietăţii Group Interval. De asemenea,  pentru coloane de tip sate/time, această proprietate mai poate avea valorile“Year”, “Quarter”, “Month” etc., înregistrările putând fi astfel grupate pe ani,trimestre, luni etc.

• Group Interval: Dacă valoarea proprietăţii Group On este alta decât“Each Value”, proprietatea Group Interval defineşte intervalul în care se poate afla valoarea câmpului respectiv pentru a face parte dintr-un grup.

• Keep Together: Dacă are valoarea No, Access va trece la o paginănouă numai atunci când pagina curentă este plină. Dacă are valoareaWhole Group (întregul grup), Access va face tot posibilul ca antetul,subsolul şi secţiunea Detail a grupului să se afle pe aceeaşi pagină. Dacăele nu încap în pagina curentă, se va trece la o pagină nouă. Dacă arevaloarea With First Detail (numai primul detaliu), Access va trece la o pagină nouă dacă antetul şi cel puţin prima înregistrare de la secţiuneaDetail a grupului nu încap pe pagina curentă.

9.6. Folosirea funcţiilor agregat în cadrul rapoartelor

Raportul Student_Cursuri ar furniza mai multă informaţie dacă ar afişa, pentrufiecare student, media cursurilor opţionale la care s-a înscris. Am mai spus că cel mai bun loc pentru a afişa totaluri este subsolul unei secţiuni sau al unui grup. Pentruexemplul nostru, media ar trebuie să fie afişată în subsolul grupului determinat decoloana NrMatricol dar, după cum puteţi vedea şi în figura 9.10, acest grup nu aresubsol. Pentru a adăuga un subsol pentru grupul NrMatricol, deschideţi fereastraSorting and Grouping şi daţi proprietăţii Group Footer a acestui grup valoarea Yes.

Access va crea subsolul NrMatricol Footer şi îl va plasa între secţiunea Detail şisecţiunea Page Footer. Acum nu mai trebuie decât să plasaţi în acest subsol o casetăde text şi să daţi proprietăţii RecordSource ca valore expresia:

=Avg ([Nota])

Eventual, daţi proprietăţii Caption a etichetei asociate valoarea “Media:” iar  proprietăţii Name a casetei, valoarea txtMedia. Acum formularul deschis în modulDesign View va arăta ca în figura 9.12:

Pag. 188

Page 184: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 184/295

Fig. 9.12

Cel mai important lucru, atunci când folosim funcţii agregat în rapoarte, esteacela că Access restrânge numărul de înregistrări pentru care se face agregarea numai

la grupul curent. Astfel, dacă includeţi o funcţie agregat în cadrul antetului sausubsolului unui grup, vor fi luate în considerare numai înregistrările care fac parte dinacel grup. Dacă o includeţi la secţiunea Page Header sau Page Footer, funcţia va lua înconsiderare numai înregistrările din pagina respectivă, iar dacă o includeţi la secţiuneaReport Header sau Report Footer, funcţia va calcula totalul pentru toate înregistrărileraportului. Astfel, puteţi crea atâtea sub-totaluri câte grupuri are raportul.

Alte funcţii agregat pe care le veţi folosi frecvent sunt: Sum([câmp_numeric])(pentru calcularea sumelor), Count([câmp_numeric]) (pentru a număra înregistrările),Min([câmp_numeric]) (pentru a afla minimul) şi Max([câmp_numeric]) (pentru a afla

maximul). Puteţi, de asemenea, să creaţi expresii în care să folosiţi funcţii agregat şisă le afişaţi drept totaluri:

=Sum([Nota]) / Count([Denumire])

9.7. Editarea rapoartelor

Am creat mai devreme raportul Student_Cursuri folosind Report Wizard şi,

apoi, i-am adăugat o casetă de text a cărei sursă de date este o funcţie agregat. Deşiraportul ne oferă multe informaţii utile, aspectul său ar mai putea fi îmbunătăţit:

Pag. 189

Page 185: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 185/295

titlurile coloanelor ar putea fi schimbate (Access a folosit numele câmpurilor, care nusunt întotdeauna intuitive şi prezentabile); formatul în care sunt afişate mediile ar 

trebui modificat astfel încât să aibă numai două zecimale; am putea evidenţia anumite

texte şi, eventual, am putea introduce numere de ordine.Bineînţeles că toate aceste modificări nu vor putea fi făcute decât în modulDesign View. Pentru a schimba titlurile coloanelor, selectaţi etichetelecorespunzătoare de la secţiunea Page Header şi, în pagina lor de proprietăţi, modificaţi proprietatea Caption: în loc de “NumeSt” şi “PrenumeSt”, introduceţi, de exemplu,doar “Nume” şi “Prenume”, iar în loc de “Denumire”, introduceţi “Cursuri”. Chiar şititlul raportului ar putea fi îmbunătăţit, din “Student_Cursuri” în “Studenti si Cursuri”.Probleme de aspect ar mai putea ridica şi alinierea textului în controale. Dacă proprietatea “Text Align” (alinierea textului) a unei etichete are valoarea “General”,

textul va fi aliniat la stânga controlului, iar dacă aceeaşi proprietate a unei casete detext are această valoare, textele vor fi aliniate la stânga iar valorile numerice sau de tipdate/time vor fi aliniate la dreapta. Pentru a schimba aceste valori, alegeţi explicit unadintre celelalte valori ale proprietăţii Text Align: “Left” (la stânga), “Center” (centrat)şi “Right” (la dreapta).

Pentru ca mediile să fie afişate cu exact două zecimale, selectaţi cutia de texttxtMedia adăugată la secţiunea anterioară şi daţi proprietăţii Format valoarea “Fixed”iar proprietăţii Decimal Places, valoarea 2. De asemenea, media fiind o informaţieimportantă, ar fi bine să o evidenţiem într-un fel. Pentru aceasta, daţi proprietăţii Font

Weight a casetei de text valoarea “Bold” şi, astfel, mediile vor fi scrise îngroşat.Un alt element des întâlnit în rapoarte îl reprezintă numerele de ordine. Să presupunem că în dreptul fiecărui student dorim să apară al câtelea este în cadrulraportului. Pentru aceasta, adăugaţi la secţiunea “NrMatricol Header” o nouă casetă detext (ştergeţi eticheta asociată, deoarece nu ne trebuie), a cărei proprietate ControlSource să fie =1. Pentru ca numărul de ordine să fie incrementat cu unu la fiecarestudent, daţi proprietăţii Running Sum a acestei casete de text valoarea “Over All”.Dacă am fi dorit ca numerotarea să reînceapă pentru fiecare grupă, valoarea proprietăţii Running Sum ar fi trebuit să fie “Over Group”.

Dacă observaţi că pentru anumite valori ale înregistrărilor textul care trebuiesă apară într-un control nu se vede în întregime deoarece controlul nu este suficient demare, daţi proprietăţii Can Grow a controlului respectiv valoarea Yes. Astfel,controlul va fi redimensionat automat, ca să poată afişa textul în întregime. Acesta poate fi şi cazul casetei de text care afişează denumirile cursurilor.

Pag. 190

Page 186: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 186/295

CAP:10. FOLOSIREA DATELOR EXTERNE

Rolul principal al unei baze de date este stocarea informaţiilor. Până acum, aţiînvăţat cum sunt stocate datele în Access şi cum să le manipulaţi după ce acestea segăsesc în baze de date. Mai trebuie să aflaţi cum puteţi transfera date în şi din Accessşi cum să folosiţi date din alte baze de date.

În acest capitol, se va prezenta:• Să importaţi date în Access• Să exportaţi date din Access• Să expediaţi date prin poşta electronică

• Să folosiţi date din baze de date externe

10.1 Copierea în sau din alte aplicaţii

Desigur, există mii de aplicaţii care stochează informaţii şi ar fi util să puteţischimba date cu acestea. Deoarece fiecare aplicaţie stochează datele într-un format propriu, pentru a face schimb de date ar trebui să cunoaşteţi formatul respectiv. Dinfericire, nu trebui să cunoaşteţi detalii despre toate aplicaţiile, ci doar despre cele maiimportante. Dacă vreţi să schimbaţi date cu un program care nu apare în listă, puteţi

alege un format standard, care să poată fi citit atât de programul respectiv, cât şi deaplicaţia dumneavoastră.Access poate schimba date cu patru tipuri de aplicaţii:

• Fişiere de tip text• Mesaje poştale• Baze de date• Foi de calcul tabelar 

De obicei, veţi lucra cu baze de date sau foi de calcul mai vechi, ori cu sisteme

 private moştenite, pe care doriţi să le înlocuiţi cu Access. În oricare dintre cazuri, văveţi da seama că facilităţile de import şi export sunt extrem de simple şi flexibile.

10.1.1 Baze de dateBazele de date diferă de la sisteme desktop mici, din care face parte Access, la

 baze de date stocate pe servere de dimensiuni medii şi până la baze de date stocate pecalculatoare mainframe de dimensiuni foarte mari. În Access, pentru transferul datelor între baze de date se foloseşte metoda TranferDatabase a obiectului DoCmd.

Pag. 191

DoCmd.TransferDatabase [TransferType], DatabaseType, DatabaseName_[, ObjectTye], Source, Destination [, StructureOnly ][, SaveLoginID]

Page 187: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 187/295

Parantezele pătrate indică un argument opţional. Să analizăm în detaliu argumenteleacestei metode:

Argument DescriereTransferType Acţiunea pe care doriţi să o executaţi, care poate fi una dintre

următoarele:acImport pentru a importa dateacExport pentru a exporta dateacLink  pentru a lega dateDacă lăsaţi acest argument necompletat, se foloseşte valoareaimplicită acImport.

 DatabaseType Tipul bazei de date în care sau din care doriţi să efectuaţi transferul.Poate fi una din următoarele:Microsoft Access FoxPro 3.0

Paradox 3.x FoxPro DBCParadox 4.x dBase IIIParadox 5.x dBase IVFoxPro 2.0 dBase 5.0FoxPro 2.5 Jet 2.xFoxPro 2.6 ODBC

 DatabaseName  Numele complet al bazei de date respective, inclusiv calea.ObjectType Tipul de obiect implicat în operaţie, care poate fi unul din

următoarele:

acTableacQueryacFormacReportacMacroacModuleDacă argumentul nu este completat, se foloseşte valoarea implicităacTable.

 Source  Numele obiectului din care provin datele.

 Destination  Numele obiectului în care sunt transferate datele. StructureOnly Trebuie să fie True dacă obiectul este un tabel şi se transferă doar structura. Dacă este False, vor fi copiate şi datele. Valoareaimplicită este False.

 SaveLoginID Se foloseşte numai pentru surse de date ODBC. Dacă este True,numele de conectare (login) şi parola vor fi memorate pentruconexiunile următoare. Dacă este False, va trebui să parcurgeţi procesul de conectare de fiecare dată când accesaţi sursa de date.Valoarea implicită este False.

Exerciţiu:- Comanda TransferDatabase 

Pag. 192

Page 188: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 188/295

La fel ca majoritatea magazinelor, Whisky Shop trebui să tipărească o broşurăde prezentare a ofertei, iar editurile cer ca lista de băuturi să fie transmisă în format de bază de date. În continuare, vom crea această bază de date.

1. Închideţi orice bază de date pe care aţi deschis-o anterior şi alegeţi New

Database… (o nouă bază de date) din meniul File.2. În pagina etichetei General, selectaţi opţiunea Blank Database (Bază dedate goală) şi executaţi clic pe OK. Denumiţi noua bază de date Brochure(Broşură) şi salvaţi-o în directorul BegVBA (sau în directorul care conţine bazele de date de exemplificare).

3. Acum închideţi această bază de date şi deschideţi fişierul Student.mdb.Deoarece în viitor vom executa operaţiunea de export la intervale regulate,vom crea acum un formular şi îl vom configura ca pe o componentă permanentă.

4. Deschideţi formularul Outside World, frmOutsideWorld, în modul deafişare Form. Veţi vedea că există deja un grup de opţiuni, fiind creată prima intrare.

5. Trebuie să activăm butonul Export astfel încât, dacă se execută clic asupralui atunci când opţiunea de deasupra este selectată, lista de băuturi să fieexportată automat în baza de date Brochure.mdb. Pentru aceasta,adăugăm comanda TransferDatabase în procedura de tratare aevenimentului clic. Treceţi în modul de afişare Design şi alegeţievenimentul On Click din foaia de proprietăţi. Adăugaţi comanda

TransferDatabase în forma următoare:

Am folosit o instrucţiune Select Case care ne permite să adăugăm ulterior înformular şi alte butoane de opţiune.6. Închideţi fereastra modulului şi treceţi în modul de afişare Form. Selectaţi

opţiunea Export to Brochure Database şi executaţi clic pe butonul Exportdin formular. Această acţiune va lansa în execuţie noua procedură,determinând exportul listei de băuturi din tabelul Curs în

noua bază de date, într-un tabel numit Lista Cursuri. Dacă efectuămexportul într-o bază de date existentă, iar tabelul este deja inclus, acesta vafi înlocuit.

Pag. 193

Private Sub cmdExport_Click()

Select Case fraExportTypeCase 1

DoCmd.TransferDatabase acExport, "Microsoft Access", _ "C:\BegVBA\Brochure.MDB", acTable, "Curs", "Lista Cursuri"

End Select 

End Sub

Page 189: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 189/295

7. Închideţi fişierul Student.mdb, salvând modificările efectuate în formular,şi deschideţi Brochure.mdb, care conţine acum noul tabel. Deschideţitabelul pentru a vedea datele.

8. Tabelul poate fi vizualizat şi editat, iar dumneavoastră aveţi posibilitateasă modificaţi câmpul CursID.

9. Treceţi formularul în modul de afişare Design şi executaţi clic pe butonulExport. Înainte de a deschide fişierul Brochure.mdb, anticipaţi ceea ceveţi vedea pe ecran.

Deşi comanda TransferDatabase este foarte flexibilă, nu veţi lucra prea multcu ea. De obicei, este folosită pentru a converti baze de date din sisteme mai vechi înAccess 97 sau pentru a face copii de siguranţă, complete sau parţiale, ale unei baze dedate. De exemplu, puteţi folosi această comandă pentru a implementa o procedură

automată de salvare de siguranţă (backup). În acest scop, creaţi un tabel care săcuprindă elementele care trebuie salvate şi momentul declaşării acestei operaţii, astfelîncât aplicaţia să poată verifica periodic acest tabel şi să execute o comandăTransferDatabase pentru obiectele şi în momentele specificate.

10.1.2 Foi de calcul tabelarTransferul datelor în foi de calcul este una dintre cele mai apreciate facilităţi

de transfer. Access 97 este ideal pentru interogarea datelor şi realizarea de rapoarte,

însă atunci când doriţi să analizaţi date numerice, cel mai bine este să folosiţi o foaiede calcul tabelar. Puteţi analiza numere şi în Access, însă nu are nici un rost, dinmoment ce există instrumentul numit Microsoft Excel, care este foarte puternic, iar transferul datelor se realizează foarte uşor. Pentru a transfera date în sau dintr-o foaiede calcul tabelar, folosiţi metoda TransferSpreadsheet a obiectului DoCmd:

Argumentele sunt similare cu cele ale comenzii TransferDatabase, pe caream analizat-o în secţiunea precedentă.

Argument Descriere

TransferType Acţiunea pe care doriţi să o executaţi, care poate fi una dintreurmătoarele:acImport pentru a importa date

Pag. 194

DoCmd.TransferSpreadsheet [TransferType] [, SpreadsheetType], _TableName, FileName [, HasFieldName] [, Range]

Page 190: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 190/295

acExport pentru a exporta dateacLink  pentru a lega dateDacă lăsaţi acest argument necompletat, se foloseşte valoareaimplicită acImport.

 SpreadsheetType Un număr reprezentând tipul de foaie de calcul în sau din care

efectuaţi transferul. Constantele pe care le puteţi folosi sunturmătoarele:acSpreadsheetTypeExcel13acSpreadsheetTypeExcel14acSpreadsheetTypeExcel15acSpreadsheetTypeExcel17acSpreadsheetTypeExcel97acSpreadsheetTypeExcelLotusWK1acSpreadsheetTypeExcelLotusWK3

acSpreadsheetTypeExcelLotusWK4acSpreadsheetTypeExcelLotusWJ2 (doar versiunea japoneză)TableName  Numele tabelului sau interogării implicate în transfer.FileName  Numele fişierului care conţine foaia de calcul, inclusiv calea. HasFieldName Dacă doriţi să folosiţi primul rând al tabelului sursă sau al foii de

calcul pentru numele câmpurilor din tabelul sau foaia de calculdestinaţie, argumentul trebuie să aibă valoarea True; dacă doriţi sătrataţi primul rând ca pe nişte date obişnuite, valoarea trebuie să fieFalse. În mod implicit, se foloseşte valoarea False.

 Range Se aplică numai la operaţiile de import. Trebuie să conţină domeniulde celule sau numele domeniului care va fi importat. Dacă este lăsatnecompletat, va fi importată întreaga foaie de calcul.

Importul datelor din foile de calcul se realizează la fel de simplu. Mulţiutilizatori încearcă să evite bazele de date, având impresia că sunt prea complexe.Totuşi, la un moment dat, datele devin prea complicate pentru a fi stocate într-o foaiede calcul tabelar şi va trebui să le importaţi într-o bază de date, împărţindu-leîn tabele. În acest caz, folosiţi metoda TransferSpreadsheet aproape în acelaşi

format ca mai sus.În capitolele următoare, veţi întâlni şi alte exemple de transfer al datelor în

Excel.

Pag. 195

Page 191: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 191/295

10.1.3 Fişiere de text

Există două modalităţi de a importa şi exporta date de tip text. Prima foloseştefişiere de text cu caractere delimitatoare, în care un anumit caracter determină unde setermină un câmp şi începe altul. A doua metodă foloseşte fişiere de text cu lăţime fixă,

care necesită ca toate câmpurile şi înregistrările să aibă poziţii prestabilite în cadrulfişierului - fiecare înregistrare (şi câmp pe care îl conţine) are acelaşi număr decaractere ca toate celelalte înregistrări.

Ambele tehnici de lucru folosesc metoda TransferText a obiectului DoCmd:

Argumentele sunt similare cu cele ale metodelor prezentate anterior:

Argument DescriereTransferType Acţiunea pe care doriţi să o executaţi, care poate fi una dintreurmătoarele:acExportDelimacExportFixedacExportHTMLacExportMergeacImportDelimacImportFixed

acImportHTMLacLinkDelimacLinkFixed

Pag. 196

DoCmd.TransferText [TransferType] [, SpecificationName], _ TableName, FileName [, HasFieldNames] [, HTMLTableName]

Page 192: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 192/295

acLinkHTMLDacă lăsaţi acest argument necompletat, se foloseşte valoareaimplicită acImportDelim.

 SpecificationName  Numele specificaţiei de import/export. Este obligatorie pentrufişierele cu lăţime fixă, dar nu şi pentru fişierele cu caractere

delimitatoare. (Deoarece când lucraţi cu fişiere de text rebuie săfurnizaţi multe valori de configurare, acestea sunt stocate deobicei pe disc ca o specificaţie, iar numele acestui grup deinformaţii este folosit apoi ca argument pentru metodaTransferText. Altfel, va trebui să transmiteţi de fiecare datăvalori pentru o mulţime de argumente. Vom mai vorbi desprespecificaţii în cele ce urmează).

TableName  Numele tabelului pe care doriţi să îl importaţi, exportaţi saulegaţi, ori numele interogării ale cărei rezultate doriţi să le

exportaţi.FileName  Numele fişierului de text, inclusiv calea. HasFieldName Este True dacă primul rând al fişierului de text conţine numele

de câmpuri şi False în caz contrar. Dacă argumentul este lăsatnecompletat, se foloseşte valoarea implicită False.

 HTMLTableName  Numele tabelului (sau listei) din documentul HTML pe caredoriţi să le importaţi sau să îl exportaţi. Această opţiune esteignorată, mai puţin în cazul în care aţi specificat un transfer HTML (acExportHTML sau acImportHTML). Dacă lăsaţi

argumentul necompletat, este folosit primul tabel (sau primalistă). Vom detalia acest argument în secţiunea despre Internet.

10.1.4 Fişiere de text cu caractere delimitatoareFişierele de text cu caractere delimitatoare folosesc un caracter special pentru

a separa câmpurile înregistrărilor. În majoritatea cazurilor, acest caracter este ovirgulă, deci fişierul de text va conţine linii de cod de genul:

camp 1, camp 2, camp 3, camp 4Încercaţi singur - Comanda TransferText  

Magazinul Whisky Shop a fost inclus recent în ancheta unei reviste careîncearcă să determine tendinţele în cumpărarea de whisky. Ziariştii s-au arătatinteresaţi mai ales de tipurile de whisky vândute şi de perioada calendaristică. Pentrua-i ajuta, le transmitem o listă în format text cu caractere delimitatoare.Adăugaţi un nou buton de opţiune în formularul Outside World. Acesta va avea

valoarea 3. Etichetaţi acest buton ca în figura alăturată:Adăugaţi următoarea secevnţă de cod la instrucţiunea Select Case din procedura caretratează acţionarea butonului Export.

Pag. 197

Page 193: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 193/295

1. Treceţi formularul în modul de afişare Form, selectaţi al treilea buton deopţiune şi executaţi clic pe Export. Deschideţi în programul Notepadfişierul C:\BegVBA\Survey.txt. Ar trebui să arate ca în figura alăturată.

Observaţi că specificaţia implicită cuprinde o virgulă ca separator de câmpuri şighilimele pentru text. Acest tip de fişier este numit Comma Separated Value (sauCSV) (adică fişier cu valori separate prin virgule) şi reprezintă cea mai sigură formăde transfer, fiind folosit şi recunoscut pe scară largă. Utilizarea ghilimelelor în jurul

textului este importantă, pentru că astfel, o virgulă dintr-un şir de text nu mai poate ficonfundată cu un separator de câmpuri. Oricum, trebuie să fiţi foarte atent laghilimelele care apar în cadrul textului. De exemplu, apostroful este un caracter valabil într-un şir, iar dacă un câmp conţine un apostrof, nu doriţi ca acesta sămarcheze sfârşitul câmpului. Este bine să verificaţi conţinutul datelor înainte săaplicaţi această metodă, pentru că utilizarea necorespunzătoare a virgulelor şighilimelelor poate avea rezulate imprevizibile.

10.1.5 Fişiere de text cu lăţime fixă

Cealaltă metodă pentru transferul datelor prin fişiere de text evită orice posibilă confuzie creată de ghilimele, separatoare de câmpuri şi nume de câmpuri.Este necesară utilizarea unei specificaţii care să detalieze numele de câmpuri, loculunde începe fiecare câmp şi dimensiunea acestora. Cea mai simplă metodă de a creaspecificaţii este oferită de aplicaţia Wizard Text Export.

10.2 Compunerea mesajelor poştaleŢinând cont de cantităţile mari de informaţii care sunt înregistrate în bazele de

date, este foarte important să puteţi compune (combina) datele în cadrul unor documente obţinute în editoare de text. De exemplu, această tehnică ar permiteexpedierea unor mesaje poştale către toţi clienţii magazinului Whisky Shop, pentru a-ianunţa despre oferte speciale sau promoţinale, dar şi despre operaţii curente şi facturi.

Încercaţi singur - Crearea unui fişier de compunere a mesajelor poştale

Puteţi folosi facilităţile de export din Access 97 pentru a crea un fişier decompunere a mesajelor poştale în programul Microsoft Word.Adăugaţi în formularul Outside World un alt buton de opţiune, de data aceasta cuvaloarea 4, şi etichetaţi-l ca în figura alăturată:

1. Completaţi instrucţiunea Select Case cu următoarea secvenţă de cod:

Pag. 198

Case 3DoCmd.TransferText acExportDelim, , "qryMonthlyWhiskyCount", _ 

"C:\BegVBA\Survey.txt", True

Page 194: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 194/295

2. Acum treceţi formularul în modul de afişare Form, selectaţi opţiunea decompunere a mesajelor poştale (Mail Merge) şi executaţi clic pe butonulExport. Va fi creat un fişier Microsoft Word cu numele Customers.doc,care poate fi folosit ca sursă de date pentru compunerea mesajelor poştale.

Săgeţile care apar în figura anterioară indică faptul că într-un fişier Word decompunere a mesajelor poştale sunt folosite caractere Tab pentru a separa câmpurileînregistrărilor. Şirurile de text sunt încadrate de ghilimele.

În capitolele următoare, veţi întâlni şi alte exemple referitoare la transferul

datelor din Access în Word.

10.3 Exportul altor obiectePână acum, aţi aflat cum să exportaţi date din tabele sau rezultate în urma unor 

interogări, însă vor apărea şi situaţii în care va trebui să exportaţi date din alte obiecteAccess. În aceste cazuri, puteţi folosi metoda OutputTo a obiectului DoCmd:

Argumentele sunt prezentate în tabelul următor: 

Argument DescriereObjectType Obiectul pe care doriţi să îl exportaţi. Poate fi:

acOutputFormacOutputModuleacOutputQueryacOutputReportacOutputTable

ObjectName  Numele obiectului Access.OutputFormat  Formatul în care va fi exportat obiectul. Trebuie să fie una dintreurmătoarele constante:

Pag. 199

Case 4DoCmd.TransferText acExportMerge, , "qryCompanyAddress", _ 

"C:\BegVBA\Customers.DOC"

DoCmd.OutputTo ObjectType [, ObjectName] [ OutputFormat ] _   [, OutputFile] [, AutoStart ] [, TemplateFile]

Page 195: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 195/295

acFormatActiveXServer pentru Microsoft Active Server Pages.acFormatHTML pentru un document HTML.acFormatIIS pentru Microsoft Internet Information Server.acFormatRTF Rich Text Format.acFormatTXT pentru format text Notepad.

acFormatXLS pentru format Microsoft Excel.OutputFile  Numele fişierului (inclusiv calea) în care trebuie transferatobiectul.

 AutoStart  Folosiţi valoarea True pentru a porni automat aplicaţia asociatăcu tipul de format extern şi False în celelalte cazuri. Dacăargumentul nu este indicat, se foloseşte valoarea implicită False.

TemplateFile  Numele şablonului pentru fişiere HTML, HTX sau ASP. Vomdiscuta despre acestea în Capitolul 17, Internet.

Încercaţi singur - Comanda OutputTo 

1. Din pagina etichetei Report, deschideţi raportul rptWhiskyTotal.Observaţi că acest raport conţine şi text formatat. Vom transfera raportulîntr-un fişier de tip RTF (Rich Text Format).

2. Deschideţi formualrul Outside World şi adăugaţi al cincilea buton deopţiune. Acesta va avea valoarea 5:

3. Adăugaţi codul următor la instrucţiunea Select Case:

4. După ce deschideţi formularul frmOutsideWorld, alegeţi această opţiuneşi executaţi clic pe butonul Export; programul World este lansat automat şiafişează acest document.

 Notă: Observaţi că numele de fişier conţine sufixul RTF, astfel ca Windows 95 sauWindows NT să poată identifica tipul de fişier. RTF provine de la Rich Text Format(text cu format îmbunătăţit), care permite includerea formatului în documentul de textşi este standardul Microsoft pentru formatarea documentelor. Utilizarea acestuistandard asigură lansarea în execuţie a programului Word. În mod similar, dacăfolosiţi constanta acFormatXLS, ar trebui să adăugaţi extensia XLS la sfârşitulnumelui de fişier. Chiar dacă Access 97 cunoaşte tipul de fişier pe care îl creaţi, nuadaugă sufixul în locul dumneavoastră.

Fiind vorba de un fişier RTF, s-au păstrat toate elementele de formatare.

Totuşi, observaţi că linia de deasupra totalului pe regiune nu a fost transferată. Ţineţicont de acest comportament dacă folosiţi în rapoarte elemente grafice, pentru că

Pag. 200

Case 5DoCmd.OutputTo acReport, , "rptWhiskyTotal", _ 

acFormatRTF, "C:\BegVBA\WhiskyTotal.RTF", True

Page 196: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 196/295

acestea nu sunt salvate într-un fişier RTF. Este o opţiune utilă atunci când doriţi sădistribuiţi rapoarte simple, fără să le tipăriţi la imprimantă.

10. 4 Poşta electronicăO altă modalitate de distribuire a datelor este prin poşta electronică. Marele

avantaj al utilizării sistemului de poştă electronică (e-mail) este uşurinţa cu care puteţitransmite date, nu numai în reţele locale, ci în întreaga lume. Răspândirea reţelelor globale (MicrosoftNetwork, CompuServe, America On Line, Internet etc.) a redustimpul necesar utilizatorilor pentru a obţine informaţiile de care au nevoie - nu maisunteţi nevoiţi să tipăriţi un raport la imprimantă, să faceţi cinci copii xerox pe care săle expediaţi la filialele companiei. Acum, alegeţi numele destinatarilor din agendaelectronică şi transmiteţi raportul respectiv într-un minut.

Puteţi transmiteţi mesaje de poştă electronică printr-o diversitate de programeclient, cum ar fi Microsoft Exchange şi Outlook, Eudora, Pegasus etc. în exemplele

din carte am folosit Microsoft Outlook, însă şi alte programe client lucrează la fel de bine.

Marele avantaj al programului Microsoft Outlook este faptul că poate fiutilizat ca un client unic de poştă electronică pentru diferite tipuri de reţele şi, dinmoment ce Outlook se ocupă de toate problememle de adresare, nu trebuie să ştiţi cetip de reţea folosiţi. Dumneavostră nu faceţi decât să specificaţi adresele, iar Outlook se ocupă de distribuirea mesajelor. Pentru a transfera date prin poşta electronică, sefoloseşte metoda SendObject a obiectului DoCmd:

Deşi există mai multe argumente decât în exemplele anterioare, acestea sunttoate foarte simple:

Argument DescriereObjectType Obiectul pe care doriţi să îl transferaţi. Poate fi:acSendFormacSendModuleacSendNoObject (doar pentru expedierea unui mesaj poştal)acSendQueryacSendReportacSendTableDacă lăsaţi acest argument necompletat, se foloseşte în mod

implicit acSendNoObject.ObjectName  Numele obiectului Access.OutputFormat  Formatul în care se transferă obiectul. Poate fi:

Pag. 201

DoCmd.SendObject [ObjectType [, ObjectName] [, OutputFormat ] [, To] _   [, CC ] [, BCC ] [, Subject ] [, MessageText ] [, EditMessage], _ 

[TemplateFile]

Page 197: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 197/295

acFormatXLS pentru format Microsoft Excel acFormatRTF pentru format RTF Microsoft WordacFormatTXT pentru format de text NotepadacFormatHTML pentru format HTMLDacă lăsaţi acest argument necompletat, Access vă cere să

alegeţi un format.To O listă de destinatari pentru poşta electronică. Dacă sunt maimulţi, trebuie să folosiţi ca separator caracterul punct şi virgulă(;) (sau caracterul List Separator prezentat în eticheta Number afoii de proprietăţi Regional Settings din panoul de controlWindows). Dacă lăsaţi acest argument necompletat, Access văcere să introduceţi recipientele.

CC  O listă de destinatari pentru linia cc. BCC  O listă de destinatari pentru linia bcc.

 Subject  Un şir care conţine linia de subiect a mesajului. MessageText  Un şir care conţine textul mesajului. Este plasat după obiectulataşat.

 EditMessage Pentru a deschide aplicaţia de poştă electronică imediat (şi a permite editarea), trebuie să folosiţi valoarea True. Pentru atransmite direct un mesaj, trebuie să folosiţi valoarea False. Dacălăsaţi argumentul necompletat, se foloseşte valoarea implicităFalse.

TemplateFile  Numele unui fişier (inclusiv calea) care va fi folosit ca şablon

 pentru documentele HTML.În exemplul următor, un raport este transmis mai multor persoane, una dintre

ele foloseşte CompuServe, alta InternetMail, iar a treia Microsoft Exchange. ÎnAccess, trebuie doar să specificaţi numele. Nu este necesar să ştiţi ce sistem de poştăelectronică foloseşte destinatarul.

Încercaţi singur - Poşta electronică

Este evident că pentru acest exemplu, aveţi nevoie de o conexiune la un sistemde poştă electronică. Însă, chiar în lipsa acesteia, puteţi să parcurgeţi procedura fără ao implementa efectiv, pentru a vedea cât de uşor poate fi adăugată această facilitate înaplicaţiile Access.Adăugaţi în grupul de opţiuni un alt buton - de data aceasta, va avea valoarea 6.

Deoarece acest formular este destinat exportului de date, nu trebuie să îlaglomeraţi cu detalii referitoare la poşta electronică, aşa încât este bine să lăsaţi toateadresele necompletate. Adăugaţi următoarea secvenţă de cod la instrucţiunea SelectCase:

Pag. 202

Case 6DoCmd.SendObject acQuery, "qryWhiskyAndPrices", acFormatXLS, _ 

, , , "Price List", "Here's our latest price list", True

Page 198: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 198/295

Prin această instrucţiune, transmitem interogarea referitoare la vânzările lunareîn format Microsoft Excel.

Rulaţi acest fragment de cod selectând al şaselea buton de opţiune în modul de

afişare Form şi executând clic pe butonul Export. Câmpurile To, cc şi bcc suntnecompletate, aşa încât sistemul de poştă electronică se va deschide normal şi vă va permite să selectaţi destinatarul (sau destinatarii) din lista de adrese.

Observaţi că linia Subject a fost completată cu textul din instrucţiune, iar textul suplimentar a fost adăugat după obiect.

În cazul în care completaţi linia To în cadrul codului şi apoi configuraţiargumentul EditMessage la valoarea False, poşta electronică este distribuită direct,fără vreo intervenţie din partea dumneavoastră. Mai simplu de atât nu se poate. Prin

urmare, dacă cineva vă spune că este dificil să comunicaţi prin poşta electronică dinAccess, puneţi-l la punct fără nici o jenă.

10.5 Date externe

În secţiunile anterioare ale acestui capitol, am arătat cum pot fi transferate dateîn şi din Access, însă există situaţii când trebuie să folosim date externe fără să leimportăm. Access poate accesa (nu este un joc de cuvinte!) date din alte surse şiacestea apar în aplicaţiile dumneavoastră ca şi cum ar fi tabele Access, permiţându-vă

astfel să stocaţi datele într-o varietate de formate, dar să le folosiţi numai din Access.În astfel de situaţii, puteţi lega datele în baza dumneavoastră de date. Această tehnicăfuncţionează în mod similar cu comenzile rapide (shortcuts) din Windows 95 - datelerămân acolo unde sunt, însă dumneavoastră aveţi o legătură rapidă la ele. Dacă datelese modifică, puteţi vizualiza modificările apărute. Dacă dumneavoastră modificaţidatele din cadrul legăturii, şi datele originale se modifică.

 Deci, care este utlitatea legării dateor externe în Access?

Ei bine, pentru început, trebuie spus că Access vă oferă posibilitateadezvoltării unor sisteme noi de baze de date, însă de multe ori, aveţi deja cantităţi maride date. Legarea permite accesul la informaţiile din bazele de date şi foile de calculmai vechi, în timp ce un sistem nou trebuie dezvoltat de la zero. Există şi variantafolosirii facilităţilor de interogare şi de crearea a rapoartelor din Access, păstrând însăaplicaţia existentă.

De asemenea, puteţi să separaţi componentele back-end şi front-end aleaplicaţiei. Componenta back-end cuprinde datele propriu-zise, în timp ce componentafront-end este interfaţa cu utilizatorul. Aceasta din urmă include formularele,rapoartele, interogările, macroconstrucţiile şi modulele. Astfel, aplicaţiadumneavoastră va fi divizată în două baze de date Access:

Pag. 203

Page 199: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 199/295

Este o tehnică uzuală, care vă permite să actualizaţi componenta front-end fărăsă afecteze componenta back-end. Vă amintiţi ce dificil este să distribuiţi aplicaţiile lautilizator. Recent le-aţi dat o copie cu ultima versiune a bazei de date, iar acum dorescsă operaţi modificări - însă au început deja să introducă date. Prin urmare, trebuie săefectuaţi modificările, dar şi să opriţi toţi utilizatorii să folosească vechea bază de date

şi să copiaţi datele în una nouă. Însă dacă separaţi componentele front-end şi back-end, partea care conţine datele nu va trebui modificată niciodată - puteţi să înlocuiţicomponenta front-end şi apoi să refaceţi legătura cu tabelele.

Dacă decideţi să aplicaţi această metodă după ce aţi creat o aplicaţie, alegeţisubcomanda Database Splitter din comanda Add-ins a meniului Tools. Programulwizard ataşat acestei comenzi vă va ghida prin etapele procesului de separare atabelelor de restul obiectelor din baza de date.

Şi tehnica de legare este foarte utilă, dată fiind popularitatea sistemelor client-

server. În acest caz, componenta back-end a bazei de date este, de obicei, un server  puternic de baze de date, cum ar fi Microsoft SQL Server, care vă pune la dispoziţiefacilităţile unei baze de date relaţionale mari. Puteţi să aveţi toate datele pe server, pentru a-l folosi la capacitate maximă, dar în acelaşi timp să continuaţi utilizareafacilităţilor sistemului Access, cum sunt formularele, interogările şi rapoartele.

În majoritatea cazurilor, puteţi chiar să mutaţi interogările pe server şi să leexecutaţi acolo, nu pe propriul calculator. Această tehnică poate îmbunătăţi viteza delucru şi, în plus, are avantajul de a minimiza traficul de reţea. Singurele informaţiicare trec prin reţea sunt instrucţiunile dumneavoastră pentru lansarea interogărilor şi

tabelul cu rezultate returnate de server. Este o abordare care face parte din modelulclient-server şi garantează că atât clientul, cât şi serverul (de exemplu, SQL Server)lucrează la parametrii optimi - lăsând serverul să ruleze interogările lungi şi folosindtabelele Access pentru a accesa rapid informaţii care nu se modifică frecvent. Este undomeniu prea vast pentru a fi prezentat aici în detaliu, dar există numeroase cărţidedicate acestui subiect.

 În Access 2.0 şi în versiunile anterioare, tabelele legate erau numite tabeleataşate.

10.6 Tabele legate

În mod sigur aţi folosit şi până acum tabele legate. Acestea sunt marcate înfoaia Tables a ferestrei bazei de date cu o săgeată:

Figura alăturată prezintă un tabel din baza de date model Northwind(distribuită împreună cu programul Access), care a fost legat la aplicaţia Whisky.Puteţi şterge oricând o legătură, fără să afectaţi în vreun fel tabelul cu date.

Încercaţi singur - Legarea unui obiect

În acest exemplu, vom folosi argumentul acLink  al metodei TransferSpreadsheet a obiectului DoCmd. Puteţi folosi acest argument şi cu metodele

Pag. 204

Page 200: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 200/295

TransferDatabase şi TransferText. Vom lega o foaie de calcul în aplicaţia noastră,însă, nedorind să o definim ca o componentă permanentă a aplicaţiei, vom lucra înfereastra de depanare.

1. Deschideţi un modul nou şi introduceţi în fereastra Debug următoareasecvenţă de cod:

2. Această instrucţiune va face legătura cu foaia de calcul creată într-unexemplu anterior. Al doilea argument indică faptul că realizăm o legăturăcu un fişier Excel versinea 5.0 sau 7.0.

3. Acum examinaţi pagina Tables a ferestrei bazei de date. Ar trebui să vedeţiun obiect nou, legat, care este o foaie de calcul (pentru a-l vizualiza, trebuisă comutaţi în altă pagină şi apoi să reveniţi).

Rezultă că această pagină poate conţine nu numai tabele, ci şi alte surse dedate. Din moment ce sursele de date pot fi legate la Access, le puteţi edita ca şicând ar fi tabele Access.

Acum puteţi deschide foaia de calcul WhiskySales ca şi când ar fi un tabelnormal. Orice modificări pe care le operaţi aici se vor reflecta în foaia de calcul, însă

fiţi foarte atent la coloanele care conţin date incomplete sau confuze.Access a detectat că în a treia coloană apar numere, dar primul rând conţinetitlurile coloanelor, care sunt format text. Dacă intenţionaţi să legaţi foile de calcul înacest fel, ar trebui să eliminaţi titlurile de coloane sau să folosiţi în legăturăargumentul Range (Domeniu), pentru a include doar datele corecte.

Încercaţi singur - Reîmprospătarea legăturilorDacă intenţionaţi să separaţi o bază de date în componentele back-end şi front-

end, este evident că aveţi nevoie de o modalitate de reîmprospătare a legăturii dintretabele. Această operaţie este utilă nu numai pentru a distribui o nouă copie a bazei dedate front-end, ci şi dacă aplicaţia back-end este instalată în altă parte decât seaşteaptă Access să o găsească.

1. Creaţi o nouă bază de date (denumiţi-o BackEnd) şi executaţi clic peCreate. Pentru a importa tabelele din baza de date model, selectaţi dinmeniu File/Get External Data şi executaţi clic pe opţiunea Import. Încontinuare, selectaţi fişierul Whisky8.mdb în caseta de dialog Import,executaţi clic pe butonul Select All şi apoi pe butonul OK în caseta dedialog Import Objects.

Pag. 205

DoCmd.TransferSpreadsheet acLink, 5, "WhiskySales", _ "C:\BegVBA\WhiskySales.XLS"

Page 201: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 201/295

2. Închideţi această bază de date, apoi creaţi o altă bază de date (FrontEnd)şi legaţi tabelele din baza de date BackEnd, selectând opţiunea Link Tables din meniul File/Get External Data. Repetaţi procesul de mai sus.

3. Schimbaţi numele bazei de date BackEnd cu NewBackEnd şi încercaţi sădeschideţi unul dintre tabelele legate:

Tabelele de aici sunt doar legate. Ele nu există, de fapt, în baza de dateFrontEnd. De aceea, dacă încercaţi să deschideţi unul dintre tabele dupămutarea bazei de date back-end, veţi obţine un mesaj de eroare.Acum vom reface legătura cu tabelele.4. Creaţi un modul nou şi adăugaţi o funcţie numită RefreshTableLinks.

Introduceţi următoarea secvenţă de cod:

5. Acum deschideţi fereastra de depanare şi apelaţi funcţia în felul următor:

6. Închideţi fereastra modulului şi încercaţi din nou să deschideţi un tabel. Dedata aceasta, nu ar trebui să mai apară un mesaj de eroare - aţi refăcutlegăturile cu tabelele, aşa că Access poate găsi uşor sursele de date.

Cum funcţionează?

Pag. 206

Public Function RefreshTableLinks(strDB As String) As Integer Dim dbCurrent  As Database 'baza ade date curenta

Dim tblLinked  As TableDef 'tabelul curent in colectie

On Error GoTo RefreshTableLinks_Err 

Set dbCurrent = CurrentDb()

For Each tblLinked In dbCurrent.TableDefs

If tblLinked.Connect <> " " ThentblLinked.Connect = ";DATABASE=" & strDBtblLinked.RefreshLink

End If Next 

RefreshTableLinks = TrueRefreshTableLinks_Exit:

Exit FunctionRefreshTableLinks_Err:

MsgBox Error$ 

RefreshTableLinks = FalseResume RefreshTableLinks_ExitEnd Function

RefreshTableLinks("C:\BegVBA\NewBackEnd.mdb")

Page 202: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 202/295

Funcţia parcurge ciclic tabelele şi le modifică proprietatea Connect. Această proprietate defineşte şirul de conectare pentru un tabel legat. Apoi, folosim metodaRefreshLink pentru a ne asigura că legătura este împrospătată. Haideţi să analizămcodul în detaliu:

Set dbCurrent = CurrentDb()

For Each tblLinked In dbCurrent.TableDefsÎncepem prin deschiderea bazei de date curente şi parcurgerea ciclică acolecţiei TableDefs.

If tblLinked.Connect <> " " ThentblLinked.Connect = ";DATABASE=" & strDB

Apoi, căutăm un şir nevid în proprietatea Connect. În cazul tabelelor locale,nu va exista nici o valoare - nu dorim să facem actualizarea pentru aceste tabele. Dacă

există, totuşi, o valoare, aceasta trebuie să fie actualizată cu numele noii baze de date(transmis funcţiei prin argumentul strDB). Proprietatea Connect conţine calea şinumele bazei de date din care sunt legate tabelele. Ea are următoarea formă:

Ca argument object , folosim tabelul pe care l-am găsit în structura ciclică,tblLinked. Argumentul databasetype este un şir care identifică tipul de fişier - pentruAccess, acest argument este lăsat necompletat, însă trebuie să introducem un caracter  punct şi virgulă ca marcaj de rezervare. Dacă doriţi să realizaţi conectarea la un tabel

Paradox, argumentul trebuie să fie "Paradox 5.x" sau unul similar. În fişierul deasistenţă (Help) din Access, găsiţi o listă completă a identificatorilor - căutaţisubiectul Connect Property.

În fine,  parameters reprezintă calea completă şi numle de fişier la bazei dedate, precedat de expresia DATABASE=, în cazul nostru "DATABASE=" & strDB.

tblLinked.RefreshLink End If 

 Next

Terminăm structura ciclică cu o instrucţiune de împrospătare a legăturii. Acestlucru este necesar pentru că simpla configurare a proprietăţii Connect nu determinărestabilirea automată a legăturii. Trebuie să folosim metoda Refresh.

Desigur, puteţi să extindeţi procedura şi să solicitaţi noul nume al bazei dedate (în loc să-l acceptaţi ca parametru). În acest fel, veţi spori flexibilitatea funcţiei.

Diferenţe între tabelele legate şi cele localeTabelele legate au o serie de avantaje faţă de cele locale însă, ca în orice

domeniu, există şi dezavantaje. Iată care sunt acestea: Deoarece tabelele legate nu fac parte din baza dumneavoastră de date,iar înregistrările trebuie să fie extrase din alt fişier de fiecare dată când

Pag. 207

object.Connect = [databasetype; [ parameters] ]

Page 203: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 203/295

încercaţi să le accesaţi, apar probleme de viteză - în special dacă tabelullegat se găseşte pe un alt calculator din reţea Tabelele legate trebuie să fie deschise ca seturi de înregistrări de tipdynaset sau instantaneu (snapshot) şi, din acest motiv, ele nu acceptămetoda Seek , care poate fi aplicată doar seturilor de înregistrări de tip

tabel. Trebuie să fiţi atent la asocierea unor tabele stocate în locuri diferite(de exemplu, unul pe calculatorul local şi unul pe calculatorul situat ladistanţă), pentru că s-ar putea ca tipurile de câmpuri să nu fie complet

compatibile. De exemplu, pot apărea probleme dacă asociaţi două câmpuride date, dintre care unul are formatul US, iar celălalt formatul British. Trebuie să fiţi atent atunci când asociaţi tabele legate de maridimensiuni cu tabele locale mici. Dacă ambele tabele sunt locale, Access

 poate optimiza asocierea, însă dacă este legat un tabel mare de pe uncalculator situat la distanţă, toate datele trebuie să fie trasferate înainte deasocierea efectivă. Şi, desigur, va trebui să luaţi în calcul supraîncărcareacauzată de transferul datelor la executarea interogării.

Cu toate aceste neajunsuri, nu ar trebui să renunţaţi. Soluţia back-end/front-end este extrem de utilă în activitatea firmelor, în condiţiile în care o aplicaţie de bazede date este modificată constant sau este distribuită în etape.

10.7 ODBC

ODBC este abrevierea expresiei Open DataBase Connectivity(Conectivita-tea bazelor de date deschise), care reprezintă o altă modalitate de acces ladate externe. Bazele de date stochează informaţiile în diferite formate şi folosescmetode diferite de acces. Aşa cum aţi văzut deja, puteţi lega la o bază de date Accesstabele din alte tipuri de baze de date. Tendinţa este însă de a include doar sistemeledesktop, cum ar fi dBase şi Paradox.

Pentru a permite tuturor sistemelor de baze de date să schimbe date înmod liber, trebuie să existe o metodă comună de acces - utilizarea unor  drivere

software adecvate, care se interpun între mecanismul bazei de date şi datele celuilaltsistem. ODBC este o metodă standard de implementare a acestui tip de conectivitate -un singur sistem cu o interfaţă larg răspândită, pentru care alţi creatori de sisteme de baze de date produc propriile lor programe driver. Microsoft a început procesul destandardizare acum câţiva ani, însă acesta este controlat în prezent de grupurileinternaţionale de standardizare, astfel că aproape toate tipurile de baze de date suportăacum ODBC, inclusiv Oracle, IBM DB/2, Ingres şi Informix. Marele avantaj este că programele pot fi scrise folosind interfaţa standard ODBC şi vor funcţiona cu orice bază de date pentru care există drivere disponibile.

Puteţi observa că mecanismul Jet acceptă câteva formate comune de baze de date desktop direct prin programe driver incluse în Access şi că ODBC este oentitate separată la "nivel" de driver. În continuare, gestionarul ODBC poate suporta

Pag. 208

Page 204: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 204/295

oricâte baze de date, fiecare prin propriul său sistem de driver. Majoritatea bazelor dedate importante, cum sunt Oracle, DB2 şi alte sisteme pentru minicalculatoare şicalculatoare mainframe, suportă ODBC, asigurând un grad înalt de flexibilitate. Dacănevoile dumneavoastră se schimbă, se pot schimba şi bazele de date.

CAP: 11.TRATAREA ERORILOR, DEPANAREA ŞI TESTAREA

Aţi învăţat multe lucruri despre programarea în Access 97, inclusiv

cum puteţi crea aplicaţii sofisticate. Ceea ce nu aţi învăţat până acum este cum săevitaţi apariţia problemelor şi cum să le detectaţi atunci când (şi nu dacă) acesteatotuşi apar.

Termenul depanare (debug) are sensul de "eliminare a erorilor din". Nimeni nu poate scrie de la început programe fără erori; întotdeauna mai există cevala care nu v-aţi gândit. De aceea, este bine să ştiţi cum să preveniţi apariţia erorilor şice trebuie să faceţi atunci când acestea apar totuşi în program.

În acest capitol veţi învăţa: Cum să preveniţi apariţia erorilor 

Diferite tipuri de erori Metode de tratare a erorilor  Cum să folosiţi evenimentele de eroare

11.1 Anticiparea erorilor

Una dintre legile lui Murphy spune: "Dacă întrezăriţi şase posibilităţica un lucru să meargă prost şi le preîntâmpinaţi, atunci va apărea în mod sigur o aşaptea, la care nu v-ţi gândit". Alta: "Este imposibil de construit ceva care să reziste la

orice intervenţie neavizată, pentru că prostia are resurse nebănuite". În ciudaadevărului amar al acestor observaţii, există posibilitatea planificării (anticipării)erorilor.

Utilizatorilor nu le pasă de dimensiunea codului. Nu îi interesează nicidacă aţi creat cel mai bun şi mai rapid algoritm de calcul al constantei Pi (π). Tot ce îşidoresc este ca aplicaţia să arate bine şi să funcţioneze corect. Detectarea şi eliminareaunei erori este întotdeauna un proces care consumă mult timp şi, ca urmare, mult maiscump decât anticiparea erorilor.

Proiectul

Pag. 209

Page 205: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 205/295

Dacă tocmai aţi întrebat "Ce proiect?", înseamnă că trebuie să mergeţi direct laînchisoare, fără să treceţi prin start şi fără să încasaţi suma de 200$ (vă amintiţi deMonopoly?). proiectul este partea cea mai importantă a aplicaţiei - fundaţia pe bazacăreia sunt construite toate celelalte obiecte. Etapa de proiectare este cea în carestabiliţi exact ce trebuie să facă aplicaţia . una dintre cele mai frecvente cauze de

apariţie a erorilor o reprezintă modificările. De multe ori, aplicaţiile nu răspundcerinţelor utilizatorului şi trebuie modificate. Ca urmare, începeţi să adăugaţi unfragment de cod aici, altul dincolo, iar erorile îşi fac apariţia. Rezervaţi-vă timpulnecesar pentru a discuta cu utilizatorii şi a afla tot ce doresc aceştia de la aplicaţie. Şinu vă miraţi dacă, după mai multe săptămâni de analiză exhaustivă a cerinţelor,dumneavoastră furnizaţi aplicaţia "la cheie", iar utilizatorul vă spune: "Este foarte bine, dar nu mai puteţi adăuga ceva aici…?" Este inevitabil să se întâmple aşa, pentrucă utilizatorii nu sunt foarte siguri de ceea ce vor pânăcând nu văd ceva concret. Nu vă repeziţi să rezolvaţi pe loc noile solicitări. În primul

rând, analizaţi problema şi toate implicaţiile pe care le presupune rezolvarea acesteia.Veţi economisii astfel o mulţime de timp şi efort.Dacă ţineţi cont de la început de aceste principii, există toate şansele să

realizaţi o aplicaţie care să poată fi modificată uşor. Această abordare determină şireducerea numărului de erori. În continuare, sunt prezentate câteva aspecte generale lacare trebuie să vă gândiţi înainte de a începe programarea propriu-zisă.

TabeleProbabil că aţi început să vă plictisiţi de atâtea sfaturi, însă este bine să

 planificaţi tabelele. Încercaţi să anticipaţi câmpurile care ar putea fi necesare, dar lacare utilizatorul nu s-a gândit. De exemplu, s-ar putea ca utilizatorii să solicite doar oadresă pentru tabelul firmelor, însă cum procedaţi dacă trebuie să sortaţi firmele dupăzonă sau după regiunea de vânzare? Aveţi nevoie de mai multe câmpuri - Oraş, Stat(Judeţ) etc. ne-am confruntat cu această problemă chiar la începutul cărţii şi am văzutcum putem împărţi un nume în elementele sale componente.

InterogăriPentru fiecare tabel, ar trebui să creaţi o interogare care să afişeze toate

câmpurile, în felul următor:

Este de preferat să folosiţi modul de afişare cu asterisc decât să specificaţiexplicit fiecare câmp, pentru că astfel, puteţi să adăugaţi câmpuri în tabel fără sămodificaţi interogarea. Ar trebui să realizaţi toate formularele şi rapoartele pe bazaacestor interogări, şi nu direct din tabele. Avantajul acestei metode este că permitemodificarea detaliilor din tabele fără a afecta formularul sau raportul, exceptând,desigur, faptul că noile câmpuri nu sunt afişate automat în formular sau raport. Deexemplu, să creaţi un pseudonim (alias) pentru această interogare. Nici un formular  bazat pe interogarea respectivă nu va trebui modificat.

Pag. 210

Page 206: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 206/295

Formulare şi rapoarteAici, principiul de bază este simplitatea. S-ar putea să vă placă la nebunie să

creaţi formulare sofisticate, însă chiar sunt necesare? Aplicaţia devine mai performantă? Ajută ele utilizatorii să folosească aplicaţia? Aceasta ar trebui să vină însprijinul utilizatorului şi să îi uşureze munca. Dacă elementul pe care îl adăugaţi la

interfaţă nu are acest rol, mai bine renunţaţi la el.Se spune că 80% dintre utilizatori folosesc doar 20% din funcţionalitatea uneiaplicaţii. Reţineţi acest aspect şi nu încărcaţi formularele cu prea multe informaţii.Dacă doriţi un singur formular, dar aveţi multe date care trebuie afişate, încercaţi săfolosiţi Tab Control, care permite împărţirea câmpurilor în pagini logice.

Gruparea funcţiilorGruparea funcţiilor înseamnă păstrarea împreună a elementelor similare. Dacă

scrieţi mai multe rutine de lucru cu şiruri, plasaţi-le pe toate într-un singur modul.

Astfel, veţi fi sigur că nu dublaţi nici o procedură, din moment ce toate rutinele deacelaşi tip sunt grupate. În plus, după ce toate procedurile dintr-un

modul au fost depanate, puteţi importa modulul în alte baze de date în care aveţinevoie de rutinele respective, fără să vă mai preocupe depanarea acestora.

11.3 Tehnici orientate pe obiect pentru prevenirea apariţiei erorilorPentru a elimina erorile dintr-o aplicaţie, puteţi folosi o serie de tehnici

orientate pe obiect.

ÎncapsulareaÎncapsularea este numită şi "mascarea datelor", deoarece acest este, de fapt,

rolul său. Ideea este că în loc de variabile publice, care pot fi accesate din oricefuncţia, folosiţi variabile private şi creaţi proceduri publice pentru a le putea accesa.Această tehnică vă asigură un control mai mare asupra datelor şi vă permite sămodificaţi implementarea codului şi variabilelor, fără a afecta alte rutine. Fiecareobiect ar trebui să ştie totul despre el însuşi şi să nu se piardă în momentul cândtreceţi într-un alt mediu de lucru.

Aşa cum s-a arătat şi în capitolul precedent, noile caracteristici ale modulelor de clasă din Access 97, precum şi procedurile Property Get şi Let care au fostintroduse încă din Access95, asigură un alt nivel de încapsulare în Access. Acestea permit mascarea datelor dintr-un formular sau modul (prin declararea lor de tip privat), însă şi accesul public prin anumite rutine selectate. Astfel, puteţi operamodificări în codul de bază, în timp ce interfaţa rămâne neschimbată. De asemenea,aveţi posibilitatea de a adăuga elemente le interfaţă prin folosirea argumentelor Opţional - avantajul este că orice nou apel le poate folosi şi, pentru că sunt opţionale,vechile apeluri vor funcţiona în continuare corect.

Pag. 211

Page 207: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 207/295

RefolosireaTehnica de refolosire a modulelor de cod se potriveşte foarte bine cu

încapsularea şi poate fi rezumată prin dictonul: "Nu are rost să reinventaţi roata".Dacă aveţi un fragment de cod care rezolvă o anumită problemă, refolosiţi-l. în afarăde faptul că economisiţi un timp preţios, în cazul în care codul respectiv nu conţine

erori, nu mai trebuie să îl depanaţi. Nu ezitaţi să folosiţi un cod creat de altcineva,dacă ştiţi că funcţionează corect şi nu încălcaţi legile referitoare la drepturile de autor.Refolosirea nu este acelaşi lucru cu furtul.

Când creaţi funcţii noi, trebuie să vă gândiţi dacă este cazul să le implementaţica funcţii generice. De exemplu, dacă aveţi o secvenţă de cod folosită în fiecareformular, puteţi transmite obiectul formular în procedură cu ajutorul obiectului Me.Astfel, orice modificare ulterioară a acestei rutine poate fi efectuată într-un singur loc,şi nu în toate formularele. Desigur, metoda are dezavantajul că o eroare apărută în procedură va afecta mai multe zone ale aplicaţiei. Însă în cazul în acre efectuaţi o

testare eficientă şi secţiunile de cod sunt independente, le puteţi transfera fără teamă îndiferite proiecte.Există mari companii care plătesc programatorilor un bonus la fiecare

refolosire a codului lor. Este o politică bună, care încurajează eforturile de planificareşi de identificare a altor domenii în care poate fi folosit programul respectiv.

Comanda Option ExplicitEste o comandă extrem de utilă, care ar trebui să fie implicită pentru toate

modulele dumneavoastră de cod. Puteţi configura această opţiune în cadrul panouluiModule al casetei de dialog Options…, care poate fi deschisă din meniul Tools:

  Această opţiune iniţializează comanda Option Explicit  pentru toate procedurile.

Când această opţiune este validată, în toate modulele noi de cod va apăreainstrucţiunea Option Explicit, motiv pentru care toate variabilele pe care le folosiţitrebuie să fie declarate explicit. Aceasta înseamnă că puteţi evita erorile cauzate detastarea incorectă, care sunt greu de sesizat. De exemplu, citiţi secvenţa următoare decod:

Aţi sesizat greşeala? Numele funcţiei a fost scris greşit în instrucţiunea decalcul a valorii de răspuns, motiv pentru care răspunsul corect nu va fi returnatniciodată. Cu toate că această procedură conţine o singură linie, s-ar putea să treacămult timp până la detectarea erorii (până când această funcţie este apelată în program).Utilizarea instrucţiunii Option Explicit garantează că acest tip de eroare nu va apărea

Pag. 212

Public Function Circumference (dblRadius As Double)Circumference = 2*3.1415926 * dblRadius

End Function

Page 208: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 208/295

în aplicaţie. Dacă instrucţiunea Option Explicit este inclusă în modul, cuvântul"Circumference" va fi marcat ca o variabilă nedeclarată în momentul compilăriideterminându-vă să corectaţi eroarea de tastare.

Verificarea sintaxei

Pagina Module a casetei de dialog Options include şi opţiunea Auto SyntaxCheck (Verificare automată a sintaxei). În cazul validării acestei opţiuni, Accessverifică sintaxa codului în timp ce scrieţi instrucţiunile, dar şi la compilarea codului, şiafişează un mesaj de eroare în cazul în care găseşte o linie incorectă. Dacă opţiunea nueste validată, linia incorectă va fi afişată cu altă culoare (stabilită prin meniul Tools,Options), iar codul va fi verificat doar la compilare. Opţiunea Auto Syntax Check esteimportantă în special dacă nu compilaţi codul înainte a furniza aplicaţia utilizatorilor,deoarece erorile de sintaxă pot fi generate la rularea programului.

S-ar putea ca, uneori, această opţiune să vă deranjeze, dar este preferabil să o

selectaţi. Avantajele atârnă mult mai greu în balanţă decât eventualele dezavantaje.Dacă totuşi nu puteţi să lucraţi cu această opţiune validată (activată),nu uitaţi ca după ce terminaţi o sesiune de editare să selectaţi opţiunea Compile AllModules din meniul Debug (când aveţi deschisă fereastra unui modul).

ComentariiExistă controverse cu privire la acest subiect. Unii programatori nu inserează

nici un fel de comentarii în cod ("Dacă a fost greu de scris, ar trebui să fie şi greu deciti"); alţi programatori comentează fiecare linie în parte. Ambele metode sunt greşite.

Trebuie să găsiţi o cale de mijloc. Iată câteva sugestii utile în acest sens: La începutul fiecărei proceduri, introduceţi un comentariu în care descrieţi rolulacesteia, ce argumente primeşte şi ce fel de valori returnează. De exemplu:

Comentaţi folosirea variabilelor. Plasaţi comentariile pe linii separate, cu excepţia situaţiilor în care descrieţi o

variabilă, când comentariul ar trebui să fie pe aceeaşi linie cu declaraţia. Comentaţi secţiuni de cod (funcţionalităţi), şi nu linii individuale.

 Nu comentaţi ceea ce este evident. Dacă atribuiţi o valoare unei variabile, nu estecazul să inseraţi un comentariu de genul: "Stabileşte valoarea la…". În astfel desituaţii, introduceţi comentarii doar dacă există un motiv pentru a descrie de ce

Pag. 213

Public Function Circumference (dblRadius As Double) As Double''Scop: Calculul circumferintei unui cerc'Argumente: dblRadius Raza cercului'Valoare returnata: Circumferinta cercului'Autor:

'Data: 11 iunie 1999

Circumference = 2*3.1415926 * dblRadiusEnd Function

Page 209: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 209/295

efectuaţi operaţia respectivă, cum ar fi atribuirea unei valori Empty sau Null pecare o veţi folosi ulterior în cod.

Depanaţi codul, nu comentariile. Nu vă bazaţi pe comentarii, pentru că, de multeori, acestea nu sunt actualizat o dată cu codul. Ar trebui să vă asiguraţi că oricemodificare pe care o efectuaţi se reflectă şi în comentariile din cod.

Cel mai important lucru pe care trebuie să îl aveţi în vedere este consecvenţa. Caşi în restul aplicaţiei, alegeţi stilul care vă place şi folosiţi-l doar pe acesta.

11.4 TestareaMulte companii mari au echipe speciale pentru testarea aplicaţiilor. Altele

 preferă să lase utilizatorii să efectueze testarea (pentru aceasta se lansează de faptversiunile beta!). oricum, indiferent de experienţa pe care o aveţi în programare, nueste indicat să săriţi peste etapa de testare a codului. Fiecare programator trebuie să îşiasume responsabilitatea pentru codul pe care l-a creat. La urma urmei, tot

dumneavoastră va trebui să eliminaţi erorile descoperite în aplicaţie.

Testarea poate avea mai multe forme şi este bine să vă rezervaţi timp pentrufiecare dintre ele. Consideraţi această etapă din procesul de realizare a aplicaţiei la felde importantă ca şi scrierea codului. În continuare, vom analiza diferite faze detestare.

Testarea funcţională

Testarea funcţională constă în a verifica dacă întreaga aplicaţie, sau o parte aacesteia îndeplineşte funcţia pentru care a fost scrisă. Există trei căi de a obţine unrăspuns şi acestea ar trebui să fie folosite în ordinea corectă: Testaţi aplicaţia personal, deoarece sunteţi cel care înţelege cel mai bine cum ar 

trebui să funcţioneze. Transmiteţi aplicaţia la utilizatori. În fond, ei sunt cei care au stabilit cerinţele. Transmiteţi aplicaţia (pentru testare), împreună cu specificaţiile de utilizare, unor 

  persoane neimplicate în proiect. Nedispunând de alte informaţii în afară deconţinutul documentaţiei, aceste persoane nu vor avea idei preconcepute. În plus,

nici nu vă vor deranja în cazul în care aplicaţia nu li se pare completă.

Testarea modului de utilizareAceasta este etapa următoare, la care treceţi după ce vă veţi convinge că

aplicaţia răspunde cerinţelor utilizatorilor. Testarea modului de utilizare se aplică înspecial porţiunilor vizibile ale aplicaţiei. Trebuie să apreciaţi dacă interfaţa este uşor de folosit sau este confuză pentru utilizatori? Respectă convenţiile uzuale? De fapt,dacă utilizatorilor nu le place cum se prezintă aplicaţia, nu mai contează cât de binerăspunde aceasta cerinţelor iniţiale. Deşi dumneavoastră aveţi propriile criterii de

apreciere, al sfârşitul zilei trebuie să realizaţi ceva care să mulţumească beneficiarul.Veţi lua în calcul şi timpul necesar pentru realizarea unei anumite operaţii. Dacă o

Pag. 214

Page 210: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 210/295

funcţie este executată într-un timp care depăşeşte limita, va trebui să rescrieţi codulrespectiv.

Testarea distructivăAceasta este etapa cea mai distractivă. Daţi aplicaţia altei persoane şi rugaţi-o

să o încerce prin orice metode, chiar neconvenţionale. Dacă testaţi un formular,apelaţi la cineva care nu a mai lucrat cu formulare, sau nici măcar cu calculatoare.Dacă testaţi secvenţe de cod., apelaţi la serviciile altui programator. Acesta va fifericit să vă purice programul. Şi puteţi fi sigur că, după ce descoperă câteva erorievidente, de care se bucură ca un copil, veţi creşte nivelul verificărilor pe cont  propriu. Deşi iniţial s-ar putea să vă simţiţi frustrat, în timp, veţi deveni un programator mai bun! (Şi veţi avea ocazia să vă răzbunaţi pe cei care, la rândul lor,vă vor ruga să le testaţi programele).

ÎntreţinereaSe spune că un programator îşi petrece 60% din timp cu întreţinerea programelor vechi (se mai spune şi că 85% dintre statistici sunt inventate, dar asta esteo altă poveste). Când operaţi modificări în cod, indiferent dacă este vorba

despre un program vechi sau de unul nou, este bine să luaţi în considerareurmătoarele aspecte:

Modificarea pe care o efectuaţi va avea impact asupra altor 

 programatori? Dacă este vorba de o rutină de bibliotecă, discutaţi cu alte persoane care folosesc rutina respectiv înainte a efectua modificările. Încazul în care este o eroare de cod şi alţii au tratat eroare a respectivă, dacădumneavoastră corectaţi codul, este posibil ca aplicaţiile lor să nu maifuncţioneze corect. Concentraţi-vă pe corectarea problemei curente. Efectuaţi o singură modificare la un moment dat. Imaginaţi-vă călucraţi la corectarea ai multor probleme, iar când rulaţi programul, apar erori noi. Care dintre modificări a generat aceste erori? Dacă rezolvaţi

 problemele pe rând şi le testaţi una câte una, timpul total de întreţinere aaplicaţiei s-ar putea reduce considerabil.  Nu vă pierdeţi vremea cu "aranjarea" sau îmbunătăţirea codului decâtîn cazul în care acesta este principalul motiv pentru care îl modificaţi.

Sugestiile prezentate mai sus sunt într-adevăr de bun simţ, însă veţi fi surprinscât de repede uitaţi de ele atunci când sunteţi concentrat asupra codului.

11. 5 Tipuri de eroriPuteţi (şi ar trebui) să urmaţi toate sugestiile anterioare referitoare la

 prevenirea erorilor, însă, din păcate, este foarte probabil ca în codul dumneavoastră săapară totuşi erori. Acestea pot fi de mai multe feluri; este important să ştiţi cu ce tip de

Pag. 215

Page 211: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 211/295

eroare aveţi de-a face, pentru a putea alege cea mai bună metodă de rezolvare. Amarătat în Capitolul 2 care sunt cele trei tipuri de erori: Erori de sintaxă Erori de execuţie Erori de semantică sau logice

În cele ce urmează, vom analiza fiecare dintre aceste tipuri de erori şi vomvedea cum le putem corecta.

În această etapă, este important să înţelegeţi deosebirea dintre erorileobişnuite şi erorile de programare (bugs). O eroare poate fi un eveniment util, cumsunt erorile de acces la date (Data Access Errors), care vă permit să rulaţi o secvenţăde cod la apariţia unei erori în tabel. De exemplu, dacă un tabel nu permite valori nullîntr-un anumit câmp, ar trebui să afişaţi pe ecran o casetă de dialog personalizată caresă descrie eroarea şi locul în care utilizatorul poate găsi informaţii de asistenţă în cazul

în care problemele persistă. Este o eroare detectabilă, care poate fi tratată de programator. O eroare de programare (bug) este o eroare pe care programatorul nu a prevăzut-o.

Erori de sintaxăSunt cele mai simple forme de erori, cauzate, în principal, de greşelile

de tastare. Cei care au depăşit stadiul de folosire a tastaturii cu două degete, vor face, probabil, mai puţine greşeli, însă aşa cum am menţionat, există o

metodă simplă de a le descoperi - lăsaţi această sarcină mediului Access. Dacă activaţiopţiunea de verificare a sintaxei şi vă asiguraţi că toate variabilele sunt declarate,Access vă va avertiza de fiecare dată când introduceţi instrucţiuni eronate. Oricum,veţi întâlni şi cazuri în care construcţia folosită este greşită. Şi acestea sunt semnalatede Access.

Fig. 11.1Pag. 216

Page 212: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 212/295

Să presupunem ca aţi tastat instrucţiunile For…Next sau instrucţiunile For…Each . Access nu a găsit instrucţiunea Each şi, ca urmare, aşteaptă apariţia uneivariabile. Deoarece acesta nu apare, când apăsaţi tasta Return, linia este evidenţiată,iar pe ecran este afişat un mesaj de eroare. Puteţi să executaţi clic pe butonul OK 

 pentru a anula mesajul de avertizare şi să corectaţi eroarea sau să reveniţi la eaulterior. Dacă nu rezolvaţi problema, eroarea va fi semnalată din nou la compilareamodulului.

Mai există un tip de eroare de sintaxă, care nu poate fi descoperit imediat.Examinaţi figura următoare:

Fig. 11.2Când executaţi clic pe butonul OK, funcţia CurrentDatabase este evidenţiată,

fie pentru că i-a scris greşit numele (în loc de CurrentDB), fie pentru că este vorba deo funcţie care nu există sau care nu poate fi vizualizată. Aceasta se poate întâmpla încazul în care creaţi într-un alt modul o procedură de tip Private, în loc de o procedurăde tip Public.

Erori de execuţieAşa cum sugerează şi numele lor, erorile de execuţie pot fi descoperite numai

în timpul execuţie programului. O eroare de execuţie determină oprirea execuţieicodului, cu toate că sintaxa este corectă, iar codul poate fi compilat. De fapt, succesulcompilării indică doar faptul că instrucţiunile din cod sunt în ordinea corectă şi că nus-au folosit funcţii nedefinite. Codul poate conţine însă multe alte tipuri de erori.

Folosirea extinsă a caracteristicilor Auto Tips (sugestii automate) a permisevitarea multor erori de execuţie, Access punând la dispoziţie parametri de proceduri, precum şi proprietăţi şi metode de obiecte. Totuşi, erorile sunt posibile.

Una dintre cele mai frecvente erori de aceste tip este Type Mismatch(Nepotrivire de tip). Această eroare apare atunci când atribuiţi o valoare de un anumittip unei variabile de tip diferit (incompatibile).

Pag. 217

Page 213: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 213/295

Puteţi să opriţi execuţia programului şi să evidenţiaţi linia de cod care agenerat eroarea, executând clic pe butonul Debug. În exemplul următor, unei variabilede tip Integer (întreg) i-a fost atribuită o valoare de tip text - ceea ce, evident, estegreşit:

Fig. 11.3

Acest exemplu ilustrează importanţa testării şi a aplicării consecvente a uneiconvenţii de nume, deoarece eroarea este dificil de detectat prin simpla trecere înrevistă a codului, chiar şi de către cei mai experimentaţi programatori.

Erori de semanticăRecent, în presă a apărut un articol despre o mică firmă din Marea Britanie

care a dezvoltat o metodă de scriere a aplicaţiilor software fără erori. Încă nu s-adovedit acest lucru, însă, dacă este adevărat, proprietarii acelei firme se vor îmbogăţi.Bill Gates, fii pe fază!

Erorile de semantică sunt cel mai dificil de descoperit, deoarece reprezintăerori în algoritmul logic al programului; chiar şi firma Microsoft a furnizat produse cu

astfel de erori, deci vă daţi seama cât de importante sunt. Uneori, aceste erori pot  produce erori de execuţie; în acest caz, pe ecran este afişată caseta de dialog prezentată într-un paragraf anterior, care vă permite să identificaţi linia de cod ce agenerat eroarea. Nu trebuie să consideraţi această informaţie literă de lege, pentru căeste posibil ca linia care a generat eroarea să nu fie şi cauza problemei. Este cazulliniilor de cod care conţin mai multe variabile. De exemplu, dacă una dintre variabileare o valoare incorectă, trebuie să găsiţi locul în care a fost atribuită valoarearespectivă. Dacă aţi scris un program modular, bine structurat, s-ar putea să parcurgeţitrei sau patru funcţii diferite (pentru că o funcţie a apelat alta, iar aceasta a apelat, la

rândul său, altă funcţie), astfel că trebuie să revedeţi toate procedurile implicate pentrua descoperi cauza reală a problemei. Într-o altă secţiune din acest capitol veţi învăţacum să procedaţi.

Pag. 218

Page 214: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 214/295

Testarea erorilor de semantică este dificil de efectuat, pentru că trebuie sătestaţi ceea ce consideraţi că ar trebui să facă programul, şi nu ceea ce  face efectiv.Totuşi, testarea nu este imposibilă, deoarece programatorii sunt persoane foarte atente.Un programator examinează un fragment de cod şi se gândeşte: "OK, ştiu ce face" şi

trece mai departe. Încercaţi să nu vă însuşiţi acest obicei. În procesele de testare şidepanare, trebuie să renunţaţi la ideile preconcepute şi să analizaţi problemele plecândde la zero. Uneori este dificil, dar merită să încercaţi.

Haideţi să analizăm o defecţiune apărută în timpul execuţiei unei aplicaţii,care a fost generată o eroare semantică. Acest exemplu particular demonstrează faptulcă un mesaj de eroare poate să nu indice cauza reală a erorii.

Încercaţi singur - Erori de execuţie şi de semantică

1. Creaţi un nou modul şi adăugaţi procedura următoare:

Această procedură împarte un număr la altul.

2. Compilaţi codul executând clic pe butonul Compile Loaded Modules şisalvaţi modulul.

3. În continuare, creaţi un formular nou, cu trei controale de text neasociate şiun buton de comandă. Modificaţi titlurile ca în figura alăturată şi schimbaţi proprietăţile Name ale casetelor de text cu txtNumber1, txtNumber2, şitxtResult, iar a butonului de comandă cu cmdDivide.

4. Acum adăugaţi următoarea linie de cod în procedura evenimentului OnClick pentru butonul de comandă:

5. Comutaţi formularul în modul de afişare Form şi introduceţi următoarelenumere: 4 şi 2

Pag. 219

Public Function DivideNumbers (dblNum1 As Double, dbl1Num2 AsDouble) _ As Double

DivideNumbers = dblNum1 / dblNum2

End Function

txtResult = DivideNumbers (txtNumber1, txtNumber2)

Page 215: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 215/295

Rezultatul este cel pe care îl aşteptaţi.

6. Acum încercaţi din nou, dar introduceţi valoarea 0 pentru al doilea număr.Şi-a făcut apariţia cunoscuta eroare Division by zero (Împărţire la zero).

7. Executaţi clic pe butonul Debug şi ajungeţi direct la linia de cod din

funcţia DivideNumbers în care a apărut eroarea.Acum trebuie să decideţi dacă aceasta este linia cu probleme. Eroarea a fost generatăde numărul introdus de utilizator - în mod evident, trebuie să verificăm dacă numărulintrodus în casetă nu este zero.Datele au fost transferate din altă procedură, deci unde verificăm valorile introduse deutilizator (în procedura respectivă sau în aceasta)? În cazul de faţă, verificarea ar trebui să fie efectuată în funcţia DivideNumbers. O funcţie trebuie să fie completautonomă - dacă fiecare procedură care o apelează verifică valorile, codul se extindefoarte mult. Prin urmare, este bine să adăugaţi secvenţa de verificare aici (în funcţie).

8. Adăugaţi următoarele linii de cod în funcţia DivideNumbers. Nu uitaţi săsalvaţi programul după ce efectuaţi modificările.

 Public Function DivideNumbers (dblNum1 As Double, dbl1Num2 As Double) _ As Double

DivideNumbers = dblNum1 / dblNum2

 End Function

9. Reveniţi în formular şi reluaţi ultimul exemplu (cel cu 0). De data aceasta,nu mai apare nici un mesaj de eroare. Funcţia nu mai încearcă să efectuezeîmpărţirea la zero. Oricum probleme nu este încă rezolvată. Matematicieniicare vor analiza programul vor observa că, deşi nu apare un mesaj deeroare, răspunsul nu este corect. Rezultatul împărţirii unui număr la 0 nueste 0. Şi încă nu am analizat toate valorile eronate care ar putea fiintroduse de un utilizator. De exemplu, ce se întâmplă dacă un utilizator introduce o literă în loc de un număr? Veţi primi un alt mesaj de eroare, dedata aceasta Run-Time Error 13, Type Mismatch. Acest mesaj vă

Pag. 220

If dbl1Num2 <> 0 Then

End If 

Page 216: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 216/295

comunică faptul că tipurile de variabile sunt incompatibile şi că se încearcăîmpărţirea printr-o literă sau printr-un şir de caractere. Trebuie să utilizămo funcţie care se poate "apăra" singură, garantând astfel că nu va mai figenerată nici o eroare de execuţie.

10. Modificaţi funcţia DivideNumbers după cum urmează:

11. În continuare, modificaţi şi procedura de tratare a evenimentului On Click  pentru butonul de comandă:

12. Rulaţi din nou exemplul. De data aceasta, nu ar mai trebui să apară nici oeroare, indiferent de valorile introduse.

Cum funcţionează?La terminarea exerciţiului, funcţia acceptă trei argumente. Primele două sunt

deja cunoscute - acestea transmit cele două numere care trebuie împărţite. Al treileaargument este folosit pentru a stoca rezultatul împărţirii şi a transfera acest rezultat înformular după terminarea cu succes a operaţiei. Deoarece numărul de parametri

Pag. 221

Public Function DivideNumbers (dblNum1 As Variant, dbl1Num2 As _ Variant, dblRV As Double) As Boolean

On Error GoTo DivideNumbers_Err dblRV = dblNum1 / dblNum2DivideNumbers = True

DivideNumbers_OK Exit Function

DivideNumbers_Err:DivideNumbers = FalseResume DivideNumbers_OK

End Function

Dim bolErrorCheck As BooleanDim dblCalResult As Double

bolErrorCheck = DivideNumbers (txtNumber1, txtNumber2, dbCalResult)

If bolErrorCheck = True ThentxtResult = dblCalcResult

ElsetxtResult = "Semantic Error"

End If 

Page 217: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 217/295

acceptaţi de funcţie s-a modificat, a fost actualizat corespunzător şi numărul de parametri cu care este apelată funcţia.

Rezultatul operaţiei este transmis prin variabila booleană bolErrorCheck .Valoarea acesteia depinde de valoarea returnată de funcţie. Dacă aceasta este True,este afişat rezultatul calculului; dacă valoarea este False, pe ecran este afişat mesajul

Semantic Error.Dacă în operaţia de împărţire apare o eroare, detecatrea acesteia, care a fost permisă prin activarea opţiunii On Error GoTo DivideNumbers_Err, redirecteazăexecuţia programului la eticheta DivideNumbers_Err. În acest punct, valoarea derăspuns a funcţiei este stabilită la False şi se iese din funcţie prin intermediul eticheteiDivideNumbers_OK . Desigur, dacă operaţia este corectă, valoarea de răspuns afuncţiei este configurată la True.

În acest fel, sarcina de a verifica valorile introduse cade în sarcina proceduriiapelante. Probabil că nu veţi folosi niciodată o funcţie doar pentru a împărţi două

numere, însă acest exemplu a arătat care sunt principiile de lucru. Procedura trebuie săfie capabilă să reacţioneze la datele de intrare incorecte, să nu ascundă erorile şi să letrateze corespunzător, dacă sunt disponibile informaţiile referitoare la codul erorii.

 Localizarea erorilor În procesul de detectare a erorilor, trebuie să vă amintiţi că mediul Access este

dirijat de evenimente, iar codul poate fi activat în cale mai diverse zone. Să luăm ca

exemplu deschiderea unui formular. Ce evenimente credeţi că sunt generate? În total,sunt cinci evenimente:Open Load Resize Activate Current

Închiderea unui formular generează trei evenimente:Unload Deactivate Close

Ca urmare, dacă la deschiderea unui formular apare o problemă, trebuie săverificaţi toate celelalte evenimente. O metodă de a verifica toate procedurile dintr-un

modul este selectarea opţiunii Full Module View din pagina Module a ferestreiOptions, accesibilă din meniul Tools.

Acelaşi rezultat se obţine prin executarea unui clic pe butonul aflat în colţuldin stânga-jos al ferestrei modulului.

Aceste acţiuni determină afişarea tuturor procedurilor în fereastra modulului,separate prin câte o linie orizontală (dacă este selectată opţiunea Procedure Separator).În cazul în care nu aţi selectat această opţiune, puteţi trece de la o procedură la alta

folosind tasta Ctrl împreună cu săgeţile de deplasare în sus şi în jos.

Pag. 222

Page 218: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 218/295

Alte eroriAceastă secţiune este dedicată tuturor celorlalte cauze care pot genera o eroare

într-un modul VBA. Desigur, numărul erorilor posibile este direct proporţional cuimportanţa aplicaţiei şi invers proporţional cu timpul necesar pentru depanare!

Una dintre cauzele generatoare de erori poate fi folosirea unor aplicaţii

externe, cum ar fi bibliotecile cu legare dinamică (DLL) sau controalele personalizate.Dacă programatorii care au scris aceste aplicaţii le-au testat corespunzător, nu ar trebui să vă confruntaţi cu defecţiuni de funcţionare, cu mici erori de programare(bugs).

Există şi alte cauze, cum ar fi memoria insuficientă sau o bază de date cu oînregistrare alterată, care pot provoca evenimente foarte neplăcute. Depăşireamemoriei disponibile (care este posibilă chiar şi sub Windows 95) semnifică faptul căAccess nu are suficiente resurse pentru a afişa toate elementele ecranului.

Cu toate că în astfel de situaţii nu prea aveţi ce să faceţi, este bine să ştiţi ce

tipuri de probleme care pot cauza erori inexplicabile. Dacă vreţi un răspuns, parcurgeţiurmătoarele etape: Verificaţi în detaliu codul scris de dumneavoastră Încercaţi să rulaţi aplicaţia pe un alt calculator 

Dacă funcţionează corect, analizaţi diferenţele dintre cele două sistemede calcul. S-au întâlnit cazuri în acre o astfel de eroare a fost acuzată de o bibliotecă DLL mai veche, existentă pe unul dintre calculatoare, celălalt

dispunând de o versiune actualizată a bibliotecii. Rugaţi pe altcineva să verifice codul sau parcurgeţi-l dumneavoastră pas cu pas, explicând toate etapele şi procedurile. Este uimitor cât derepede putem detecta o eroare atunci când explicăm cuiva fiecareinstrucţiune a programului. Intraţi în panică!

 Nu ar trebui să ajungeţi niciodată la ultima etapă, deoarece puteţi găsi întotdeaunaundeva sau la cineva răspunsul la problema dumneavoastră. Dacă este posibil, folosiţireţeaua dezvoltatorilor de produse Microsoft (Microsoft Developer Network) sau alte

servicii on-line, cum sunt Microsoft Network, CompuServe şi Internet. Veţi intra într-o altă lume de dimensiuni foarte mari, unde toţi (sau majoritatea) sunt dispuşi să văajute.

11.6. Depanarea

După ce aţi aflat care sunt metodele de prevenire a erorilor şi tipurile de eroricare pot apărea, trebuie să ştiţi şi cum să detectaţi erorile. Pe măsură ce câştigaţi

experienţă în programarea cu VBA, veţi vedea că instinctul vă va ajuta tot mai mult şiveţi descoperi erorile doar pe baza intuiţiei. Până atunci, vă vom indica direcţia în caretrebuie să căutaţi.

Pag. 223

Page 219: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 219/295

Execuţia programuluiAccess vă pune la dispoziţie ,mai multe metode care permit navigarea prin

codul aflat în execuţie. Astfel, puteţi să începeţi dintr-un loc în care să ştiţi că programul funcţionează corect şi să avansaţi pas cu pas spre zona în care se manifestă

eroarea.Există două locuri în care găsiţi toate facilităţile pentru depanare.• Primul este bara cu instrumente Visual Basic• Al doilea este meniul Debug

Prin combinarea acestora, obţineţi controlul complet asupra modului deexecuţie al programului. În următoarele secţiuni vor fi explicate şi funcţiile tuturor  butoanelor, precum şi utilizările acestora; apoi vom trece la o aplicaţie practică.

Puncte de întrerupere

Punctele de întrerupere (breakpoints) sunt esenţiale în depanare, pentru că vă permit să marcaţi liniile la care doriţi ca execuţia programului să fie oprită temporar.Puteţi stabili punctele de întrerupere în patru feluri:

Executaţi clic pe butonul Toggle Breakpoint. Selectaţi opţiunea Toggle Breakpoint din meniul Debug. Apăsaţi tasta F9. Executaţi clic pe marginea din stânga a ferestrei modulului, în dreptulinstrucţiunii corespunzătoare.

Toate aceste acţiuni sunt de comutare, adică stabilesc un punct de întrerupere acolounde nu există şi elimină unul existent. Nu există o limită pentru numărul de punctede întrerupere care pot exista la un moment dat într-un program.Când Access întâlneşte o linie cu punct de întrerupere, programul este oprit, pe ecraneste afişată fereastra cu codul rulat în momentul respectiv, în cadrul căreia esteevidenţiată linia cu punctul de întrerupere. Puteţi folosi fereastra de depanare pentru ainspecta sau a stabili valorile variabilelor, sau chiar pentru a schimba codul înfereastra modulului. Programul va rămâne activ până când îl opriţi.Execuţia programului poate fi oprită şi apăsând tasta Ctrl+Break în timpul rulării

codului. Această combinaţie de taste are acelaşi efect cu un punct de întrerupere, permiţîndu-vă inspectarea variabilelor şi chiar modificarea codului.

Continuarea execuţieiPuteţi folosi butonul Go/Continue pentru a continua execuţia unui program

oprit temporar. Execuţia va începe de la linia curentă şi va continua până laintroducerea unei date de către utilizator sau până ce se ajunge la un alt punct deîntrerupere.

Stoparea execuţieiPuteţi acţiona oricând butonul End pentru a opri execuţia programului.

Pag. 224

Page 220: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 220/295

Reiniţializarea execuţieiButonul Reset opreşte execuţia programului şi reiniţializează toate varibilele.

Este cel mai util instrument în cazul în care folosiţi variabile statice pentru memorareavalorilor. De asemenea, puteţi folosi acest buton atunci când depanaţi module deformulare sau de rapoarte. Când execuţia se opreşte, nu puteţi accesa formularul sau

raportul respectiv dacă nu executaţi clic pe butonul Continue sau Reset.Execuţia codului pas cu pasOprirea într-un punct de întrerupere este foarte utilă, însă cum procedaţi dacă

doriţi să analizaţi liniile de cod în timpul execuţiei? Stabilirea unui punct deîntrerupere la fiecare linie de cod ar fi un proces foarte laborios; de aceea, a fostintrodusă posibilitatea de execuţie a codului pas cu pas. După oprirea unui program, puteţi rula o singură instrucţiune la un moment dat, având astfel posibilitatea să aflaţicare linii de cod sunt corecte şi care conţine erori. Există mai multe posibilităţi de a

executa codul pas cu pas: Butonul Step Into execută doar linia pe care este plasat cursorul. Dacăaceastă linie conţine apelul unei proceduri, va determina intrarea în codul procedurii şi continuarea execuţiei pas cu pas. Butonul Step Over execută tot linia pe care este plasat cursorul. Dacălinia curentă conţine o procedură, codul acesteia este executat normal -fără a fi parcurs pas cu pas. Ulterior, la revenirea din procedură, se treceautomat la execuţia pas cu pas a programului.

Butonul Step Out continuă execuţia programului de la proceduracurentă şi opreşte execuţia la linia care urmează după procedura apelantă.Este un fel de combinaţie între Step Out şi Step Over.

Dacă aveţi nevoie de mai multă flexibilitate, puteţi folosi opţiunea Run ToCursor din meniul Debug. Plasaţi cursorul pe linia la care doriţi să se opreascăexecuţia programului şi apoi selectaţi Run To Cursor. Toate liniile până la cea cucursorul vor fi parcurse normal (nu pas cu pas), ca şi cum pe această linie a fot plasatun punct de întrerupere temporar.

Avantajul metodei Step Into este că puteţi verifica fiecare linie de cod dintoate procedurile întâlnite în timpul execuţiei. Însă există şi dezavantajul că este ometodă mare consumatoare de timp, în special dacă procedurile conţin bucle. MetodaStep Over vă permite să executaţi rapid procedurile despre care ştiţi că sunt corecte.Şi, desigur, dacă folosiţi proceduri care au fost deja testate şi depanate, puteţi trece peste ele pentru a vă concentra asupra codului nou, unde vă aşteptaţi să apară erori.

Opţiunea Run To Cursor este extrem de utilă în cazul în care codul conţine bucle (structuri ciclice) pentru că vă permite să săriţi rapid la instrucţiunea de după buclă, economisind astfel mult timp.

Pag. 225

Page 221: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 221/295

Repetarea execuţiei liniei de codPosibilitatea de a repeta execuţia anumitor linii de cod a fost introdusă încă din

Access 95, însă a fost mult simplificată în Access 97. Acest lucru poate reprezenta unavantaj real în cazul în care v-aţi oprit la un punct de întrerupere şi observaţi că o liniede cod care a fost deja executată conţine o eroare. În această situaţie, puteţi să reveniţi

la linia respectivă şi să repetaţi execuţia codului (după corectarea erorii). În acestscop, trageţi săgeata de pe marginea ferestrei modului în noua locaţie. Executaţi clic pe linia la care s-a oprit execuţia codului şi apoi, ţinând apăsat butonul mouse-ului,trageţi cursorul pe o altă linie.

Observaţi transformarea cursorului într-o săgeată care indică noua linie. Cândajungeţi pe linia următoare celei pe care vreţi să poziţionaţi cursorul, eliberaţi butonulstâng al mouse-ului:

Când continuaţi execuţia programului, acest va fi reluat de la noua linie decod. O altă metodă de efectuare a acestei operaţii este să plasaţi cursorul pe noua linie

şi să apăsaţi combinaţia de taste Ctrl+F9.Saltul peste liniile de codSaltul peste liniile de cod poate fi util, însă presupune multă atenţie. După

 plasarea cursorului pe o linie care nu a fost încă executată, puteţi folosi opţiunea Set Next Statement din meniul Debug pentru a comunica mediului Access că aceasta estelinia pe care doriţi să o executaţi în continuare. Toate liniile de cod anterioare suntignorate.

Opţiunea Show Next Statement vă va informa ce linie de cod urmează să fieexecutată. Este o informaţie utilă în cazul în care aţi analizat alte proceduri şi aţi pierdut poziţia curentă din fereastra de cod.

Modificarea coduluiAccess permite modificarea codului în timp ce execuţia este oprită, astfel încât

dumneavoastră să puteţi corecta eventualele erori descoperite. Pentru a continuaexecuţia programului de la linia corectată, executaţi clic pe butonul Continue. De fapt,chiar dacă rescrieţi secţiuni întregi de cod, puteţi continua execuţia programului.Totuşi, Access nu vă va permite să modificaţi o declaraţie. Procedând astfel, înseamnăcă întreaga structură a codului se modifică (nu numai câteva linii) şi veţi primi unmesaj prin care sunteţi întrebat dacă doriţi să abandonaţi modificările sau săreiniţializaţi programul. Selectarea opţiunii de reiniţializare are acelaşi efect cuexecutarea unui clic pe butonul Reset - se opreşte execuţia codului, sunt reiniţializatetoate variabilele, iar punctul următor de execuţie se mută pe prima linie de cod, pregătind o nouă pornire.

Pag. 226

Page 222: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 222/295

Dacă doriţi să modificaţi anumite variabile, fără să reiniţializaţi programul, puteţi să ieşiţi din această procedură, să modificaţi variabilele locale şi apoi să stabiliţiurmătoarea instrucţiune pentru ca procedura să poată fi rulată din nou.

Stiva de apeluri

Când depanaţi programe mari sau complexe, ori programe bine modularizate, puteţi să pierdeţi punctul curent din program. Dacă executaţi clic pe butonul CallStack (Stiva de apeluri), veţi vedea pe ecran o listă cu procedurile active:

Observaţi că acestea nu sunt procedurile care au fost rulate, ci procedurile caresunt executate în momentul respectiv. De exemplu, dacă procedura A apelează procedura B şi B apelează C, iar dumneavoastră opriţi execuţia programului în C,executând un clic pe butonul Calls, veţi vedea pe ecran C, B, A, adică proceduraexecutată în mod curent şi cele care au apelat-o. Dacă aţi terminat execuţia proceduriiC şi apoi aţi continuat execuţia procedurii B, în fereastra de apeluri vor fi afişate doar 

B şi A. Este una dintre situaţiile în care se recomandă folosirea opţiunii Show NextStatement, pentru că s-ar putea să uitaţi de unde aţi început analiza procedurilor chiar în mijlocul procesului de depanare.

Fereastra de depanare (Debug)Aţi văzut deja mai multe exemple de utilizare a ferestrei de depanare, unde

 puteţi introduce comenzi care sunt executate imediat - în versiunile anterioare deAccess, aceasta era numită fereastra imediată. Oricum, este fereastra folosită cel mai

frecvent în depanare. În cadrul ei, puteţi afişa datele, puteţi executa codul şi puteţichiar analiza variabilele.De asemenea, puteţi folosi fereastra de depanare pentru a schimba conţinutul

variabilelor, astfel încât să corectaţi valorile care pot genera erori. Dacă

bănuiţi că o anumită valoare va determina apariţia unor probleme în cod, puteţi sămodificaţi valoarea respectivă şi să continuaţi apoi lucrul. Este o metodă foarte utilăîn timpul testării, permiţându-vă să introduceţi valori eronate în variabile pentru atesta răspunsul procedurilor.

Dacă aţi folosit versiuni anterioare de Access, veţi observa că fereastra dedepanare a fost considerabil modificată; haideţi să vedem cum arată noua fereastră:

Pag. 227

Page 223: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 223/295

Fig. 11.4

Panoul Locals afişează variabilele şi valorile conţinute de acestea în cadrul procedurii

active la momentul respectiv. Panoul Watch afişează variabilele pe care doriţi să leurmăriţi în cadrul execuţiei codului. În dreapta există o casetă de text, care afişeazăstarea procedurii, şi butonului de construcţie, care afişează fereastra Call Stack.Panoul de jos, Immediate Pane, a fost folosit până acum pentru apelurile de proceduri.

Elemente de urmărireButonul Instant Watch (Urmărire imediată) vă permite să stabiliţi un element

de urmărire pentru variabile sau expresii. Puteţi folosi elementele de urmărire şi ca puncte de întrerupere condiţionale. Dacă specificaţi un element de urmărire (watch) cu

opţiunile Break When Expression Is True (opreşte execuţia când expresia esteadevărată) sau Break When Expression has Changed (opreşte execuţia la modificareaexpresiei), codul va fi oprit la execuţie, permiţându-vă să analizaţi atât elementul deurmărire, cât şi valorile variabilelor.

Este o metodă utilă, mai ales când aveţi o variabilă care provoacă probleme,dar nu ştiţi unde a fost valoarea respectivă. În acest caz, puteţi să adăugaţi o opţiunede întrerupere pentru elementul de urmărire, iar execuţia programului va fi oprităimediat ce valoarea este adevărată sau se modifică. Prin

utilizarea acestei variante de punct de întrerupere, execuţia programului esteîncetinită, ceea ce nu reprezintă o problemă la depanare.

Încercaţi singur - Depanarea codului

Pentru acest exemplu, trebuie să deschideţi modulul Chapter 11 Debuggingdin fişierul Whisky11.mdb în modul de afişare pentru proiectare (Design). Modululconţine următoarele trei proceduri:

DisplayWhisky, care afişează toate tipurile de whisky pentru un numede regiune. GetWhisky, care încearcă toate tipurile de whisky pentru o regiunedintr-o matrice globală. DisplayWhiskies, care afişează conţinutul matricei globale.

DisplayWhisky acceptă ca intrare o matrice cu nume de regiuni,astrRegions(), şi apelează funcţia GetWhisky o dată pentru fiecare regiune dinmatrice. Apoi apelează procedura DisplayWhiskies, care afişează în fereastra dedepanare valorile existente în matricea globală. Pentru a găsi toate înregistrărilecorespunzătoare regiunii selectate, GetWhisky creează o instrucţiune SQL şi apoi

Pag. 228

Page 224: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 224/295

adaugă fiecare tip de whisky în matricea globală. Există şi un argument opţional, care permite includerea sau excluderea preţului produsului după preferinţe.

Vom experimenta fiecare dintre aceste funcţii şi vom vedea cum le putemdepana atunci când descoperim o eroare; în plus, vom analiza variabilele pe care leconţin. Deoarece veţi controla execuţia funcţiilor din fereastra de depanare, este

necesar să deschideţi şi această fereastră.1. În primul rând trebuie să stabiliţi un punct de întrerupere şi, deoarece doriţi

să executaţi codul pas cu pas, să îl plasaţi pe prima linie executabilă dinfuncţia DisplayWhisky:

2. Apoi apelaţi procedura din fereastra de depanare:

Ar trebui să observaţi oprirea execuţiei codului. Executaţi clic pe DebugWindow pentru a aduce această fereastră în prim-plan:

3. Haideţi să analizăm în detaliu panoul Locals:

Acest panou afişează toate variabilele care sunt active sau care se găsesc îndomeniu. Prima linie este pentru modul, iar semnul plus indică posibilitateaexpandării pentru a afişa elementele componente. A doua linie afişează

atrRegions, o matrice locală care nu are încă atribuite valori. A treia linie conţinestrRegion, o variabilă locală cu valoarea Empty, care are valoarea atribuită automatla crearea variabilelor Variant.

4. Executaţi clic pe semnul plus (sau executaţi dublu-clic pe linie) pentru aexpanda linia Chapter 11 Debugging:

Pe ecran sunt afişate cele două variabile globale, împreună cu tipurile şivalorile lor. Puteţi vedea că mastrWhiskies este o matrice de tip typWhisky şică strSQL este un şir (string). Expandaţi şi astrRegions pentru a vedea ceconţine.

Deoarece astrRegions este o matrice, pe ecran va fi afişat fiecare element almatricei, împreună cu valoarea conţinută.

5. Haideţi să încercăm o altă metodă de analiză a variabilelor. În fereastra dedepanare, puteţi introduce un semn de întrebare urmat de numele variabilei

Pag. 229

DisplayWhisky "Islay", "Highland"

Page 225: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 225/295

Pe ecran va fi afişat numele regiunii pe care l-aţi transmis ca prim argument al procedurii. Puteţi analiza şi variabila strRegion, însă aceasta nu conţine nimic, pentrucă linia nu a fost încă executată şi, ca urmare, nu a primit nici o valoare.

6. Acum executaţi clic pe butonul Step Into pentru a rula această linie de cod.

Poziţionaţi cursorul pe linia strRegion din buclă, pentru a vedea o altămetodă de analiză a variabilelor.

Pe ecran apare o casetă explicativă (etichetă ToolTip) în care este afişatăvaloarea variabilei.

7. Punctul de întrerupere este în continuare pe linia For Each, însă liniacurentă este următoarea, care apare evidenţiată. Acum, să vedem ultimametodă de analiză a variabilelor, Quick Watch (Urmărire rapidă).

Poziţionaţi cursorul pe strRegion şi executaţi clic pe butonul Quick Watch(sau folosiţi combinaţia de taste Shift+F9):

Prin această metodă, pe ecran este afişată aceeaşi informaţie ca în panoulLocals, însă într-un format puţin diferit. În plus, aveţi posibilitatea de a adăuga acestelement de urmărire în lista Watch. Vom arăta imediat cum se procedează, însădeocamdată, executaţi clic pe butonul Cancel şi ieşiţi din fereastră.

8. Folosiţi butonul Step Into pentru a trece la procedura GetWhiskies şi

executaţi clic pe Debug Window pentru a duce această fereastră în prim –  plan.

Observaţi că variabilele pentru procedura GetWhiskies sunt afişate acum înfereastra Locals. Argumentele au valori, însă nu şi variabilele locale, pentru că nu le-am configurat încă.

9. Acum este momentul să analizăm stiva de proceduri, aşa încât executaţi clic pe butonul Calls pentru a vedea unde ne aflăm.

În fereastră puteţi vedea ordinea în care aţi executat procedurile. Proceduracurentă (activă) este afişată în fruntea listei, iar procedura pe care aţi apelat-o apareimediat dedesubt. Prima procedură este la sfârşitul listei. Chiar şi din acest exemplusimplu, vă puteţi da seama ce se întâmplă în cazul programelor mari.

10. Să spunem că doriţi să executaţi codul pas cu pas, până la linia care citeşteurmătoarea înregistrare din setul de înregistrări. Plasaţi cursorul pe linia

Pag. 230

recR.MoveNext

Page 226: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 226/295

şi alegeţi Run To Cursor din meniul Debug. Execuţia continuă până lalinia selectată. Acum sunteţi în etapa în care aţi completat deja un elemental matricei, iar execuţia s-a oprit pe linia selectată de dumneavoastră;treceţi în fereastra de depanare. În primul rând, expandaţi variabila recR  pentru a vedea setul de înregistrări:

Remarcaţi că sunt disponibile toate proprietăţile pentru seturi de înregistrări. Unele nuau valori sau nu pot fi aplicate în cazul acestui tip de set de înregistrări, însă toate aufost afişate instantaneu. Derulaţi conţinutul ferestrei. Vei vedea colecţiile setului deînregistrări.

Observaţi că acest set de înregistrări conţine şase câmpuri care pot fiexpandate pentru a analiza detaliile corespunzătoare fiecăruia. Veţi avea posibilitateasă examinaţi aceste detalii mai târziu; deocamdată, să continuăm exerciţiul.

11. Derulaţi fereastra până în partea superioară şi expandaţi Chapter 11Debugging, apoi mastrWhiskies:

Fiind prima iniţializare a datelor, a fost creat numai primul membru al matricei, iar cele trei elemente ale acestuia conţin valorile corecte. Este mult mai simplu decât

 prin vechea metodă, care presupunea introducerea fiecărui element în fereastra de

depanare pentru a-i vedea conţinutul.12. Plasaţi cursorul pe linia recR.Close şi selectaţi opţiunea Run To Cursor.

Execuţia codului va continua până la linia solicitată. Metoda este utilă maiales la depanarea unui cod cu structuri ciclice, când puteţi să plasaţicursorul pe instrucţiunea de după buclă şi apoi să săriţi peste buclarespectivă fără să mai stabiliţi un punct de întrerupere.

13. Executaţi de două ori clic pe butonul Step Into pentru a reveni la proceduraDisplayWhisky, adică la funcţia apelantă. Parcurgeţi câteva instrucţiuni până când ajungeţi la următoarea linie de cod din procedura GetWhiskies:

Aţi ajuns din nou la bucla în care este completată matricea globală. Vreţi săvedeţi numele de whisky fără ca acesta să fie tipărit în fereastra de depanare şi fără săcomutaţi panoul Locals - astfel că stabiliţi un element de urmărire (watch) pe aceastăvariabilă pentru a o vedea permanent.

14. Evidenţiaţi recR("WhiskyName") şi executaţi clic pe butonul Quick Watch. Pe ecran este afişată fereastra Quick Watch, care conţine variabila

Pag. 231

.strName = recR("WhiskyName")

Page 227: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 227/295

selectată şi valoarea acesteia la momentul curent. Acum executaţi clic pe butonul Add. În urma acestei comenzi, treceţi în panoul Watch

Aici apar aceleaşi informaţii ca în panoul Locals, însă numai pentru variabilelecare vă interesează. Dacă aveţi variabile din mai multe proceduri, este afişat şi

contextul. În acest caz, contextul este pentru modulul curent.15. Poziţionaţi ferestrele astfel încât să vedeţi atât variabila urmărită cât şi

codul, apoi parcurgeţi pas cu pas programul până ajungeţi la instrucţiunearecR.MoveNext. urmăriţi modificarea valorii variabilei în timpulexecuţiei.

16. Puteţi adăuga şi alte elemente de urmărire executând clic cu butonul dreptal mouse-ului în fereastra de urmărire şi selectând opţiunea Add Watch…Pe ecran apare următoarea casetă de dialog:

17. Acum puteţi alege nu numai ceea ce doriţi să urmăriţi, dar şi modul în carese face urmărirea. Tipul de urmărire (Watch Type) al unei expresii deurmărire (Watch Expression) este similar cu cel ape care

tocmai l-aţi văzut: afişează valoarea expresiei pe care o urmăriţi. OpţiuneaBreak When Value Is True (Opreşte execuţia când valoarea esteadevărată) va adăuga o expresie de urmărire şi va opri execuţia  programului atunci când valoarea expresiei este adevărată. Opţiunea

Break When Value Changes (Opreşte execuţia la modificarea valorii) vaopri execuţia programului atunci când valoarea expresiei se modifică.Această metodă poate fi foarte utilă dacă aveţi o variabilă globală a căreivaloare este modificată de o altă procedură, dar nu sunteţi sigur unde areloc modificarea. În acest caz, puteţi să stabiliţi un element de urmărire şisă rulaţi programul în mod normal; la fiecare modificare a expresiei,execuţia codului va fi oprită.

18. Haideţi să experimentăm opţiunea Break When Value Is True, pentru aopri execuţia programului atunci când preţul unei sticle de whiskydepăşeşte 30 de lire.

Executaţi clic pe butonul OK şi observaţi că elementul de urmărire a fostadăugat în listă:

Valoarea curentă este falsă.

19. Executaţi clic pe butonul Go/Continue şi fereastra Watch va fi afişată în  prim-plan, indicând faptul că valoarea expresiei este acum adevărată(True):

Pag. 232

Page 228: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 228/295

Programul şi-a continuat execuţia până când a găsit un preţ mai mare de 30 delire. Corectitudinea opririi programului poate fi verificată în fereastra Localssau în panoul Debug:

20. Să presupunem că preţul nu este corect. Nu puteţi modifica valoarea înexpresia recR("Price") fără a executa o instrucţiune recR.Edit saurecR.Update, însă puteţi schimba valoarea în matrice. Introduceţi nouavaloare în panoul de depanare şi apăsaţi tasta Return:

Este o operaţie similară cu configurarea unei variabile în cadrul codului.

21. Acum acţionaţi butonul Continue pentru a continua execuţia, dar nu pas cu pas. Procedura va fi finalizată, iar detaliile corespunzătoare vor fi afişate

  pe ecran. Dacă derulaţi puţin conţinutul ferestrei, găsiţi sortimentulGlengoyne, vechi de 12 ani, adică valoarea pe care tocmai aţi modificat-o.

Observaţi că noul panou Locals oferă un mar avantaj programatorului. În plus,este util ca instrument de instruire, pentru examinarea proprietăţilor obiectelor pemăsură ce sunt folosite în program. Merită să faceţi un efort pentru a învăţa să îlfolosiţi, deoarece pe termen lung, veţi economisi foarte mult timp.

11.7 Utilizarea sistemului de asistenţă (Help)Executarea programelor pas cu pas vă poate ajuta să descoperiţi erorile, însă

nu cazul să începeţi direct cu această metodă. În primul rând, ar trebui să consultaţifişierul de asistenţă (Help), deoarece conţine o listă cu cele mai frecvente tipuri deerori şi descrierea cauzelor care le-au generat. În general, casetele de dialog pentrumesajele de eroare, care apar supărător de des în procesul de depanare a codului,include un buton Help. Dacă poziţionaţi cursorul pe un cuvânt cheie din fereastra decod şi apăsaţi tasta F1, pe ecran este afişat textul de asistenţă contextuală pentrucuvântul respectiv. De asemenea, puteţi selecta opţiunea Contents and Index dinmeniul Help pentru a găsi informaţii despre un anumit subiect - desigur, Accessacceptă opţiunea Answer Wizard (în acelaşi meniu), care vă permite să introduceţiîntrebări între-un limbaj natural. În plus, puteţi folosi noul Office Assistant, carerăspunde solicitărilor dumneavoastră:

Pag. 233

Page 229: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 229/295

Executaţi clic pe butonul de căutare (Search), iar Clipit va afişa pe ecran olistă de subiecte:

Fig.11. 5Pag. 234

Page 230: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 230/295

Fişierul de asistenţă (Help) este cu adevărat util în situaţiile în care mesajul deeroare returnat de sistem nu descrie cauza erorii. Să luăm ca exemplu proceduraErrorHelp:

Această procedură acceptă ca parametru de intrare un şir, care este folosit pentru a selecta câmpul din dreapta al tabelului Bottling. Încercaţi să rulaţi proceduracu parametrul următor:

Call ErrorHelp ("DistillationDate")

Şi veţi primi o listă cu toate datele la care au fost distilate băuturile. Încercaţi şi cu parametrul următor:

Call ErrorHelp ("DateDistilled")

Pag. 235

Public Sub ErrorHelp(strColumn As String)'Scop: Prezinta un mesaj de eroare util la cautarea unei

coloane intr-un set de inregistrari'Argumente: strColumn Coloana care este cautata'Valoarea returnata: nici una

Dim dbCurrent  As Database ' Baza de date curentaDim recBottling  As Recordset ' Un instantaneu al tabelului cu

' sortimentele de bauturiDim strSQL  As String ' sir SQL

'construieste un sir SQL si deschide setul de inregistraristrSQL = "SELECT " & strColumn & " FROM Bottling" Set dbCurrent = CurrentDb()Set recBottling = dbCurrent.OpenRecordset (strSQL, dbOpenSnapshot)

' parcurge setul de inregistrari tiparind coloanaWhile Not recBottling.EOF  

Debug.Print recBottling(strColumn)recBottling.MoveNext 

recBottling.Close

End Sub

Page 231: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 231/295

Veţi primi acest mesaj de eroare:

Fig.11.6

 Nu vă spune prea mult, nu-i aşa? Executaţi clic pe butonul Help şi veţi vedea pe ecrano fereastră de asistenţă cu un conţinut mult mai edificator:

Fig.11.7

Al doilea paragraf este important, indicând faptul că încercaţi să selectaţi unnume de câmp necunoscut.

Tratarea erorilorAcum, după ce aţi aflat cum puteţi să preveniţi greşelile şi cum să le detectaţi

 pe cele care nu pot fi anticipate, trebuie să învăţaţi cum să trataţi erorile într-un modcât mai elegant. Reţineţi că  greşelile şi erorile sunt lucruri diferite. Un proiect bun, otestare şi o depanare corespunzătoare ar trebui să elimine toate greşelile din codul

dumneavoastră. Însă acesta nu înseamnă că nu vor apărea erori.De exemplu, să ne imaginăm că programul pe care l-aţi scris accesează un

anumit fişier de pe disc - să presupunem că este vorba de un fişier legat. Ştiţi că în codPag. 236

Page 232: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 232/295

nu există greşeli, aşa încât va accesa întotdeauna corect fişierul respectiv şi va prelucra datele fără nici o problemă. Însă erori pot apărea în continuare - dacă cinevamută fişierul în altă locaţie pe disc sau îl şterge, veţi primi un mesaj de eroare.

Există situaţii în care doriţi să ignoraţi o anumită eroare sau să declanşaţi oaltă acţiune decât cea prevăzută de Access 97 pentru eroarea respectivă. În acest caz,

este necesar să împiedicaţi mediul Access să oprească execuţia codului şi să afişezemesajul standard de eroare - trebuie să trataţi personal erorile, pe măsură ce apar.

Erori în Visual BasicProbabil aţi întâlnit secvenţe de cod pentru tratarea erorilor, în special dacă aţi

folosit la crearea formularelor programul asistent (wizard) Command Button. Dacă nuincludeţi o rutină proprie de tratare a erorilor, Access foloseşte o rutină prestabilită,care afişează un mesaj de eroare şi opreşte execuţia codului. Prin introducereainstrucţiunii On Error, comunicaţi mediului Access că veţi folosi o rutină proprie

 pentru afişarea erorilor. De exemplu, citiţi următoarea secvenţă de cod:

Această este schema recomandată pentru majoritatea rutinelor.

Instrucţiunea On Error specifică o etichetă la care trece automat execuţiacodului în cazul apariţiei unei erori. Etichetele sunt simple marcaje existente în cod şirespectă aceleaşi convenţii de nume ca şi variabilele, exceptând faptul că la sfârşit ausemnul două puncte (:). Prin convenţie, pentru numele etichetelor de erori folosiţinumele procedurii, la care adăugaţi _Err.

Prin comanda Resume, comunicaţi mediului Access că tratarea erorilor s-aterminat şi că ar trebui să continue execuţia din rutina principală. După procesareacodului pentru rutina de eroare, efectuaţi una dintre acţiunile următoare:

Încercaţi din nou instrucţiunea care a produs eroarea, folosindcomanda Resume. Aceasta comunică mediului Access că trebuie să revinăla instrucţiunea care a cauzat eroarea şi să o ruleze din nou. Folosiţiaceastă metodă numai dacă sunteţi sigur că eroarea nu se va produce înmod repetat. Comanda Resume este utilizată de obicei împreună cu o

Pag. 237

Public Sub ErrorHandling()

On Error GoTo ErrorHandling_Err 'O parte din cod se gaseste aici

ErrorHandling_Exit:Exit Sub

ErrorHandling_Err:'Codul de tratare a erorii se gaseste aici

End Sub 

Page 233: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 233/295

casetă de mesaj, în care utilizatorul este întrebat dacă doreşte să repete oanumită acţiune. Dacă eroarea poate fi tratată fără oprirea execuţiei, continuaţi cu liniaurmătoare procedurii principale. În acest caz, folosiţi comanda ResumeNext; procesarea rutinei continuă de la linia care urmează celei în care a

apărut eroarea. Această metodă ar trebuie folosită numai dacă eroarea nuva acuza probleme ulterioare în aplicaţie. Dacă procesarea rutinei nu mai poate continua, ieşiţi din procedură. Înacest caz, ar trebui să folosiţi comanda Resume ErrorHandling_Exit pentru a comunica rutinei să treacă la eticheta de ieşire. Dacă eroarea a fost atât de gravă încât a oprit execuţia întregului program, ieşiţi din program folosind comanda End.

Acum puteţi să începeţi scrierea propriei dumneavoastră proceduri de tratare a

erorilor. Vom folosi un exemplu simplu, cu o casetă de intrare în care se cereutilizatorului să introducă un număr şi apoi se împarte valoarea 10 la numărulrespectiv.

Încercaţi singur - Crearea unei proceduri de tratare a erorilor

1. Creaţi următoarea subrutină ErrorHandling:

Pag. 238

Public Sub ErrorHandling()Dim dblResult As Double

dblResult = 10 / InputBox("Introduceti un numar:")MsgBox "rezultatul este " & str$(dblResult)

End Sub 

Page 234: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 234/295

Fig.11.8

2. Rulaţi subrutina în fereastra de depanare. Procedura afişează pe ecran unmesaj în care se cere introducerea unui număr. Apoi atribuie variabileidblResult valoarea obţinută împărţind 10 la numărul introdus de utilizator şi afişează rezultatul. Introduceţi câteva numere pentru a testa subrutina.

Fig.11.9

Pag. 239

Page 235: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 235/295

Fig.11.10

3. Introduceţi cifra 0 - veţi vedea mesajul de eroare Divide By Zero(Împărţire la zero). Apoi lăsaţi caseta de intrare necompletată - va fi afişatmesajul de eroare Type mismatch.

Fig.11.11

Eroarea Type mismatch apare din cauză că este returnat un şir - funcţiaInputBox returnează un şir vid (empty) dacă nu introduceţi nici o valoare încasetă. Când Access încearcă să împartă 10 la acest şir, realizează că tipurilede variabile sunt incompatibile. Avem nevoie de o rutină de tratare a erorii.

4. Modificaţi codul ca mai jos şi mai încerca o dată:

Pag. 240

Public Sub ErrorHandling()Dim dblResult As DoubleOn Error GoTo ErrorHandling_Err dblResult = 10 / InputBox("Introduceti un numar:")MsgBox "rezultatul este " & str$(dblResult)ErrorHandling_Exit:

Exit Sub

  ErrorHandling_Err:MsgBox Err.Descrition & " - " & Err.Number Resume ErrorHandling_Exit

End Sub 

Page 236: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 236/295

Într-un exerciţiu anterior, am filtrat erorile cu ajutorul unor variabile booleene, însă nu am făcut deosebire între tipurile de erori, numindu-le pe toate erorisemantice. Această rutină de tratare a erorilor afişează mesajul de eroare şi numărul

erorii şi apoi face saltul la instrucţiunea de ieşire. În anumite circumstanţe, este ometodă preferabilă celei care afişează mesajul de eroare prestabilit, pentru că vă permite editarea textului mesajului. Acum, dorim să detectăm două erori distincte şi sădeclanşăm în fiecare caz o acţiune specifică.

Obiectul Err a fost introdus în Access 95. Dacă doriţi, puteţi continua să folosiţi Error$ şi Err pentru descrierea şi numărul erorii, însă noul obiect conţine mai multe informaţii şi este mult mai clar. Ar fi bine să folosiţiobiectul Err în toate programele pe care le scrieţi de acum înainte.

5. Modificaţi din nou codul de tratare a erorilor, astfel încât să fie ceva mai"inteligent" decât înainte:

6. Încercaţi să introduceţi 0 sau o literă şi vedeţi ce se întâmplă. Dacă doriţisă ieşiţi din această procedură, introduceţi un număr diferit de 0.

Cum funcţionează?

Pag. 241

ErrorHandling_Err:Select Case Err.Number Case 13 ' Type mismatch - empty entry (Incompatibilitate - sir vid)

Resume Case 11 ' Divide by zero (Impartire la zero)

dblResult = 0 

Resume Next Case Else

MsgBox Err.Description & " - " & Err.Number Resume ErrorHandling_Exit 

End Select 

Page 237: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 237/295

În loc să lăsaţi mediul Access să afişeze meniul standard de eroare, puteţi să specificaţi mult mai clar acţiunea care va avea loc.

Select Case Err.Number

Prima instrucţiune verifică dacă Err.Number conţine numărul de eroare.Case 13 ' Type mismatch - empty entry (Incompatibilitate - sir vid)

Resume  

Eroarea indică o nepotrivire a tipurilor de variabile: fie caseta de intrare arămas necompletată, fie a fost introdus un şir de caractere ce nu reprezintă un număr.În acest caz, caseta este afişată din nou pe ecran - instrucţiunea Resume cere revenireala linia care a cauzat eroarea. Dacă încercaţi să apăsaţi butonul Escape, vă veţi da

seama că nu are nici un efect. Acelaşi lucru este valabil şi pentru butonul Cancel dincaseta de intrare. Funcţia InputBox returnează un şir vid dacă nu se introduce nici ovaloare, aşa încât este generată aceeaşi eroare. Din acest motiv, nu se recomandă săfolosiţi rezultatele unei funcţii cum este InputBox direct în expresii numerice, fără overificare preliminară a conţinutului acestora.

Case 11 ' Divide by zero (Impartire la zero)dblResult = 0

 Resume Next 

Eroarea 11 apare dacă în caseta de intrare a fost introdusă valoarea 0, situaţieîn care putem ignora pur şi simplu eroarea. Atribuiţi rezultatului valoarea 0 şiintroduceţi instrucţiunea Resume Next, care cere continuarea execuţiei programuluide la linia aflată imediat după cea care a generat eroarea. Aceasta este linia ce conţineMsgBox.

Case Else MsgBox Err.Description & " - " & Err.Number 

 Resume ErrorHandling_Exit Chiar dacă nu ne aşteptăm să apară alte tipuri de erori, este bine să avem în

vedere şi tratarea acestora. În astfel de cazuri, pe ecran este afişat un mesaj şi se iesedin procedură.

Adevărata problemă din acest exemplu este faptul că va fi returnată valoarea 0 pentru o eroare de împărţire la 0, fără a fi afişat un mesaj de eroare. Amintiţi-vă că ammenţionat această problemă ceva mai devreme în cadrul capitolului de faţă. Ar trebuisă modificaţi secvenţa de cod astfel încât toate erorile să fie returnate, sau măcar semnalate prin afişarea unor mesaje pe ecran,

Pag. 242

Page 238: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 238/295

deoarece forma actuală este evident greşită şi poate indica o eroare anterioară de program.

Cu toate că este un exemplu foarte simplu, veţi vedea cât de uşor poate fi  personalizată rutina de tratare a erorilor, conferindu-i un grad mai mare deflexibilitate.

Utilizarea instrucţiunilor Exit Function şi Exit Sub în rutinele de tratare aerorilor

În rutinele de tratare a erorilor, puteţi include alte două instrucţiuni Access -Exit Function şi Exit Sub. Acestea vă permit să renunţaţi la folosirea etichetelor,astfel că rutinele devin mai uşor de citit şi de depanat. De exemplu, am putea rescriefuncţia ErrorHandling astfel:

 Public Sub ErrorHandling() Dim dblResult As Double

On Error GoTo ErrorHandling_Err 

dblResult = 10 / InputBox("Introduceti un numar:") MsgBox "rezultatul este " & str$(dblResult)

 ErrorHandling_Err: Select Case Err.Number 

Case 11 ' Divide by zero (Impartire la zero)dblResult = 0Resume Next

Case ElseMsgBox Err.Description & " - " & Err.Number 

End Select 

 End Sub

Această metodă permite şi folosirea butonului Cancel , care, în versiuneaanterioară a rutinei, nu a funcţionat. Când este detectat numărul de eroare 13, folosiminstrucţiunea Exit Sub pentru a determina ieşirea din subrutină. Deşi pare o procedurăsimplă, deoarece sunt mai puţine etichete în cod, vă recomand prima metodă dintr-unmotiv foarte important - există un singur punct de ieşire din

Pag. 243

Exit Sub

Case 13 ' Type mismatch - empty entryExit Sub

Exit Sub

Page 239: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 239/295

  procedură. Aceasta înseamnă că puteţi introduce instrucţiuni de cod înainte de procedura de ieşire, ştiind sigur că acestea vor fi rulate, ceea ce nu se întâmplă încazul inserării instrucţiunilor Exit Sub în diverse porţiuni ale codului.

Erori în formulare şi rapoarteÎn Access, există erori care sunt asociate cu formularele - formularele au uneveniment Error asociat. În mod normal, acesta este gol (nu are cod scris) şi, în cazulapariţiei erorii este executată rutina prestabilită; însă, la fel ca în procedurile normale, puteţi adăuga propria dumneavoastră secvenţă de cod. Evenimentul de eroare preiadouă argumente:

Fig.11.12

Primul argument, DataErr, reprezintă numărul erorii şi este folosit în acelaşi fel caErr în exemplul anterior.

Al doilea argument, Response, indică dacă doriţi sau nu ca mesajul de eroare  prestabilit să fie afişat pe ecran. Dacă atribuiţi acestui argument valoareaacDataErrContinue, Access va ignora eroarea şi va continua execuţia codului - ceeace vă permite să afişaţi pe ecran propriul dumneavoastră mesaj de eroare. Dacăatribuiţi argumentului valoarea implicită, acDataErrDisplay, pe ecran este afişatmesajul prestabilit pentru eroarea respectivă. Haideţi să vedem cum a fost

implementat acest procedeu în baza de date şi să schimbăm mesajul afişat pe ecran laapariţia unei anumite erori.

Erori DAOAşa cum am arătat în capitolele anterioare, colecţia Errors (care a fost

introdusă în versiunea Access95) conţine toate erorile referitoare la obiectele de accesla date. Dacă bănuiţi că eroarea provine de la un obiect de acces la date, verificaţimesajele de eroare din toată colecţia, dar şi obiectul eroare.

Pag. 244

Page 240: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 240/295

Erori definite de utilizatorS-au spus multe lucruri despre erorile din Access, însă puteţi defini propriile

dumneavoastră erori. Este o metodă foarte utilă, pentru că permite crearea unei

erori specifice într-o procedură atunci când se întâmplă un anumit lucru, apoi o

tratează la fel ca pe erorile interne. De asemenea, permite declanşarea rutinelor pentruerori prestabilite, chiar fără apariţia efectivă a unei erori.Prin utilizarea metodei Raise a obiectului Err, sunt generate erori definite de

utilizator. Obiectul va raporta eroarea în modul obişnuit. Diferenţa este cădumneavoastră trebuie furnizaţi numărul de eroare. Acesta poate fi un număr deeroare standard din VBA, cum ar fi 13 pentru Type Mismatch (Incompatibilitateatipurilor de date), sau un număr care nu face parte din gama celor utilizate în VBA. Numărul maxim este 65535, însă VBA nu foloseşte valori de peste 32000, ceea ceînseamnă că aveţi de unde alege.

Încercaţi singur - Definirea unor erori proprii

1. Deschideţi procedura ErrorHandling pe care aţi analizat-o ceva maidevreme şi modificaţi codul astfel:

 Public Sub ErrorHandling()

 Dim dblResult As Double

 MsgBox "rezultatul este " & str$(dblResult)

 ErrorHandling_Exit:Exit Sub

 ErrorHandling_Err:Select Case Err.Number 

Case 13 ' Type mismatch - empty entryResume

Case 11 ' Divide by zero

Pag. 245

Dim VarNumber  As Variant

On Error GoTo ErrorHandling_Err 

VarNumber = InputBox("Introduceţi un număr:")If Not IsNumeric(VarNumber) Then

Err.Raise 32000 End If dblResult = 10 / VarNumber 

Page 241: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 241/295

dblResult = 0Resume Next

Case Else

MsgBox Err.Description & " - " & Err.Number 

Resume ErrorHandling_ExitEnd Select 

 End Sub

Acum, dacă valoarea de intrare nu este numerică, rutina de tratare a erorii esteapelată cu numărul de eroare 32000. Pentru a preveni apariţia unor conflicte cu mediulAccess, folosiţi întotdeauna în cod numere mai mari de 32000.

2. Modificaţi rutina de tratare a erorilor, adăugând o secţiune suplimentară:

3. Lansaţi în execuţie procedura şi introduceţi în caseta de intrare o literă. Noua rutină de tratare a erorilor procesează eroarea cu numărul 32000 lafel ca pe celelalte. Ca urmare, funcţia va afişa pe ecran propriul

dumneavoastră mesaj.Dacă nu trataţi explicit erorile definite de utilizator şi folosiţi o simplă casetă

de mesaj pentru a afişa textul standard, veţi obţine mesajul de eroare Application-defined or object-defined error.

De exemplu, în procedura anterioară ar fi afişat mesajul Application-definedor object-defined error - 32000.

Stiva de eroriDeoarece Access este un mediu dirijat de evenimente, procesează periodic

mici secvenţe de cod care corespund evenimentelor. Pe măsură ce este introdusăfiecare procedură, rutina de tratare a erorilor este reiniţializată şi orice eroare estetratată independent. Access nu trebuie să păstreze o stivă de erori, răspunzându-le pemăsură ce apar. Deşi acest mod de lucru este destul de simplu, trebuie să fiţi atentunde anume caută Access codul de tratare a erorilor.

Pag. 246

Case 32000 MsgBox "Trebuie sa fie un numar"Resume ErrorHandling_Exit

MsgBox Err.Description & " - " & Err.Number 

Page 242: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 242/295

La apariţia unei erori, Access parcurge în sens invers procedura activă curentăîn căutarea unei rutine de tratare a erorilor şi o execută pe prima pe care o găseşte.Dacă nu găseşte nici una, apelează rutina implicită de tratare a erorilor.

De exemplu, să presupunem că avem trei proceduri: A, B şi C. A apelează B şiB, la rândul său apelează C. Dacă C generează o eroare, Access va reveni la

B şi apoi la A în căutarea unei rutine de tratare a erorii. Dacă nu găseşte nimic în Bsau A, apelează rutina prestabilită.

Reţineţi că acest mod de lucru nu afectează în nici un fel fluxul de control al programului în care procedura C este încă activă. Săgeţile de revenire în procedurileapelante indică unde caută Access o rutină de tratare a erorii.

Să presupunem acum că v-aţi hotărât să creaţi propria dumneavoastră rutină detratare a erorii. Veţi plasa câte o rutină în A, B şi C sau vă veţi baza pe facilitatea de backtracking (revenire) şi veţi plasa rutina doar în procedura A? Dacă aveţi de-a facecu erori similare, este foarte normal să creaţi o singură rutină şi, datorită capacităţii de backtracking, să o plasaţi la cel mai înalt nivel.

De exemplu, puteţi avea următorul cod de tratare a erorilor doar în procedura A:

Pag. 247

 A_Err:Select Case Err.Number 

Case w ' Este periculos, deci se ieseResume A_Exit

Case x ' Trecere la linia urmatoare de cod

Resume NextCase y ' O noua incercare

ResumeCase z ' O eroare prestabilita, care va fi tratata de Access

Err.Raise q

End Select 

Page 243: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 243/295

Deşi codul este foarte simplu, există o problemă serioasă, care poate schimbafluxul programului. Nici Resume şi nici Resume Next nu vor continua execuţia cu procedura C, aşa cum aţi putea crede, cu linia curentă din procedura care trateazăeroarea.

Deci Resume va relua execuţia de la linia care a apelat procedura B - aceastaeste linia curentă în procedura A.

În mod similar, Resume Next va continua execuţia cu linia care urmează dupăapelul procedurii B. Observaţi că nici una dintre metode nu va returna execuţia în procedura C. Haideţi să examinăm puţin diagrama următoare pentru a vedea ce seîntâmplă:

Diagrama ilustrează riscul utilizării unei singure rutine pentru tratarea erorilor.Totuşi, există şi situaţii în care această metodă este utilă - trebuie să cunoaşteţi acesteaspecte şi să faceţi o planificare (proiectare) corespunzătoare. De exemplu, puteţi să

Pag. 248

Page 244: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 244/295

 plasaţi o rutină de plasare a erorilor în A şi alta în C. Rutina din C tratează erorilegenerate în procedura respectiv (C), permiţând continuarea execuţiei programului încondiţii normale, în timp ce rutina din A poate fi folosită pentru erorile din A şi B. Deasemenea, puteţi folosi instrucţiunea Err.Raise în procedura C pentru a forţa Access sămute rutina de tratare a erorilor pe nivelul imediat superior. Iată un exemplu în acest

sens:

Această procedură are o rutină care verifică numărul erorii. Dacă este vorba deeroarea 13 (Type Mismatch), mesajul de eroare este afişat aici, dar orice altă eroareeste transmisă înapoi pe lanţul de apeluri. Pentru aceasta se foloseşte metoda Raiseobiectului Err, care are ca efect regenerarea erorii. Cele trei argumente sunt numărulde eroare, sursa (în acest caz, procedura "c") şi descrierea. Codul propriu-zis esteformat doar din două linii, ambele fiind generatoare de erori. Prima atribuie uneivariabile întregi o valoare foarte mare, care va acuza o depăşire (overflow) - nu esteeroarea 13, deci vom genera eroarea din nou. A doua linie este eroarea 13, care poatefi tratată aici. Oricum, în acest exemplu aţi putea comenta faptul că se atribuie ovaloare mare variabilei înainte de generarea erorii, deoarece cele două evenimente nu pot avea loc simultan. Haideţi să vedem ce conţinut ar avea o posibilă procedurăapelantă:

Pag. 249

Sub c()

On Error GoTo c_Err 

Dim intOne As Integer 

intOne = 123456789

intOne = "wrong"c_Exit:

Exit Subc_Err: 

Select Case Err.Number Case 13

MsgBox "c: Error " & Err.Number & ": " & Err.DescriptionCase Else

Err.Raise Err.Number, "c", Err.DescriptionEnd Select

Resume c_ExitEnd Sub

Sub b()Dim intI As Integer Debug.Print "In b"

Call c

Debug.Print "In b: setting intI to 123456789"

intI = 123456789End Sub

Page 245: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 245/295

Această procedură nu conţine decât apelul procedurii c şi generează propria saeroare - o depăşire. Deoarece nu are o rutină proprie de tratare a eroii, Access va căutaînapoi în lanţul de apeluri pentru a găsi o rutină corespunzătoare; în exemplul nostru,această rutină se găseşte în procedura a:

Această procedură conţine o rutină de tratare a erorilor, care afişează sursaerorii, precum şi numărul şi descrierea acesteia. Să facem o recapitulare a procedurilor:

a apelează b, care apelează c. c are propria sa rutină de tratare a erorilor, dar se ocupă doar deeroarea 13 - toate celelalte sunt retrimise procedurii b. b nu are o rutină proprie, deci transmite eroarea înapoi la a. Rutina de tratare a erorilor din a afişează pe ecran mesajul de eroare.

Acest exemplu demonstrează că puteţi trata anumite erori local, însă trebuie săaveţi şi o procedură generală, care să se ocupe de celelalte erori posibile. ProprietateaSource a obiectului Err vă permite să identificaţi locul unde a fost generată eroarea.

Pag. 250

Sub a()

On Error GoTo a_Err 

Debug.Print "In a"

Call b

Debug.Print "In a: 2 / 0 = " & 2 / 0

a_Exit:Exit Sub

a_Err:

MsgBox "a (" & Err.Source & "): Error " & Err.Number & ": " &_ Err.Description

Resume a_Exit

End Sub

Page 246: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 246/295

11.7 Depanarea codului de depanareUneori, introduceţi în cod rutine de tratare a erorilor, dar chiar acestea sunt

generatoare de erori. În astfel de cazuri, deschideţi meniul Tools, alegeţi Options şi

apoi selectaţi panoul Advanced. În grupul Coding Options găsiţi opţiunea Break onAll Errors (Opreşte execuţia la orice eroare).Dacă activaţi această opţiune, Access va ignora rutinele de tratare a erorilor 

scrise de dumneavoastră şi le va folosi întotdeauna pe cele prestabilite. Astfel, puteţisă scrieţi rutinele de tratare a erorilor chiar la crearea aplicaţiei, însă aveţi posibilitateade a le dezactiva în etapa de depanare.

Controlul de versiuneProbabil vă veţi întreba ce caută o secţiune dedicată controlului de versiune

într-o carte despre VBA, mai ales în secţiunea referitoare la depanare şi testare. Uniidintre dumneavoastră se vor întreba ce este controlul de versiune. Pentru cei care nuştiu, controlul de versiune reprezintă capacitatea de a marca aplicaţiile modificate caversiuni distincte. Astfel, aveţi posibilitatea de a păstra un istoric al modificărilor,fiecare cu un număr de versiune, de a analiza diferenţele dintre versiunile succesive, şichiar de a anula modificările.

Vă veţi întreba la ce vă folosesc toate acestea. Ei bine, acest control este foarteimportant. Ca dezvoltator de aplicaţii, trebuie să efectuaţi deseori modificări în cod:corectarea unor erori de programare, îmbunătăţiri, şi chiar încercări de genul "să

vedem dacă merge aşa". În trecut, nu exista nici o posibilitate de identificare amodificărilor, în afară de comentarii, care nu oferă, totuşi, siguranţa necesară. Dupăapariţia controlului de versiune, lucrurile au devenit mult mai simple. Poate că amexagerat puţin, însă am vrut să vă daţi seama ce reprezintă controlul de versiune şi dece vorbim despre el în prezentul capitol.

Dacă nu v-am convins încă, urmăriţi raţionamentul următor. Să ne imaginăm osituaţie de lucru obişnuit. Aţi realizat o aplicaţie de baze de date care a fost bine primită de utilizatori. Totuşi, în cadrul procesului de modernizare, trebuie să mai parcurgeţi trei sau patru faze de lucru şi să corectaţi erorile de programare. Cum procedaţi? Poate ar fi bine să faceţi câte o copie a bazei de date pentru fiecare fază în parte. Sau poate că trebuie să scrieţi codul cu funcţionalitatea corect pentru fiecarefază. Ce faceţi cu erorile de programate? Cum separaţi o corectură de alta? Şi ce se vaîntâmpla dacă implementaţi o corectură, dar apoi sunteţi nevoit să o ştergeţi? Vă puteţi aminti cu exactitate ce aţi modificat? Sunt locuri unde aceste evenimente au loczilnic (nu numai în programare) şi se aplică nu doar pentru departamentele IT, ci şi pentru programatori individuali.

Una dintre cele mai solicitate facilităţi pentru noua versiune de Access a fostVersion Control (controlul de versiune). Mulţi utilizatori au aşteptat-o încă de laAccess 95, însă nu au beneficiat de ea. Acum, în sfârşit, această facilitate estedisponibilă.

Pag. 251

Page 247: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 247/295

Haideţi să aruncăm o privire asupra noilor caracteristici de control de versiunedin Access97 şi să vedem cum vă pot ajuta acestea în activitatea de programare.

Controlul de versiune în Access 97Voi începe prin a spune că acest control de versiune nu este o caracteristicăautomată în Access, şi nici o facilitate de care beneficiaţi gratuit. Pentru a putea folosicontrolul de versiune, aveţi nevoie de produsele software Office Developer EditionTools şi Microsoft Visual SourceSafe.

Visual SouceSafe este produsul care realizează efectiv controlul deversiune. A fost lansat pe piaţă de câţiva ani şi este folosit în special de programatorii în Visual Basic. Office Developer Edition Tools vă oferă, printre multe alte

instrumente, programul de completare care conectează Access la VisualSourceSafe.Ambele produse sunt componente suplimentare, pe care trebuie să le

cumpăraţi, însă puteţi să le consideraţi o investiţie. Vă vor ajuta să economisiţi multtimp. Garantat.

Visual SourceSafeVisual SourceSafe efectuează controlul de versiune pentru orice tip de fişier:

fişiere Visual Basic, documente, fişiere binare etc. este un produs orientat pe proiect şi

 permite organizarea şi partajarea codului, ca şi controlul asupra editării. În figuraurmătoare este prezentat ecranul principal:Prima observaţie este asemănarea evidentă cu Windows Explorer. În panoul

din stânga puteţi vedea o listă de proiecte. $/ reprezintă directorul rădăcină, la fel caC:\ pentru unitatea de disc. Sub directorul rădăcină se află o listă de proiecte care, larândul lor, conţin subproiecte. Observaţi că aici apare cartea de faţă, incluzând baza dedate, documentele Word şi imaginile grafice. Panoul din dreapta afişează lista defişiere asociate unui proiect, numele de utilizator şi data ultimei modificări.

Deci ce face Visual SourceSafe? Gândiţi-vă la acest program ca la un

  bibliotecar. Puteţi să căutaţi cărţile pe care le are, să verificaţi dacă numeledumneavoastră este scris pe ele, iar în cazul în care aţi efectuat modificări, le puteţianula. Observaţi în figura de mai sus că am găsit două fişiere modificate. Fiecaremodificare pe care o efectuaţi asupra unui fişier este adăugată ca o versiune distinctă.

De exemplu, în figura anterioară există trei versiuni ale fişierului ReadMe.txt.Puteţi vedea cine le-a căutat şi când. Una dintre cele mai importante facilităţi ale programului Visual SourceSafe este că vă permite să vizualizaţi modificările care auapărut de la o versiune la alta.

Visual SourceSafe evidenţiază liniile şterse, liniile modificate şi liniile nou

introduse, astfel încât dumneavoastră puteţi vedea ce s-a modificat. Acest lucru estefoarte util în situaţiile în care nu vă amintiţi exact ce aţi modificat, sau dacă lucraţi înechipă şi doriţi să vedeţi ce modificări au efectuat colegii dumneavoastră.

Pag. 252

Page 248: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 248/295

Programul de completare Access SourceSafeComponenta Visual SourceSafe pentru Access este furnizată ca un program de

completare, care este adăugat la meniul Tools.

Când adăugaţi o bază de date în Visual SourceSafe, fiecare element al acesteiaeste blocat, nepermiţând nici o modificare.

În imaginea alăturată, puteţi vedea cum s-a modificat pictograma, indicând

faptul că elementul este blocat. Pentru a anula blocarea unui fişier, apăsaţi butonuldrept al mouse-ului şi selectaţi opţiunea Check Out din meniu.În acest fel, veţi introduce în baza de date o copie editabilă a obiectului. Din

nou, pictograma asociată obiectului se modifică, astfel încât să puteţi vedea starea încare se găseşte acesta.

Acum puteţi edita obiectul şi, după ce aţi terminat, marcaţi-l din nou, ştiindsigur că tot ce aţi modificat se păstrează separat de orice altă modificare. Deasemenea, puteţi folosi Visual SourceSafe pentru a introduce observaţii referitoare laversiune şi o listă de modificări.

Cu aceasta, am încheiat scruta prezentare a produsului Visual SourceSafe şi amodului în care poate fi folosit în Access; deşi nu este o componentă standard, merităsă o achiziţionaţi. Odată, am pierdut trei zile căutând o greşeală de programare într-un  proiect de dimensiuni mari. Dacă aş fi avut la dispoziţie controlul de versiune,  probabil că aş fi descoperit eroarea în câteva ore. Posibilitatea de a controlamodificările reprezintă o latură importantă a dezvoltării de aplicaţii, aşa încât lăsaţi puţin cartea şi mergeţi repede să cumpăraţi produsul prezentat.

11.9 RezumatChiar dacă aţi citi printre rânduri, v-aţi dat seama că acest capitol se referă la

 planificare. Detectarea şi rezolvarea problemelor software consumă multe resurse, dar  printr-un mic efort de planificare, puteţi economisi mult timp.

La fel de importantă ca planificarea aplicaţiei este şi anticiparea cerinţelor şinevoilor utilizatorului. Încercaţi să vă puneţi în locul acestuia, să vă imaginaţi ce vaface, astfel încât să construiţi un program cât mai simplu de utilizat. Nu ar trebui să puneţi niciodată un utilizator în situaţia de a primi un mesaj de eroare care îi creeazăimpresia că a greşit ceva, deoarece poate deveni reticent faţă de software, ajungândchiar să refuze utilizarea programului. Alan Cooper, inventatorul limbajului VisualBasic, spunea: "Petrecem atâta timp lucrând cu calculatoarele, încât nu ne dăm

Pag. 253

Page 249: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 249/295

seama că, deşi este plăcut să umilim un calculator, nu ne putem permite săumilim un utilizator".

În acest capitol au fost prezentate următoarele subiecte: Modul de proiectare a aplicaţiei în scopul reducerii la minimum a

numărului de erori Tehnici orientate pe obiect care pot fi folosite pentru prevenireaerorilor  Testele pe care ar trebui să le efectuaţi pentru orice aplicaţie nouă Tipurile de erori şi modul de corectare acestora

Depanarea codului prin execuţie pas cu pas, folosind punctele deîntrerupere şi elementele de urmărire Scrierea propriilor rutine de tratare a erorilor 

Controlul de versiune

Prin prevenirea şi detectarea erorilor, veţi îmbunătăţi cu siguranţă performanţele oricărui program pe care îl scrieţi. Puteţi atinge nivelul de aplicaţie fărăerori. Acest proces este cunoscut sub numele de optimizare şi îl vom prezenta încapitolul următor.

Pag. 254

Page 250: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 250/295

CAP: 12.OPTIMIZAREA BAZEI DE DATE

Chambers 20th Century English Dictionary defineşte optimizarea ca fiind:

Pregătirea sau revizuirea unui sistem sau program de calculator învederea obţinerii eficienţei maxime.

Vom analiza diferite metode prin care un programator se poate asigura căaplicaţia de baze de date funcţionează cu eficienţă maximă.

Vor fi prezente următoarele subiecte specifice: Eficienţa unei secvenţe de cod Cum se măsoară viteza unui program? Câteva sugestii de scriere a codului pentru a crea programe mai rapide

Ce trebuie să avem în vedere când scriem aplicaţii de reţea?

12.1 Eficienţa

Instrumentul Performance Analyzer (care poate fi activat din bara demeniuri, executând clic pe Tools/Analyze şi selectând opţiunea Performance) estefoarte util în cazul aplicaţiilor de baze de date cu performanţe scăzute. Totuşi,Performance Analyzer nu vă ajută să rezolvaţi toate problemele, una dintre acesteafiind optimizarea codului VBA.

Dacă scopul nostru este să obţinem o eficienţă maximă, se pune întrebarea:"Prin ce se caracterizează eficienţa?". Este o întrebare mult mi complexă decât pare la prima vedere. Iată care sunt cele mai importante criterii de evaluare a eficienţei uneiaplicaţii de baze de date: Viteza reală de execuţie Viteza aparentă Amprenta de memorie (adică dimensiunea) Traficul de reţeaAproape întotdeauna este posibil să optimizaţi o aplicaţie potrivit unuia dintre aceste

criterii de evaluare a performanţelor, însă cum procedaţi pentru ca aplicaţia să lerespecte pe toate patru? Răspunsul este simplu: nu puteţi face acest lucru şi nici nu ar trebui să încercaţi.

Pag. 255

Page 251: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 251/295

Una dintre sarcinile pe care le aveţi de rezolvat când începeţi un proiect dedezvoltare este să stabiliţi o listă de priorităţi. Care dintre cei patru factori menţionaţianterior sunt cei mai importanţi pentru implementarea cu succes a aplicaţiei? Caresunt de dorit şi care sunt lipsiţi de relevanţă?La criteriile de performanţă prezentate anterior puteţi adăuga încă patru:

Protabilitatea Robusteţea Mentenabilitatea Refolosirea

  Nici unul dintre aceşti factori nu conduc neapărat la creşterea eficienţeiaplicaţiei - optimizarea unei secvenţe de cod potrivit criteriilor de portabilitate saurobusteţe va determina micşorarea vitezei de execuţie a programului sau un consummai mare de memorie.

De fapt, aceşti opt factori acţionează în direcţii diferite. Să considerămurmătoarele secvenţe de cod:

Sau:

Ambele exemple conduc la acelaşi rezultat. Totuşi, primul dintre ele are untimp de execuţie de patru ori mai mare decât al doilea. Dacă optimizaţi codul în privinţa vitezei, ar trebui să alegeţi o a doua variantă.

Pe de altă parte, s-ar putea ca mulţi programatori, în special cei fărăexperienţă, să opteze pentru primul exemplu. Dacă optimizaţi mentenabilitatea, alegeţiaceastă variantă (în special dacă, pe un calculator obişnuit, ambele secvenţe de codsunt executate într-o fracţiune de secundă).

În capitolul de faţă, nu veţi afla metoda optimă de scriere a unui program. Aceasta va depinde de priorităţile determinate pentru fiecare aplicaţie în parte. În schimb, vom prezenta impactul fiecăruia din cei patru factori de optimizaremenţionaţi anterior.

12.2 Reducerea supraîncărcării memoriei

Pag. 256

If (bool1 = True And bool2 = True) Or (bool1 = False And_ bool2 = False)Then

boolResult = FalseElse

boolResult = True

End If 

boolResult = (bool1 Xor bool2)

Page 252: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 252/295

Un calculator desktop modern care rulează Access 97 are, de obicei, între 16 şi64 M de memorie (RAM). În acest spaţiu de memorie este executat codul aplicaţieidumneavoastră. Cu cât calculatorul are mai multă memorie, cu atât scade frecvenţa decitire şi de scriere pe disc (procese relativ lente) şi, ca urmare, programul are o vitezămai mare de execuţie.

Ca regulă generală, mai multă memorie înseamnă performanţe mai bune. Întrecut, calculatoarele erau limitate la 32 sau 64 kiloocteţi de memorie. Pentru a face ocomparaţie, aceasta reprezintă de aproximativ 2000 de ori mai puţin decât memoriacalculatorului pe care îl folosesc eu pentru a scrie acest capitol. În acele timpuri, chiar dacă nu aţi fi avut un sistem de operare sau un program capabil să

folosească 96 M de RAM - ceea ce depăşeşte cu mult capacitatea calculatoarelor mainframe - costul memoriei ar fi reprezentat o avere.

De aceea, nu este surprinzător faptul că, având la dispoziţie o cantitate dememorie limitată, programatorii consumau foarte mult timp pentru a face ca aplicaţiilesă încapă (şi să lucreze) pe minusculele resurse ale calculatoarelor lor. Sintagma lamodă era "programare disciplinată"; limbajul folosit de obicei era limbajul deasamblare sau codul maşină (aproape ilizibil pentru un nespecialist), iar rezultateleobţinute constituiau o dovadă de ingeniozitate şi de perseverenţă.

Astăzi, aceste probleme au dispărut. Dacă un program este prea lent, nu aveţidecât să adăugaţi 16 M de RAM pe calculator! Preţurile sunt modice. Oricum, ar costamult mai mult să rescrieţi codul programului astfel încât acest să ruleze pe un

calculator cu 12 M de memorie la fel de rapid ca vechea versiune pe un calculator cu24 M de memorie!  Nu am amintit toate acestea pentru a vă încuraja să construiţi aplicaţii

dezordonate. Memoria, deşi relativ ieftină, este preţioasă. Cu cât consumă mai puţinămemorie, programul este mai rapid şi permite execuţia simultană a altor programe.

În plus, dacă scrieţi o aplicaţie care va fi folosită de o mie de utilizatori,fiecare megaoctet suplimentar de memorie necesar aplicaţiei echivalează cu 1000 Mde memorie pe toate calculatoarele pe care va rula programul.

Cu alte cuvinte, pentru majoritatea proiectelor, scrierea unei aplicaţii cu oamprentă mică de memorie constituie în continuare o prioritate esenţială în programare.

Ca urmare, la dezvoltarea unei aplicaţii, ar trebui să ţineţi cont de următoarelerecomandări: Alegeţi corect tipurile de date. Grupaţi procedurile pe module. Eliminaţi comentariile şi secvenţele de cod inutile. Eliberaţi memoria ori de câte ori este posibil.  Nu încărcaţi în memorie module / biblioteci care nu sunt necesare.

Salvaţi baza de date ca fişier MDE.

Pag. 257

Page 253: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 253/295

12.2.1 Alegerea corectă a tipurilor de dateDiverse tipuri de date ocupă spaţii diferite de memorie. Dimensiunile spaţiului

de memorie ocupat de fiecare tip de date sunt prezentate în tabelul următor:Tipul de date Dimensiunea de

stocareDomeniul de valori

Byte (Octet) 1 octet 0 până la 255Boolean 2 octeţi True sau FalseInteger (Întregi) 2 octeţi -32.768 până la 32.767Long (Lungi) 4 octeţi -2.147.483.648 până la 2.147.483.647Single (Simple) 4 octeţi -3,403E38 până la -1,401E-45;

0; 1,401E-45 până la 3,403E38Double (Duble) 8 octeţi -1,798E308 până la -4,941E-324; 0;

4,941E-324 până la 1,798E308

Tipul de date Dimensiunea destocare Domeniul de valori

Currency (Monetare) 8 octeţi -922.337.203.685.477,5808 la922.337.203.685.477,5807

Decimal (Zecimale) 14 octeţi -7,923E28 până la 7,923E28 (variazăîn funcţie de numărul de zecimale dinnumăr)

Date (Date calendaristice) 8 octeţi Ianuarie 1, 10 până la Decembrie 31,9999

Object (Obiect) 4 octeţi O referinţă la orice tip de obiectFixed string (Şir de lungimefixă)

1 octet pentrufiecare caracter 

Până la aproximativ 65.400 caractere

Variable Length String (Şir de lungime variabilă)

10 octeţi +lungimea şirului

Până la aproximativ 2 miliarde decaractere

Variant (Numeric) 16 octeţi Acelaşi domeniu ca pentru variabilelede tip Double

Variant (Şir) 22 octeţi +lungimea şirului

Acelaşi domeniu ca pentru şirurile delungime variabilă

Aşa cum puteţi vedea, variabilele de tip Double ocupă de patru ori mai multămemorie decât variabilele de tip întreg. Însă, şi aici, optimizarea este o chestiune decompromis - variabilele duble şi simple pot păstra valori dintr-un domeniu mult maimare decât variabilele întregi.

Problema utilizării memoriei devine şi mai importantă când se lucrează cumatrice. Linia de cod:

ocupă aproximativ 800 de octeţi de memorie, în timp ce linia următoare ocupă în jur de 200 de octeţi:

Pag. 258

ReDim adb1 (9, 9) As Double

ReDim aint (9, 9) As Integer 

Page 254: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 254/295

Ca regulă generală, dacă dimensiunea amprentei de memorie este o prioritatede programare - şi de obicei este - alegeţi cele mai mici variabile care pot memoravalorile respective. Pentru a nu uita să atribuiţi explicit tipuri de variabile, ar trebui săselectaţi opţiunea Require Variable Declaration din caseta de dialog

Tools/Option…Am mai spus acest lucru - dar merită să îl repetăm - folosiţi cu prudenţă tipulde date Variant.

12.2.2 Gruparea procedurilor în moduleVBA încarcă modulele numai când este apelată o procedură din modulul

respectiv. Acest procedeu se numeşte încărcare la cerere. Rin urmare, dacă aveţi orutină care apelează trei proceduri acestea se găsesc în module separate, în memorie

vor fi încărcate toate cele trei module. Prin gruparea judicioasă a procedurilor cu funţiiînrudite în acelaşi modul, puteţi reduce la minimum numărul de module încărcatesimultan în memorie.

12.2.3 Eliminarea comentariilor şi secvenţelor de cod inutileAşa cum am arătat, este bine să comentaţi codul pe care îl scrieţi. Chiar dacă

înţelegeţi instrucţiunile în momentul în care le scrieţi, s-ar putea ca peste şase luni sănu vă mai amintiţi rolul fiecăreia. În plus, comentarea liniilor de cod ajută laînţelegerea acestuia de către alte persoane. Inserarea comentariilor în momentul

scrierii codului nu necesită prea mult timp, însă vă poate scuti de un efort mult maimare în viitor (de exemplu, în cazul depanării). Desigur, şi comentariile au preţul lor.Fiecare comentariu inserat în cod este încărcat în memorie împreună cu

 procedura la care se referă. Pentru a evita supraîncărcarea memoriei de către aplicaţiadumneavoastră, puteţi lua în considerare şi varianta copierii fişierului cu baza de dateoriginală şi eliminării tuturor comentariilor din copia destinată clienţilor. Astfel, veţiobţine o versiune de dimensiuni reduse pe care o puteţi folosi şi distribui utilizatorilor,şi o versiune comentată, cu care puteţi lucra atunci când sunteţi nevoit să modificaţiceva în aplicaţie. O soluţie şi mai bună o constituie salvarea bazei de date în formatMDE. Acest proces asigură eliminarea tuturor comentariilor din cod şi compilareaautomată a acestuia. Fişierele MDE vor fi prezentate în Capitolul 18.

Oricum, nu justificaţi lipsa comentariilor din cod prin argumentul: "Nu estesuficientă memorie" atunci când adevăratul motiv este că nu aveţi chef să leintroduceţi. Lăsaţi lenea la o parte!

Acelaşi principiu se aplică şi în cazul procedurilor nefolosite, sau aşa-numitul"cod mort". Procesul de dezvoltare a aplicaţiilor presupune o mulţime de experimenteşi, uneori, vă veţi da seama că programul este plin de proceduri inutile sau de proceduri pe care le-aţi păstrat pentru orice eventualitate. Ştergeţi şi aceste porţiuni decod din versiunea de aplicaţie care va fi distribuită clienţilor.

Pag. 259

Page 255: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 255/295

12.2.4. Eliberarea memoriei ori de câte ori este posibilPentru a elibera memoria folosită de o matrice dinamică, puteţi folosi

instrucţiunea Erase. După terminarea lucrului cu matricea, instrucţiunea Erase vaelimina datele din matrice şi va elibera memoria folosită de aceasta.

Instrucţiunea Erase nu eliberează spaţiul folosit de matricele statice (cum sunt

cele de dimensiune fixă). În schimb, le reiniţializează.Puteţi elibera şi memoria folosită de variabilele obiect de care nu mai aveţinevoie. Această operaţie se realizează prin configurarea tuturor variabilelor la ovaloarea specială, numită Nothing.

Reţineţi că memoria folosită de un obiect nu poate fi eliberată dacă mai există

o referinţă la obiectul respectiv în cod. Într-un exemplu din capitolul precedent, amfolosit această proprietate pentru a împiedica distrugerea unei instanţe a unui formular  pop-up, prin plasarea unei referinţe la acesta în colecţia declarată la nivelul modululuiunui alt formular. Referinţa respectivă a împiedicat distrugerea primului formular înainte de închiderea celui de-al doilea şi de ieşirea colecţiei din domeniu.

12.2.5 Nu încărcaţi în memorie module / biblioteci care nu sunt necesareVom vedea în capitolul următor că bazele de date biblioteci pot reprezenta o

soluţie utilă pentru stocarea şi refolosirea procedurilor de care aveţi nevoie frecvent.Aceste biblioteci pot fi folosite şi pentru a păstra aplicaţii wizard şi programe decompletare, cum ar fi aplicaţiile wizard de control şi de proiectare a formularului, caresunt distribuite împreună cu produsul Access. Fiecare dintre aceste baze de date biblioteci trebuie să fie încărcată în memorie atunci când este folosită, ceea ce măreştesubstanţial spaţiul necesar de memorie. Ca urmare, pentru a reduce cantitatea dememorie necesară instalării aplicaţiei, ar trebui să nu încărcaţi bazele de date biblioteci sau programele de completare care nu sunt absolut necesare.

12.2.6 Salvarea bazei de date ca fişier MDECătre sfârşitul cursului, vom analiza ultimele retuşuri pe care ar trebui să le

efectuaţi asupra aplicaţiei înainte de a o distribui utilizatorilor finali ai bazei de date.Unul dintre acestea constă în conversia bazei de date într-un fişier MDE. Prin operaţiade conversie, se compilează toate modulele din baza de date şi se eliminăcomentariile, instrucţiunile inutile etc. din codul sursă. Rezultă două avantaje majore:creşte siguranţa bazei de date şi scade cantitatea de memorie necesară pentru rulareaaplicaţiei.

 Reţineţi faptul că nu puteţi modifica formatul fişierelor MDE şi că este bine să păstraţi întotdeauna o versiune originală a bazei de date în format MDB.

Pag. 260

Set objExcel = Nothing

Page 256: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 256/295

12.2.7 O ultimă recomandare - cumpăraţi mai multă memorie Nu este nici o păcăleală! Pentru a rula, Access 97 are nevoie de minimum 12

M de RAM într-un sistem Windows 95 şi de 16 M de RAM pe o staţie de lucruWindows NT. Am făcut experimente pe sisteme cu 12 M, 16 M, 24 M şi 32 M şi pot

să afirm că pentru a obţine performanţe acceptabile, limita inferioară de memorie estede 16 M pentru rularea independentă sub Windows 95 şi de 24 M pentru Windows NT.

Dacă lucraţi într-o reţea sau dacă folosiţi şi alte aplicaţii Windows simultan, văveţi da seama că merită să cheltuiţi nişte bani pentru a suplimenta memoria cu 8 M deRAM (în ambele cazuri).

12.3 Creşterea vitezei de execuţie

Reducerea cantităţii de memorie ocupată de baza de date Access şi codulacesteia poate avea ca rezultat creşterea vitezei de lucru, atât a aplicaţieidumneavoastră, cât şi a altor aplicaţii Windows. Dacă viteza de execuţie este o prioritate de programare, există şi alte metode pe care puteţi să le luaţi în considerare:

Folosiţi constante

Folosiţi tipuri specifice de obiecte (asociere iniţială)

Folosiţi tranzacţii acolo unde este cazul

Folosiţi variabile, şi nu proprietăţi

Evitaţi structurile lente

Folosiţi funcţii şir 

Evitaţi instrucţiunea IIf 

Folosiţi operaţii aritmetice cu întregi ori de câte ori este posibil

Folosiţi cod in-line

Folosii judicios instrucţiunea DoEvents

Folosiţi cicluri For Each…

Folosiţi metoda Requery, nu acţiunea Requery

Folosiţi cuvântul cheie Me

Creaţi formularele pe baza unor interogări salvate

Pag. 261

Page 257: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 257/295

Creşteţi viteza operaţiilor cu baza de date

Vom analiza în detaliu aceste procedee şi vom prezenta câteva secvenţe de coddemonstrative. Exemplele de cod vă vor ajuta să evaluaţi impactul acestor tehnici delucru (asupra performanţei). Calculatoarele diferă foarte mult în privinţa dimensiunii

memoriei RAM, a vitezei procesorului, a dimensiunii memoriei cache, a vitezeidiscului etc. Aceste diferenţe se reflectă în performanţele codului VBA rulat pe fiecaremaşină în parte. Nu mă credeţi pe cuvânt; parcurgeţi singur toate aceste exemple.

Analizând rezultatele de mai jos, s-ar putea să vă întrebaţi dacă are rost să vă pierdeţi vremea pentru a implementa unele dintre aceste îmbunătăţiri. Dacă o operaţienu durează decât trei milisecunde, de ce v-aţi strădui să optimizaţi codul pentru cadurata operaţiei respective să se reducă la o milisecundă? Cine va observa acest lucru?Ei bine, trebuie să spunem că, deşi s-ar putea ca diferenţa să nu fie sesizabilă pentru osingură linie de cod, în cazul executării repetate a codului,

diferenţa devine evidentă. De exemplu, să presupunem că parcurgeţi ciclic toatecontroalele unui formular pentru verificarea unei anumite condiţii; sau să parcurgeţiciclic toate înregistrările dintr-un set de înregistrări. Obişnuiţi-vă să scrieţi întotdeaunaun cod eficient - astfel, veţi putea depăşi fără nici o problemă şi situaţiile în care acestaspect este cu adevărat important.

12.3.1 Cronometrarea execuţiei codului

Pentru a testa viteza de execuţie a unei secvenţe de cod, există mai multeopţiuni disponibile. O metodă foarte simplă este folosirea funcţiei Timer. Deexemplu, am putea utiliza secvenţa următoare de cod pentru a afla cât durează parcurgerea unei structuri ciclice For...Next... pentru 32.000 de valori.

Pag. 262

Option Compare DatabaseOption Explicit

Dim lngStart As LongDim lngEnd As Long

Sub ShowTime()MsgBox lngEnd - lngStart & " secunde"

End SubFunction UseTimer()

Dim i As Integer 

lngStart = Timer For i = 0 to 32000Next ilngEnd = Timer ShowTime

End Function

Page 258: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 258/295

Funcţia Timer returnează numărul de secunde care s-au scurs de la miezul

nopţii (de la ora 0). În exemplul de mai sus, am salvat valoarea funcţiei Timer învariabila lngStart înainte de începerea ciclului de instrucţiuni:

lngStart = Timer

După terminarea ciclului, am salvat valoarea funcţiei Timer în variabilalngEnd:

lngEnd = Timer

Prin scăderea primei valori din a doua, putem determina durata procesului de ciclare:

MsgBox lngEnd - lndStart & " secunde"

În cazul în care încercaţi singur acest exemplu, veţi observa repede o limitareevidentă. Deoarece funcţia Timer face rotunjirea la nivel de secundă, pe ecran vaapărea, probabil, următoarea casetă de mesaj la rularea codului.

Fig.12.1

Pag. 263

Page 259: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 259/295

Deci exemplul nu este relevant dacă testaţi un cod a cărui execuţie dureazămai puţin de o secundă! . Adăugaţi încă trei de zero la 32000 si să rulăm codul .

Fig.12.2

O altă soluţie este să apelaţi pentru cronometrare o funcţie API. Bibliotecawinmm.dll conţine o funcţie numită timeGetTime, care returnează numărul demilisecunde trecute de la pornirea sistemului Windows. Am văzut această funcţie la

lucru în capitolul dedicat tehnicilor de programare avansată. Funcţia returnează ovaloare cu precizia de o milisecundă (1/1000 dintr-o secundă), fiind mult mai adecvată  pentru cronometrarea execuţiei unei secvenţe de cod. În plus, este uşor deimplementat. Următorul exemplu de convenţii de denumire vă arată cum puteţideclara şi folosi funcţia pentru a determina durata de execuţie a aceluiaşi cod:

Option Compare DatabaseOption Explicit 

Dim lngStart As LongDim lngEnd As Long

Sub ShowTime()

End Sub

Dim i As Integer 

For i = 0 to 32000 Next i

 ShowTime

Pag. 264

Declare Function TimeIt Lib "winmm.dll" Alias "timeGetTime" ()_ 

As Long

MsgBox (lngEnd - lngStart) & " milisecunde"

Function UseTimeIt()

lngStart = TimeIt

lngEnd = TimeIt

Page 260: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 260/295

 End Function

Modificarea semnificativă este adăugarea declaraţiei funcţiei timeGetTime,ceea ce permite apelarea acesteia direct din Access ca funcţie TimeIt:

Declare Function TimeIt Lib "winmm.dll" Alias "timeGetTime" ()_ As Long

De data aceasta, rezultatul va fi ceva mai clar: 20 miliseconds.

12.3.2 Folosirea constante

Dacă folosiţi în cod valori care nu se modifică, ar trebui să le atribuiţi unor 

constante, nu unor variabile. Când întâlneşte o variabilă într-o linie de cod VBA,Access trebuie să acceseze locaţia de memorie care conţine variabila pentru adetermina valoarea acesteia. Pe de altă parte, valoarea unei constate este determinatăşi trecută în cod în etapa de compilare. Astfel, citirea valorilor din constante dureazămult mai puţin decât a celor din variabile:

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

VarsAndConstants

(Partea 1)

Utilizând variabile

locale

100000 67,8 0,0007

VarsAndConstants(Partea 2)

Utilizând constantelocale

100000 50,0 0,0005

12.3.3 Folosiţi tipuri specifice de obiecte (asociere iniţială)

În versiunile anterioare de Access, puteaţi întâlni frecvent linii de cod ca

acestea:

Deşi codul poate fi executat, nu este eficient. Datorită faptului că variabilaobiect frm a fost declarată As Object, Access nu ştie cu ce tip de obiect are de-a face.Aceasta înseamnă că ori de câte ori încercăm să inspectăm sau să configurăm valoareaunei proprietăţi, ori să apelăm în timpul execuţiei o metodă a acelui obiect, Access

trebuie să verifice mai întâi dacă proprietatea sau metoda respectivă corespundobiectului. Această tehnică este cunoscută sub numele de asociere  ulterioară. Ometodă mai bună de scriere a acestui cod este:

Pag. 265

Dim frm As ObjectSet frm = Forms!frmSwtchboard

Page 261: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 261/295

De data aceasta, Access ştie ce tip de obiect este frm. Ca urmare, poatedetermina încă din etapa de compilare ce proprietăţi şi metode corespund obiectului.Această tehnică este numită asociere iniţială. Deoarece Access

trebuie să facă verificarea o singură dată, înainte de rulare, diferenţa dintre vitezele deexecuţie ale secvenţelor de cod prin cele două metode poate fi semnificativă.

Un alt avantaj al tehnicii de asociere iniţială este faptul că Access poatedetermina încă din faza de compilare ce proprietăţi şi metode corespund obiectului.Orice eroare cauzată de scrierea greşită a unor nume de proprietăţi sau metode este

detectată în etapa de compilare şi nu apare ca eroare de execuţie.

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

SpecificObjects (Partea1)

Utilizând sintaxa AsObject

100000 35796,5 0,3580

SpecificObjects (Partea

2)

Utilizând variabile

obiect specifice

100000 7507,1 0,0751

12.3.4 Folosiţi variabile, nu proprietăţi

Puteţi obţine performanţe similare folosind variabile pentru a facereferire la formulare, controale şi proprietăţi. Dacă urmează să includeţi într-o procedură mai multe referinţe la un formular, raport sau control, este indicat să creaţi pentru obiectul respectiv o variabilă obiect şi apoi să faceţi referire la variabilă, şi nu

la obiectul propriu-zis.

Se poate folosi şi structura With.

Pag. 266

Dim frm As Form_frmSwitchboardSet frm = Forms!frmSwitchboard

Dim frm As Form_frmSwitchboardDim ctl As ImageSet frm = Forms!frmSwitchboardSet ctl = frm!imgLogo

sTemp1 = ctl.PicturesTemp2 = ctl.PictureAlignmentsTemp3 = ctl.SizeModeWith ctl

sTemp1 = .PicturesTemp2 = .PictureAlignmentsTemp3 = .SizeMode

End With

Page 262: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 262/295

Codul scris cu una din cele două sintaxe prezentate mai sus va fi rulat multmai repede decât codul care foloseşte sintaxa lungă.

În această situaţie, sintaxa With…End With este rulată mai încet decât primametodă, care foloseşte variabile obiect. Aceasta se datorează supraîncărcării pe care o presupune configurarea structurii With. Totuşi, dacă veţi adăuga între instrucţiunileWith şi End With din ce în ce mai multe referinţe la obiectul specificat, aceastăstructură poate deveni mai eficientă.

12.3.5 Folosiţi funcţii şir

Utilizarea funcţiilor şir este un alt domeniu în care se poate manifestaimprecizia. Majoritatea funcţiilor şir au versiuni de tip Variant. De exemplu, funcţiaFormat returnează pentru un anumit format o valoare Variant.

Pe de altă parte, funcţia Format$ returnează un şir formatat.

De fapt, orice funcţie care are ca sufix caracterul $ returnează o valoareString. Dacă formataţi o variabilă sau un grup de caractere ce vor fi atribuite uneivariabile şir, veţi obţine rezultate mai bune folosind versiunea şir a funcţiei (în loc deversiunea Variant).

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

StringFunctions(Partea 1)

Utilizând funcţiaFormat

100000 7141,3 0,0714

StringFunctions(Partea 2) Utilizând funcţiaFormat$ 100000 6749,9 0,0675

Pag. 267

sTemp1 = Forms!frmSwitchboard!imgLogo.PicturesTemp2 = Forms!frmSwitchboard!imgLogo.PictureAlignmentsTemp3 = Forms!frmSwitchboard!imgLogo.SizeMode

varTemp = Format ("abcdef", ">")

strTemp = Format$ ("abcdef", ">")

Page 263: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 263/295

12.3.6 Evitaţi folosirea structurilor lente

O altă modalitate de a mări viteza de execuţie a codului VBA este evitareastructurilor lente. Ce înseamnă aceasta? Majoritatea limbajelor oferă programatoruluimai multe metode de a efectua o anumită operaţie. Dacă viteza reală de execuţie este o prioritate de programare, ar trebui să testaţi viteza obţinută prin aplicarea fiecăreiadintre aceste metode şi să o alegeţi pe cea corespunzătoare (adică pe cea mai rapidă).În practică s-ar putea să vă daţi seama că metoda cea mai rapidă intră în conflict cu o

altă prioritate de programare, aşa încât trebuie să recurgeţi la un compromis. Chiar şiîntr-o astfel de situaţie, cronometrarea secvenţelor de cod este utilă, pentru că veţi putea folosi informaţiile obţinute în proiectele viitoare.

12.3.7 Funcţia Immediate If (IIf)

Funcţia Immediate If (IIf) este considerată, de obicei, o metodă rapidă şi simplă de areturna una din două valori, ca urmare a evaluării unei expresii ca adevărată sau falsă.

Dacă Expression are valoarea True, se returnează TruePart, iar dacăExpression este False, se returnează FalsePart. Instrucţiunea este echivalentă cusecvenţa de cod următoare:

Principala diferenţă între cele două formate este că funcţia IIf  va evaluaîntotdeauna atât TruePart, cât şi FalsePart, în timp ce structura If normală va evaluadoar partea care este returnată. Pentru a vedea ce implicaţii au aceste metode, să luămîn considerare următoarele secvenţe de cod:

Pag. 268

value = IIf (Expression, TruePart, FalsePart )

 If Expression Thenvalue = TruePart 

Else

value = FalsePart End If 

If lngNumber = 5 Then

lngRetVal = 10Else

lngRetVal = Dlast("OrderID", "Order", "OrderDate < #01-01-96#")End If 

Page 264: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 264/295

Si:

Ambele proceduri fac acelaşi lucru: evaluează variabila lngNumber. Dacăaceasta are valoare 5, procedura atribuie variabilei lngRetVal valoarea 10. Altfel, procedura atribuie variabilei lngRetVal o valoare căutată în tabelul Order.

Deosebirea dintre proceduri este că a doua va căuta întotdeauna înregistrareadin tabelul Order, indiferent dacă este necesară sau nu. Prin urmare, dacă cele două proceduri sunt apelate cu argumentul lngNumber egal cu 5, a doua va fi considerabilmai lentă.

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

IfAndIIf (Partea 1)

IIf , unde lngNumber = 5 100 4918,5 49,185

IfAndIIf (Partea 2)

If , unde lngNumber = 5 100 1,0 0,01

IfAndIIf (Partea 1)

IIf , unde lngNumber = 10 100 4634,3 46,343

IfAndIIf (Partea 2) If , unde lngNumber = 10 100 4596,4 45,9638

12.3.8.Folosiţi operaţii aritmetice cu întregi ori de câte ori este posibil

Viteza cu care se efectuează operaţiile aritmetice depinde de tipul de date alvariabilelor folosite în calcul şi de tipul operaţiei efectuate.

În general, calculele cu variabile Integer şi Long sunt mai rapide decât cele cuvariabile Single şi Double. Acestea, la rândul lor, sunt mai rapide decât calculele cuvariabile Currency. Majoritatea operaţiilor cu variabile de tip Variant durează dedouă ori mai mult decât cele în care sunt folosite alte tipuri de variabile.

Cu toate că timpii de execuţie pentru o singură operaţie diferă foarte puţin, încazul operaţiilor repetitive (cum ar fi în ciclurile de mari dimensiuni), diferenţa devinesemnificativă.

12.3.9 Folosiţi cod in-line

Ceva mai devreme, am arătat că variabilele pot fi transmise ca argumente în proceduri fie prin referinţă, fie prin valoare. Când o variabilă este transmisă prinreferinţă (cazul implicit), procedura apelată transferă un pointer către locaţia de

Pag. 269

lngRetVal = IIf (lngNumber = 5, 10, _ 

DLast ("OrderID", "Order", "OrderDate < #01-01-96#"))

Page 265: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 265/295

memorie a variabilei transmise. În schimb, când o variabilă este transmisă prinvaloare, se face o copie a variabilei şi aceasta este transmisă procedurii. Deşitransferul variabilelor prin valoare are câteva avantaje, este mai lent decât transferul prin referinţă.

Oricum, ambele metode sunt mai lente decât plasarea secvenţei de codcorespunzătoare in-line şi renunţarea la apelul unei proceduri. Dezavantajul principalal folosirii codului in-line este dificultatea de întreţinere în cazul în care aceeaşisecvenţă de cod apare in-line în mai multe proceduri. Însă dacă principala prioritate de programare este viteza de execuţie, ar trebui ca utilizarea codului in-line să constituieo opţiune serioasă.

12.3.10 Folosiţi structura For Each…Visual Basic include o structură de ciclare numită For Each…Next…, care

 permite parcurgerea succesivă a tuturor elementelor unei matrice sau unei colecţii dedate.

Înainte de introducerea limbajului VBA, metoda standard folosită în practicăconsta în determinarea numărului de elemente din colecţie sau matrice şi utilizareastructurii For…Next… pentru a inspecta fiecare element cu ajutorul unui contor deciclare pe post de index al colecţiei.

Ori de câte ori este posibil, folosiţi prima structură. Un ciclu For Each…Next… este mult mai rapid decât un ciclu obişnuit care foloseşte un contor de ciclareca index al colecţiei sau al matricei.

Pag. 270

For Each qdf In CurrentDb.QueryDefssTemp = qdf.SQLqdf.Close

Next

For iCounter = 0 To CurrentDb.QueryDefs.Count - 1Set qdf = Current.Db.QueryDefs(iCounter)

sTemp = qdf.SQLqdf.Close

Next

Page 266: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 266/295

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

For Each(Partea 2)

Utilizând o structură ciclicătradiţională

10 592,3 59,2250

For Each

(Partea 1)

Utilizând structura For…

Each

10 237,8 23,7750

12.3.11 Folosiţi judicios instrucţiunea DoEvents

Dacă nu schimbaţi condiţiile implicite de lucru, o procedură VBA aflată înexecuţie acţionează foarte egoist, acaparând toate resursele Access. De exemplu, dacărulaţi următoarea secvenţă de cod, vă veţi da seama rapid că Access este blocat pânăla terminarea execuţiei codului.

Pe calculatorul meu, execuţia acestei rutine durează aproximativ 2,8 secunde.Este bine să treceţi controlul sistemului Windows cât mai des posibil. De exemplu, s-ar putea ca în timpul execuţiei acestei rutine să doriţi anularea ei, oprirea temporarăsau chiar efectuarea unei alte operaţii. Nu este prea plăcut ca rutina respectivă să

ignore toate solicitările dumneavoastră. Aveţi nevoie de o modalitate de a permite şi procesarea altor evenimente în timpul execuţiei rutinei.Acest lucru este posibil prin utilizarea instrucţiunii DoEvents. Aceasta cere

sistemului Windows să trateze toate mesajele sau apăsările de taste care se găsesc încoada de aşteptare. În secvenţa următoare de cod, ori de câte ori ciclul ajunge lainstrucţiunea DoEvents, sistemul Windows preia controlul execuţiei şi verifică dacăîn alte aplicaţii există mesaje sau apăsări de taste care aşteaptă să fie procesate. Dupătratarea acestora, sistemul de operare transferă din nou controlul procedurii.

Cu toate că este folositoare în programare, această metodă consumă mult timp.În condiţiile în care se face o verificare a evenimentelor la fiecare parcurgere aciclului, durata de execuţie a rutinei depăşeşte 55 de minute! Dacă doriţi să

folosiţi instrucţiunea DoEvents, fiţi ceva mai rezervat. Secvenţa anterioară de cod poate fi rescrisă astfel:

Pag. 271

For lngCounter = 1 to 1000000i = Rnd*12

Next lngCounter 

For lngCounter = 1 to 1000000i = Rnd*12DoEvents

Next lngCounter 

Page 267: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 267/295

În acest caz, Windows preia controlul la fiecare 50.000 de cicluri, adică de 20de ori în 4,13 secunde (durata de execuţie a rutinei). Aceasta înseamnă uncomportament corespunzător al rutinei, dar şi o viteză de execuţie destul de mare.Instrucţiunea DoEvents adaugă doar 1,34 secunde la timpul de execuţie al secvenţeide cod.

În tabelul următor sunt prezentate rezultatele obţinute rulând cele trei variantede cod pe un calculator din clasa Pentium. Le puteţi testa şi dumneavoastră cu ajutorul procedurii DoEventsTest din baza de date Whisky14.mdb de pe CD-ul ataşat cărţii,

însă nu uitaţi că efectuarea testului cu câte o instrucţiune DoEvents la fiecare iteraţieva fi foarte lentă.

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

DoEventsTest(Partea 1)

Fără DoEvents 100000 2785,0 0,0279

DoEventsTest(Partea 2)

20 de apeluri DoEvents 100000 4127,0 0,0413

DoEventsTest(Partea 3) 100000 de apeluriDoEvents 100000 3348986,0 33,4899

12.3.12 Folosiţi metoda Requery, nu acţiunea Requery

O altă metodă de accelerare a execuţiei procedurilor este evitarea utilizăriiacţiunii Requery pentru afişarea unor valori actualizate într-un formular sau control şi

folosirea, în schimb, a metodei Requery. Aceasta este mai rapidă, deoarece nuefectuează decât o simplă repetare a execuţiei interogării pe care se bazeazăformularul sau controlul respectiv (deci nu reface setul de operaţii pe care le presupune acţiunea Requery - închiderea formularului, redeschiderea acestuia şi apoirepetarea execuţiei).

Pag. 272

For lngCounter = 1 to 1000000i = Rnd*12If lngCounter Mod 50000 = 0 Then DoEvents

Next lngCounter 

DoCmd Requery ctlText.Name 'Aceasta instructiune este lentactlText.Requery 'Aceasta instructiune este mult

‘mai rapida

Page 268: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 268/295

Trebuie să ştiţi că, uneori, metoda  Requery şi acţiunea  Requery pot generarezultate diferite. Metoda  Requery extrage din memorie valorile actualizate,  fără cheie, în setul de înregistrări al formularului, pe baza setului de cheiexistent, sau a setului de valori cheie. În schimb, acţiunea Requery reface

 setul de chei şi apoi extrage din memorie valorile fără cheie.

12.3.13 Folosiţi cuvântul cheie Me

În cazul în care folosiţi cuvântul cheie Me pentru a face referire la un formular în procedura unui eveniment, Access caută formularul respectiv în spaţiul de numelocal. Aceasta înseamnă că formularul va fi găsit mult mai repede decât în cazulspecificării sale printr-o referinţă completă.

12.4 Creşterea vitezei de execuţie a operaţiilor cu baza de date

Dacă optimizările pe care le realizaţi prin modificarea sintaxei instrucţiunilor VBA sunt uneori insesizabile, optimizarea apelurilor bazei de date conduce aproape

întotdeauna la îmbunătăţirea performanţelor. Motivule este foarte simplu. Apelurile bazei de date sunt executate, de obicei, într-un timp mai lung decât instrucţiunile VBAnormale, astfel că o creştere cu 10% a performanţelor va fi mult mai uşor vizibilă încazul apelului bazei de date. În continuare, vom analiza câteva modalităţi prin care puteţi îmbunătăţi interacţiunea codului VBA cu baza de date.

12.4.1 Folosiţi indexuri Adăugarea unui index la un câmp reprezintă o metodă de îmbunătăţire a

 performanţelor de căutare în câmpul respectiv. Cu toate că adăugarea indexurilor încetineşte actualizările şi măreşte riscul apariţiei conflictelor de blocare, aceastăsupraîncărcare este de obicei compensată de performanţele obţinute la căutareafrecventă în câmpurile respective în cadrul interogărilor. Puteţi sesiza aceste avantajerulând procedura UsingIndexes. Procedura deschide de două ori un set de înregistrări prin următoarea secvenţă de cod:

Pag. 273

Forms!frmFoo.BackColor = QBColor(9) 'Aceasta instructiune este lentaMe.BackColor = QBColor(9) 'Aceasta instructiune este mai

’rapida

Set rec = CurrentDb.OpenRecordset _ ("SELECT OrderID FROM [Order] WHERE OrderDate < #1/1/96#", _ 

dbOpenDynaset)rec.MoveLastlngRetVal = rec(0)rec.Close

Page 269: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 269/295

La prima deschidere a setului de înregistrări, câmpul OrderDate nu esteindexat; a doua oară, este indexat. Tabelul următor prezintă timpii de execuţie pentruaceastă funcţie, însă dacă doriţi, puteţi testa rutina personal.

Procedura Comentarii Număr deiteraţii

Rezultate (ms)Total Pe iteraţie

UsingIndexes(Partea 1)

OrderDate nu este indexat 100 4653,0 46,5300

UsingIndexes

(Partea 2)

OrderDate este indexat 100 2163,0 21,6300

12.4.2. Folosiţi semne de carte

La deschiderea unui set de înregistrări, fiecărei înregistrări îi este atribuităautomat o proprietate Bookmark  (semn de carte). Dacă aţi deschis un set deînregistrări şi ştiţi că veţi reveni la înregistrarea curentă, este bine să salvaţi într-o

variabilă semenul de carte (Bookmark ) corespunzător înregistrării respective.Atribuind proprietăţii Bookmark a obiectului Recordset valoarea pe care aţi salvat-oîn variabilă, veţi putea reveni la înregistrare mult mai rapid decât prin metodele Findsau Seek .

Semnele de carte (  Bookmark  ) sunt stocate ca matrice de octeţi şi ar trebui să  fie salvate în acest format, şi nu ca şiruri. Cu toate că puteţi salva proprietatea Bookmark  într-o variabilă şir, este posibil ca prin comparareavalorii Bookmark a unei înregistrări cu o valoare Bookmark memorată de o

variabilă şir să nu obţineţi rezultate corecte (cu excepţia cazului în care areloc o comparare binară).

12.4.3. Folosiţi ca sursă pentru formulare interogări salvate

Interogările salvate sunt rulate mult mai rapid decât cele create dinamic cuajutorul instrucţiunilor SQL, pentru că sunt deja compilate. De aceea, un formular care

Pag. 274

Page 270: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 270/295

se bazează pe o interogare salavată va fi deschis mult mai repede decât unul care areca sursă de înregistrări (RecordSource) o instrucţiune SQL.

Dezavantajul acestei metode este dificultatea întreţinerii. Dacă exportaţi în altă  bază de date un formular bazat pe o interogare salvată, trebuie să exportaţi şiinterogarea corespunzătoare. Pe de altă parte, dacă formularul are ca sursă de

înregistrări (RecordSource) o instrucţiune SQL, nu trebuie exportat decât formularul.12.5. Creşterea vitezei aparente

Până acum, aţi aplicat diverse metode de creştere a vitezei reale de execuţie acodului VBA şi a apelurilor bazei de date. Cum procedaţi însă dacă aţi optimizataplicaţia pentru o viteză reală de execuţie, dar aceasta continuă să fie lentă? Unadintre opţiunile posibile este creşterea vitezei aparente a aplicaţiei. Este vorba deviteza cu care crede utilizatorul că va fi rulată aplicaţia, nu de viteza reală de execuţie.

Pentru a face ca aplicaţia să pară mult mai rapidă, aveţi la dispoziţieurmătoarele modalităţi de optimizare:

Utilizarea unui formular de început Utilizarea indicatoarelor care ilustrează progresul operaţiei Ştergerea codului din modulele de formular  Preîncărcarea şi ascunderea formularelor  Memorarea locală a datelor 

12.5.1 Un formular simplu de început

Una dintre cele mai sigure metode de a distrage atenţia utilizatorilor atuncicând o aplicaţie efectuează o operaţie într-un interval de timp prea mare este afişareaunor imagini grafice atrăgătoare. De fapt, aşa procedează Microsoft. Ce se întâmplăcând porniţi Access, Word sau Excel? Vedeţi un formular de început sau un ecran dedescriere cu menţiunea de copyright:

Când vedeţi imaginea respectivă, vă spuneţi în gând: "Arată bine. Aş vrea ca şiaplicaţia mea să aibă un aspect atât de profesional!". Şi până să vă treziţi din reverie,

aplicaţia s-a şi încărcat.Dacă nu aţi vedea un ecran de deschidere, probabil că v-aţi întreba: "Oare cese întâmplă? De ce durează aşa de mult încărcarea aplicaţiei?". Ecranele de deschidereîşi îndeplinesc rolul pentru care au fost concepute.

Vestea bună este că, în Access 97, puteţi realiza foarte uşor ecrane dedeschidere. Nu trebuie decât să creaţi un formular şi să specificaţi numele său înrubrica Display Form din caseta de dialog Tools/Startup…

Un mic sfat: nu încărcaţi formularul de început cu prea multe controale sau cu

un cod prea complex pentru evenimentul Load, deoarece riscaţi ca afişareaformularului să dureze prea mult şi nu vă mai atingeţi scopul!

Pag. 275

Page 271: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 271/295

12.5.2 Folosiţi indicatoare care ilustrează progresul operaţiei

O altă modalitate de a distrage atenţia utilizatorilor - şi de a-i asigura că seîntâmplă ceva - este afişarea pe ecran a unui indicator care prezintă progresuloperaţiilor efectuate. Funcţia SysCmd oferă o metodă simplă de a realiza acest lucru.

Pentru a afişa un indicator de progres pe bara de stare a aplicaţiei, trebuie parcurse treietape: Iniţializarea contorului (indicatorului) de progres, cu specificareavalorii maxime şi a textului care trebuie afişat Actualizarea repetată a contorului pentru a ilustra progresul operaţiei Ştergerea indicatorului de progres

Următoarea secvenţă de cod reprezintă una dintre metodele de afişare aindicatorului de progres:

Această procedură determină afişarea unui indicator de progres, care se umplegradual, precum şi a testului "Testing…".

Desigur, pentru actualizarea indicatorului, dumneavoastră nu trebuie să scrieţiun ciclu de instrucţiuni. Vă puteţi structura procedura astfel:

Pag. 276

Sub ShowProgress()

Dim varRetVal As VariantDim i As Integer 

Dim j As Integer Dim intRnd As Integer 

'Initializeaza indicatorul de progres si stabileste valoarea maxima 300

For i = 0 To 300'Executa o serie de operatii de prelucrareFor j = 0 To 1000

IntRnd = Rnd * 10 + 1Next j

‘ Actualizeaza contorul pentru a ilustra progresul operatiei

varRetVal = SysCmd(acSysCmdUpdateMeter, i)Next i

'Elimina indicatorul de progres de pe bara de starevarRetVal = SysCmd(acSysCmdRemoveMeter)

End Sub

Page 272: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 272/295

Cele trei constante, acSysCmdInitMeter, acSysCmdUpdateMeter şiacSysCmdRemoveMeter, care sunt folosite pentru iniţializarea, actualizarea şiştergerea indicatorului de progres de pe bara de stare, sunt intrinsece mediului Access.Cu alte cuvinte, fac parte din limbaj şi nu trebuie declarate nicăieri.

12.5.3 Ştergeţi codul din modulele de formulare

Utilizatorii încep să se agite dacă execută clic pe un buton pentru a deschideun formular şi afişarea acestuia întârzie. Aşa se întâmplă de obicei când un formular are foarte mult cod în modulul său, care măreşte durata de încărcare. În acest caz, ar trebui să ştergeţi codul din modulul de formular şi să îl plasaţi într-un modul de codstandard. Ca urmare, formularul va fi afişat mult mai repede, iar codul va fi încărcatnumai la cerere, după deschiderea formularului.

12.5.4 Preîncărcaţi şi ascundeţi formularele

Pe lângă metoda prezentată anterior, dacă folosiţi frecvent un anumit formular care necesită mult timp pentru încărcare şi descărcare, puteţi să încărcaţi formularul întimpul lansării în execuţie a aplicaţiei şi apoi să îl afişaţi şi să îl ascundeţi, în loc să îlîncărcaţi şi descărcaţi în memorie.

Pag. 277

Sub ShowProgress()Dim varRetVal As Variant

'Initializeaza indicatorul de progres si stabileste'valoarea maxima 300varRetVal = SysCmd(acSysCmdInitMeter, "Testing…", 300)

'Executa o serie de operatii de prelucrare….'Actualizeaza contorul pentru a ilustra progresul operatieivarRetVal = SysCmd(acSysCmdUpdateMeter, 5)

'Executa alte operatii de prelucrare….'Actualizeaza contorul pentru a ilustra progresul operatieivarRetVal = SysCmd(acSysCmdUpdateMeter, 10)

'Alte operatii de prelucrare…….'Actualizeaza contorul pentru a ilustra progresul operatieivarRetVal = SysCmd(acSysCmdUpdateMeter, 15)

 Elimina indicatorul de progres de pe bara de starevarRetVal = SysCmd(acSysCmdRemoveMeter)

End Sub

Page 273: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 273/295

Această tehnică va încetini lansarea în execuţie a aplicaţiei, dar va creştesubstanţial performanţa de ansamblu. Puteţi întârzia încărcarea formularului chiar şidupă afişarea pe ecran a formularului principal al aplicaţiei. În timp ce utilizatorul priveşte formularul principal, în fundal poate fi încărcat al doilea formular.

Metoda prezentată este utilă dacă viteza aparentă este o prioritate de

 programare, însă reţineţi că mai multe formulare încărcate concomitent vor sporicantitatea de memorie necesară aplicaţiei.

12.5.5. Stocaţi datele în memoria locală

O zonă cache este o zonă de memorie (sau spaţiu pe hard-disc) utilizată pentrua stoca valori provenite din altă parte şi pregătite pentru a fi refolosite. De exemplu,Windows 95 plasează datele provenite de pe hard-disc într-o zonă cache reprezentatăde o porţiune din memorie. Sunt frecvente situaţiile în care un program foloseşte în

mod repetat aceleaşi date. Prin această metodă, programul va citi datele direct dinzona cache şi nu va mai pierde timp căutându-le de fiecare dată pe hard-disc. În plus,citirea din memorie este mai rapidă şi mai eficientă decât citirea de pe hard-disc.

Prin urmare, puteţi îmbunătăţi performanţele unei aplicaţii utilizând zonecache pentru stocarea datelor. În ordinea descrescătoare a vitezei, cele trei metode deobţinere a datelor sunt:

Citirea datelor din memorie (de exemplu, variabile, matrice) Citirea datelor din tabele stocate

Citirea datelor din tabele stocate pe calculatoare legate într-o reţea

Dacă doriţi să creşteţi viteza aparentă de rulare a aplicaţiei, gândiţi-vă la un nivelsuperior de stocare a datelor (adică la schimbarea tipului de memorie cache).Dacă păstraţi date accesate frecvent - dar care nu se modifică des - într-un tabel de peun sever de reţea ar trebui să aveţi în vedere copierea datelor pe calculatorul clientlocal pentru ca aplicaţia să ruleze mai repede. Totuşi, va trebui să vă asiguraţi că, oride câte ori sunt actualizate pe server, datele vor fi actualizate şi pe calculatoareleclient (şi invers).

În mod similar, dacă aveţi date într-un tabel de căutare (de exemplu, Region) pe careîl accesaţi frecvent prin codul VBA, puteţi crea cu ajutorul metodei GetRows omatrice pentru stocarea datelor respective. Această tehnică poate mări semnificativviteza de obţinere a datelor. Bineînţeles, va creşte şi necesarul de memorie pentruaplicaţia dumneavoastră.

12.5.6. Consideraţii referitoare la lucrul în reţea

Până acum, ne-am concentrat atenţia asupra scrierii unui program care să încapă într-ozonă redusă de memorie şi să poată fi executat cât mai repede posibil - sau măcar să

Pag. 278

Page 274: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 274/295

creeze această impresie. Însă unul din motivele esenţiale pentru care aplicaţiile de baze de date Access sunt lente nu are nici o legătură cu dimensiunea memorieinecesare sau cu viteza de execuţie a codului. De cele mai multe ori, rularea lentă estecauzată de cantitatea enormă de date care trebuie să fie citite de pe disc şi apoitransferate prin reţea.

Lucrul în reţea are două neajunsuri importante. În primul rând, performanţaobţinută la transferul datelor - în special printr-o reţea lentă - poate fi mai slabă decâtîn cazul folosirii tabelelor locale. În al doilea rând, s-ar putea ca aplicaţiadumneavoastră să genereze un intens trafic de reţea. Acest fapt îi va deranja pe ceilalţiutilizatori ai reţelei, care vor observa că aplicaţiile lor sunt încetinite considerabil dincauza aglomerării traficului. Dacă unul dintre cele două aspecte menţionate reprezintăo problemă pentru dumneavoastră, puteţi aplica următoarele tehnici:

Căutarea după câmpuri indexate în tabele ataşate Plasarea pe calculatorul local a obiectelor care nu sunt de tip tabel

Dezactivarea opţiunii AutoExpand

12.6. Ultimele retuşuri

Toate sugestiile de până acum au fost analizate ca priorităţi specifice de  programare: creşterea vitezei reale de execuţie, reducerea traficului de reţea sau

micşorarea amprentei de memorie a aplicaţiei de baze de date.În unele cazuri, o singură măsură de optimizare poate aduce mai multeavantaje. De exemplu, schimbarea tipului unei variabile de la Variant la întreg vareduce considerabil necesarul de memorie şi va creşte viteza de execuţie.

Totuşi, există şi situaţii în care o măsură de optimizare are efecte antagonice:atât pozitive, cât şi negative. De exemplu, tehnica de încărcare şi ascundere aformularelor va mări viteza aparentă de execuţie a aplicaţiei, dai şi amprenta dememorie a acesteia. În această situaţie, trebuie să vă stabiliţi priorităţile şi să acţionaţiîn consecinţă.

Secţiunea finală din acest capitol prezintă câteva tehnici care îmbunătăţescîntotdeauna performanţele aplicaţiei dumneavoastră - indiferent de priorităţile de programare.Acestea sunt:

Compactarea bazei de date Compilarea tuturor modulelor  Deschiderea bazelor de date în mod exclusiv

Pag. 279

Page 275: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 275/295

12.6.1 Compactarea bazei de dateDupă o perioadă de timp, este posibil să constaţi că performanţele aplicaţiei

dumneavoastră sunt în scădere. Cauza ar putea fi procesul de fragmentare a bazei dedate.

Fragmentarea se produce la ştergerea unor obiecte din baza de date, în situaţia

în care spaţiul folosit de aceste obiecte nu este recuperat. Baza de date va fi ca unşvaiţer - cu o mulţime de spaţii goale - şi, în acelaşi timp, va deveni mai lentă. Deşi nueste deteriorată în nici un fel, performanţele scad. Aceasta pentru că citirea datelor necontigue (fragmentate) de pe disc este mai lentă decât a datelor contigue.

Prin compactarea unei baze de date, este eliminat tot spaţiul nefolosit (găuriledin şvaiţer), iar paginile de date devin contigue. Aplicarea acestei tehnici prezintădouă avantaje:

Îmbunătăţirea performanţelor bazei de date Reducerea dimensiunii fişierului bazei de date

Compactarea unei baze de date se poate realiza cu ajutorul opţiunii specificedin meniu, dar şi prin cod VBA, folosind metoda CompacteDatabase a obiectuluiDBEngine:

Pentru a obţine performanţe optime, înainte de compactarea bazei de date ar trebui să folosiţi un program de defragmentare a discului (de exemplu Disk 

Defragmenter, care este distribuit împreună cu Windows 95).12.6.2 Compilarea tuturor modulelor

Aţi lucrat cu înfrigurare tot weekend-ul pentru a termina aplicaţia de baze dedate, în vederea prezentării de luni în faţa consiliului. Aţi testat aplicaţia azi-noapte -într-un mediu obişnuit de lucru - şi aceasta a funcţionat bine. Mai aveţi la dispoziţie ooră şi vă gândiţi să rulaţi o mică rutină proprie de bibliotecă pentru a adăuga procedurilor nişte anteturi de efect. Durează doar câteva minute şi aţi rulat-o de multeori, aşa încât ştiţi sigur că nu conţine erori de programare.

Momentul aşteptat a sosit; membrii consiliului se aşează în jurul mesei,dumneavoastră executaţi clic pe pictograma aplicaţiei… şi aşteptaţi… aşteptaţi…aşteptaţi…

"Ce este asta?" vă întrebaţi în gând. "Ce s-a întâmplat cu aplicaţia mea? Semişcă de parcă ar fi un câine şchiop… aflat în comă". Poate că aţi uitat să recompilaţiaplicaţia!

Când efectuaţi modificări (de orice fel) într-un modul de cod standard sau într-

un modul de clasă (inclusiv modulele de formulare şi rapoarte), modulul respectivtrebuie să fie recompilat înainte de a fi lansat în execuţie. Pentru a

Pag. 280

DBEngine.CompactDatabase "c:\myold.mdb","c:\mynew.mdb"

Page 276: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 276/295

compila codul din toate modulele bazei de date, selectaţi opţiunea Compile and SaveAll Modules din meniul Debug.

Dacă nu compilaţi explicit codul prin această metodă, sistemul Accesscompilează codul în timpul de execuţie, ceea ce poate determina o întârzieresemnificativă, în special dacă modulele compilate conţin multe linii de cod.

Întârzierea este limitată dacă aţi validat caseta Compile On Demand (Compilare lacerere) din pagina etichetei Module a casetei de dialog Tools/Options… În acest caz,Access compilează secvenţele de cod apelate de procedura executată - prin arborele deapeluri. Ca urmare, întârzierea este mai mică. Pentru siguranţă, ar trebui ca înainte dedistribuirea aplicaţiei, să compilaţi întotdeauna întregul cod. Prin compilare, vor fidetectate o serie de erori, cum ar fi o instrucţiune For… care nu este urmată deinstrucţiunea Next.

12.6.3 Deschiderea bazelor de date în mod exclusivDacă sunteţi singura persoană care va folosi baza de date la un moment dat, ar 

trebui să o deschideţi în mod exclusiv. Aplicaţia va fi executată mai rapid, deoareceAccess nu va mai pierde timpul cu monitorizarea altor utilizatori care doresc să blocheze înregistrări. Pentru a vă asigura că baza de date va fi deschisă în modexclusiv, selectaţi opţiunea Exclusive ca Defalut Open Mode în pagina eticheteiAdvanced a casetei de dialog Tools/Options…

Dacă doriţi să deschideţi o singură bază de date în mod exclusiv atunci când

este prestabilit modul partajat, executaţi clic în caseta de validare Exclusive din casetade dialog Open Database.Dacă lansaţi aplicaţia din linia de comandă, puteţi folosi opţiunea /Excl pentru

a obţine acelaşi rezultat.

Dacă deschideţi baza de date în VBA, configuraţi argumentul Exclusive lavaloarea True atunci când folosiţi metoda OpenDatabase:

12.7 Rezumat

Pag. 281

c:\access\msaccess.exe c:\abwrox\code\wrox.mdb /Excl

Set db = DBEngine(0).OpenDatabse("c:\abwrox\code\wrox.mdb", True)

Page 277: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 277/295

Crearea unei aplicaţii este o mare realizare. Construirea unei aplicaţii carerulează rapid (sau măcar dă această impresie) şi u ocupă toată memoria calculatoruluiînseamnă însă cu totul altceva - este ceea ce va consacra sau va invalida aplicaţi.Utilizatorii sunt fiinţe nerăbdătoare şi, pentru ei, nimic nu este mai rău decât un program ineficient.

Acest capitol a prezentat o serie de sugestii şi trucuri pentru creşterea vitezeigenerale de execuţie a codului. Înainte de a începe scrierea secvenţelor de cod, ar trebui să stabiliţi care sunt priorităţile de programare şi apoi să urmaţi sugestiile prezentate în carte. Nu uitaţi că optimizarea unei priorităţi, cum ar fi mentenabilitatea, poate afecta un obiectiv secundar, a de exemplu viteza de execuţie a codului - numaidumneavoastră puteţi decide care prioritate este mai importantă.

În capitolul de faţă, s-a prezentat:

Cum poate fi redusă supraîncărcarea memoriei prin alegerea

corespunzătoare a tipurilor de date, recuperarea memoriei şi renunţarea lacomentariile de prisos

Tehnicile de programare prin care puteţi mări viteza de execuţie

Diverse trucuri, cum ar fi utilizarea unui ecran de început şi a unor 

indicatoare care să ilustreze progresul unei operaţii, pentru a distrage

atenţia utilizatorului şi a crea impresia că aplicaţia rulează mai rapid

Cum să măriţi eficienţa unei aplicaţii de reţea

În capitolul următor, vom discuta despre avantajele codului refolosibil, arătândcum puteţi folosi bibliotecile de rutine şi programe de completare pentru a reducetimpul de dezvoltare şi de testare a aplicaţiei.

Pag. 282

Page 278: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 278/295

CAP: 13 .INTERNET

Iată subiectul cel mai fierbinte şi controversat din lumea calculatoarelor. Mulţi

văd în Internet salvatorul societăţii noastre - prin crearea unei comunităţi globale, careare la dispoziţie o abundenţă de informaţii, 24 de ore pe zi. Alţii văd în Internet unmonstru care aşteaptă să ne înghită după ce îi vom cădea cu toţii în capcaneleademenitoare.

Indiferent de care parte vă situaţi, realitatea este că reţeaua Internet există, vaexista încă mulţi ani şi, cel mai important, poate constitui un instrument de lucrufoarte util.

Acest capitol este dedicat modalităţilor în care puteţi folosi facilităţile Internetîn Access 97. Vom prezenta următoarele subiecte:

Ce este Internetul?

Cum se utilizează hiperlegăturile?

Cum se pot publica date în Internet?

Crearea unui browser Web

13.1 Ce este Internetul?

Termenul Internet denumeşte o colecţie de calculatoare legate între ele - oreţea foarte mare, dat atâta tot. Înainte de a vedea cum putem folosi caracteristicileAccess pentru a ne conecta în şi din Internet, vom defini câteva noţiuni:

HyperText Markup Language, HTML,  este formatul în care sunt stocatedocumentele Internet. Este un limbaj foarte simplu, care iniţial, era destinataranjării textului pe ecran, formatărilor etc. caracteristica hipertext permitestabilirea unor legături între documente, astfel încât dumneavoastră să puteţi trece

uşor de la un document la altul, urmărind legăturile şi referinţele existente. HTMLevoluează continuu, incluzând din ce în ce mai multe facilităţi; deocamdată,gândiţi-vă la HTML ca la o posibilitate de formatare a documentelor.

Un browser (program de navigare în Web) este un program care afişeazădocumente HTML. Cele mai cunoscute browsere sunt Microsoft Internet Explorer şi Netscape.

Un sit Web este un calculator (sau un grup de calculatoare) din Internet care păstrează documente HTML. De exemplu, situl Web al editurii Wrox se găseşte laadresa http://www.wrox.com. Expresia www provine de la World Wide Web,

numit uneori doar Web; wrox este numele companiei, iar com prescurtarea de lacompanie sau sit comercial. Alte sufixe des întâlnite sunt .edu (pentru situri

Pag. 283

Page 279: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 279/295

educaţionale, cum sunt cele ale universităţilor şi colegiilor) şi .gov (pentru situriguvernamentale).

O adresă URL (Uniform Resource Locator) este numele atribuit unui anumit sitWeb sau a unui document din situl respectiv. Documentele sunt stocate la fel ca pe

un hard-disc obişnuit, într-o structură de directoare. Pentru pagina Access a firmeiMicrosoft, adresa URL ar fi http://www.microsoft.com/access. Un server Web este maşina care controlează un sit Web. Acest server primeşte

cereri de la browserele Web şi le pune la dispoziţie documentele solicitate.

13.2 Protocoale

Pentru a evita orice confuzie, haideţi să vedem care sunt principalele proto-coale folosite în Internet şi cum funcţionează.

Un protocol este numele limbajului prin care calculatoarele comunică între ele.Într-o reţea sistemele componente se înţeleg prin intermediul unui protocol de reţea.Când comunicaţi cu un calculator din Internet, folosiţi tot un protocol de reţea. Decând prin Internet se furnizează şi alte materiale decât pagini HTML, au apărut şi protocoale care indică activitatea pe care doriţi să o desfăşuraţi. De exemplu:

Când folosiţi un browser Web pentru a accesa documentele HTML, utilizaţi un protocol de transfer pentru hipertext (HxperText Transfer Protocol - HTTP). Estemotivul pentru care adresele URL încep cu http:. În acest fel, se comunică

serverului Web tipul de serviciu pe care doriţi să îl folosiţi. Un alt protocol important este protocolul pentru transferul fişierelor (File Transfer Protocol - FTP). Acest vă permite să transferaţi în şi dintr-un server Web programe şi documente. În acest caz, adresa URL va începe cu ftp:.

Un alt protocol pe care îl veţi folosi, probabil, în Access este protocolul MailTo,care ajută programul dumneavoastră de poştă electronică să transmită mesaje e-mail. În acest caz, adresa va începe cu mailto:.

Desigur, există multe alte protocoale, însă acestea nu sunt folosite atât defrecvent precum cele prezentate anterior.

13.3 Date de tip hiperlegătură (Hyperlink)

Access 97 are un nou tip de date pentru lucrul în Internet - Hyperlink . Caurmare, puteţi introduce o adresă URL ca un câmp într-un tabel sau într-un formular.Hiperlegătura poate conţine trei informaţii: un text de afişare, o adresă şi o sub-adresă.

Textul de afişare este textul pe care doriţi să îl afişaţi pe ecran. Aţiobservat probabil în timpul navigării prin Web că multe legături suntdescrise prin text, şi nu prin adrese URL.

Adresa este URL-ul materialului care va fi vizualizat. Sub-adresa este secţiunea din cadrul materialului.

Pag. 284

Page 280: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 280/295

Cele trei părţi sunt separate prin semnul diez (#); prin urmare, o hiperlegătură aratăastfel:

 Display Text#Address#Sub Address

Pentru clarificare vom prezenta câteva exemple:

Adresa URL Textul afişat pe ecran Acţiunehttp://www.microsoft.com http://www.microsoft.com Sare la pagina iniţială

MicrosoftMicrosoft on theWeb#www.microsoft.com

#

Microsoft on the Web Sare la pagina iniţialăMicrosoft

Hyperlinks#C:\Wrox\BegVBA97\Internet.doc#Hyperlinks

Hyperlinks Deschide documentulC:\Wrox\BegVBA97\Internet.doc şi sare lasemnul de carteHyperlinks

Whiskies#C:\Wrox\BegVBA97\Whisky.mdb#Form frmMaintWhisky

Whiskies Deschide formularulfrmMaintWhisky din baza de date

C:\Wrox\BegVBA97\Whisky.mdbWhiskies## FormfrmMaintWhisky

Whiskies Deschide formularulfrmMaintWhisky din baza de date curentă

Observaţi că tipul de date hiperlegătură nu limitează adresele URL doar ladocumente HTML. Puteţi indica şi documente Word, foi de calcul Excel, formulareAccess etc. Beneficiind de posibilitatea de a deschide formulare, puteţi chiar să

înlocuiţi codul butoanelor care deschid alte formulare cu o adresă de hiperlegătură.Aceasta va deschide un formular nou fără a folosi vreo instrucţiune de cod.

13.4. Cum se utilizează hiperlegăturile?

Gândiţi-vă cât de utile ar fi hiperlegăturile în aplicaţia dumneavoastră, pentruca utilizatorii, cu un singur clic de mouse, să poată ajunge într-un sit Web. Dinfericire, hiperlegăturile sunt extrem de simplu de implementat, pentru că Access permite folosirea tipului de date Hyperlink în tabele şi formulare.

Pag. 285

Page 281: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 281/295

13.5 Hiperlegături în VBA

După ce aţi văzut câte de uşor este să adăugaţi hiperlegături în tabele şiformulare, vă întrebaţi, probabil, cum puteţi implementa prin program aceste

elemente. Ei bine, şi tipul de date Hyperlink are câteva metode şi proprietăţi, la fel catoate celelalte obiecte.

Element Tip DescriereHyperlink  Proprietate O proprietate a controlului asociat cu coloana de

hiperlegături care face referire la obiectulhiperlegătură.

Address Proprietate Adresa principală a hiperlegăturii.SubAddress Proprietate Sub-adresa hiperlegăturii.

Follow Metodă Urmăreşte hiperlegătura până la destinaţie. Are oacţiune similară cu executarea unui clic pe control.AddToFavorities Metodă Adaugă hiperlegătura în dosarul Favorites.FollowHyperlink  Metodă Urmăreşte hiperlegatura direct prin adresă. Este

folosită pentru controalele care nu au proprietateaHyperlinkAddress.

HyperlinkPart Metodă Desparte hiperlegătura în părţile componente.

Datorită utilizării simple a hiperlegăturilor din tabele şi formulare, s-ar putea

să nu aveţi nevoie să folosiţi aceste funcţii prin cod VBA. Aşa cum aţi văzut,executarea unui clic pe o hiperlegătura în Access este acelaşi lucru cu deschiderea de pagini Web cu ajutorul unei hiperlegături. Totuşi, s-ar putea să existe situaţii în care sădoriţi manipularea hiperlegăturilor prin cod - în acest scop, puteţi folosi metodele dintabelul de mai sus, care sunt foarte simple. Există o funcţie care vă uşurează munca;aceasta se numeşte HyperlinkPart.

13.6. Publicarea în Web

Acum, după ce aţi văzut că datele pot fi legate şi din surse externe, vă întrebaţi probabil cum să puneţi la dispoziţia celor interesaţi datele din Access. Este foartesimplu, însă, şi în acest caz, vom începe prin a prezenta câteva aspecte teoretice.

13.6.1 Documente HTML staticeO pagină HTML statică este un document HTML independent, care prezintă

datele din momentul în care a fost creat. Documentul nu este legat la o bază de date şinu reflectă modificările din cadrul acesteia. Pentru a actualiza datele dintr-un

document HTML static, va trebui să îl creaţi din nou. Documentele HTML statice suntfoarte bune pentru texte cu caracter general, însă nu şi în cazul bazelor de date,

Pag. 286

Page 282: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 282/295

deoarece nu afişează cele mai recente informaţii. Aceste documente au sufixul .htmlşi pot fi folosite pe orice server Web.

În documentele HTML statice puteţi salva tabele, interogări, formulare şirapoarte. În cazul rapoartelor, formatarea se păstrează, astfel că documentul rezultatva arăta exact ca un raport Access, însă pentru celelate tipuri de obiecte, documentul

va avea aspectul unei foi de date.Există două metode de a salva datele ca document HTML. Prima metodă este

următoarea: selectaţi elementul dorit şi alegeţi Save As/Export…din meniul File.Apoi selectaţi opţiunea To an External File or Database (Într-un fişier extern sauîntr-o bază de date) din caseta de dialog afişată pe ecran.

Pe ecran va fi afiată caseta de dialog Save standard. Schimbaţi opţiunea Saveas type în HTML Documents (Documente HTML).

Introduceţi un nume de fişier şi executaţi clic pe butonul de Export; cu aceasta,

aţi terminat. Acum puteţi deschide fişierul într-un browser Web. Trebuie remarcat căîn câmpurile de căutare sunt afişate numele de identificare, şi nu datele de căutare.

13.6.2 Aplicaţia wizard HTML ExportA doua metodă de a exporta obiecte ale unei baze de date în documente

HTML constă în folosirea aplicaţiei wizard HTML Export. Pentru a o lansa înexecuţie, alegeţi Save As HTML din meniul File. Aplicaţia vă va conduce prinetapele procesului de creare a documentului HTML, permiţându-vă să alegeţiobiectele pe care doriţi să le salvaţi şi tipul de export pe care doriţi să îl realizaţi.

Există şi alte opţiuni, care vă permit să alegeţi şabloane, o sursă de date ODBC sau o bază de date Access, precum şi locul unde doriţi să salvaţi documentul. Nu vom studia toate aceste detalii; amintim doar că aplicaţia wizard reuneşte

trei metode de salvare a informaţiilor în documente HTML.

13.6.3 Internet Data ConnectorInternet Data Connector - IDC permite afişarea unei pagini dinamice, create

dintr-un document HTML, care interoghează baza de date şi afişează informaţiilecăutate. La fiecare deschidere sau împrospătare a paginii, are loc o nouă interogare a bazei de date. Această bază de date poate fi orice sursă de date ODBC, însă serverulWeb trebuie să fie Microsoft Internet Information server (IIS). Sunt necesare douăfişiere: un fişier .idc şi unul .htx.

În fişierele IDC puteţi exporta tabele, interogări şi formulare, însă toateacestea vor arăta ca nişte foi de date. Urmaţi acelaşi algoritm ca în cazul documentelor HTML statice, însă de data aceasta selectaţi în câmpul Save as type opţiuneaMicrosoft IIS 1-2.

Pag. 287

Page 283: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 283/295

13.6.4.Active Server Pages

Active Server Pages (pagini server active), succesorul lui IDC, este otehnologie de creare a paginilor dinamice, care afişează baza de date în starea sacurentă. Spre deosebire de IDC, aceste pagini sunt similare cu formularele, permiţând

introducerea, editarea şi ştergerea datelor dintr-o pagină Web. Datele pot proveni dinorice sursă ODBC, însă serverul Web trebuie să fie Internet Information Server, dedata aceasta cel puţin versiunea 3.0, având instalată opţiunea Active Server Pages.Fişierele Active Server Pages sunt înregistrate cu extensia .asp. spre deosebire demetoda IDC, care creează două fişiere, metoda Active Server Pages creează un singur fişier pentru fiecare foaie de date.

În fişierele ASP puteţi exporta tabele, interogări şi formulare. Tabelele şiinterogările sunt afişate ca foi de date, iar formularele sunt afişate în format HTML,

având un aspect similar cu formularele din Access. Controalele din formular suntînlocuite cu controale ActiveX, însă codul VBA al formularului nu este convertit.

Pentru a poziţiona controalele în pagina HTML, Access foloseşte controlulMicrosoft HTML Layout. Acest program este distribuit împreună cu Internet Explorer 3.0 sau o versiune ulterioară (şi este disponibil în situl Web Microsoft), însă nu poaterula independent. Prin urmare, pentru a crea pagini ASP aveţi nevoie de InternetExplorer, cel puţin versiunea 3.0.

Lista următoare prezintă controalele Access care sunt înlocuite cu controaleActiveX.

Controlul Access Controlul ActiveX corespunzătorCasetă de text Casetă de textCasetă de text asociată unuicâmp cu o hiperlegătură

Casetă de text care afişează textul hiperlegăturii. Cutoate acestea, hiperlegătura nu poate fi urmărită.

Casetă cu listă Casetă cu listă (cu o singură coloană)Casetă combinată Casetă combinată

Controlul Access Controlul ActiveX corespunzător

Pag. 288

Page 284: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 284/295

Etichetă Etichetă. Dacă eticheta are configurate proprietăţileHyperlinkAddress şi/sau HyperlinkSubAddress, este creatăo hiperlegătură pentru etichetă.

Buton de comandă Buton de comandă, dar secvenţa de cod corespunzătoare butonului nu este salvată. Dacă butonul de comandă are

configurate proprietăţile HyperlinkAddress şi/sauHyperlinkSubAddress, este creată o hiperlegătură pentru buton.

Grup de opţiuni Grup de opţiuni, însă fără un cadru de grupButon de opţiune Buton de opţiuneCasetă de validare Casetă de validareButon comutator Buton comutator  Control ActiveX Control ActiveX, însă secvenţa de cod corespunzătoare

controlului este salvată.

Următoarele controale nu sunt convertite la salvarea unui formular ca fişier ASP şi, de aceea, sunt ignorate:

Controale Tab Dreptunghiuri Linii Separatori de pagini Cadre de obiecte neasociate Cadre de obiecte asociate Controale de imagine Fundalurile de formulare configurate cu ajutorul proprietăţii Picture

În ciuda acestor lipsuri, obţineţi un formular funcţional.

Pentru a salva datele într-un fişier ASP, folosiţi acceaşi metodă ca mai înainte,însă de data aceasta, selectaţi în câmpul Save as type opţiunea Microsoft ActiveServer Pages.

Şi aici există spaţii speciale pentru introducerea şablonului HTML şi ainformaţiilor despre sursa de date ODBC, însă apare şi un câmp pentru adresaserverului, unde trebuie să introduceţi adresa completă la care va fi stocat documentul.În exemplul nostru, este o adresă la care este instalat Personal Web Server, careacceptă şi paginile server active (Active Server Pages).

Dacă aţi salvat un formular, puteţi să deschideţi fereastra aplicaţiei InternetExplorer 3.0 pentru a-l vizualiza.

Deşi nu este perfectă, această tehnică a permis parcurgerea unor paşiimportanţi în direcţia realizării unor aplicaţii pentru Web.

Pag. 289

Page 285: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 285/295

13.7. Crearea unui browser

Până acum, aţi văzut cât de uşor vă puteţi publica datele din Access însistemul Web; însă cum includeţi funcţii Web în aplicaţiile dumneavoastră? Este un proces la fel de simplu, deoarece firma Microsoft a realizat un control de navigare

Web (Web Browser Control) care poate fi adăugat în formularele dumneavoastră.Astfel, formularele vor avea propriul browser şi nu veţi mai fi nevoit să rulaţi unulseparat. Oricum, pentru a folosi acest control, trebuie să aveţi instalat produsulInternet Explorer 3.0 sau o versiune ulterioară.

Încercaţi singur - Un browser Web

1. Deschideţi tabelul Company în modul de afişare pentru proiectare(Design) şi adăugaţi un câmp nou, numit WebSite, de tip Hyperlink .

Salvaţi şi închideţi tabelul.2. Deschideţi formularul frmMaintCompany în modul de afişare pentru proiectare. Măriţi puţin dimensiunea formularului.

3. Selectaţi butonul More Controls (Alte controale) din caseta de instrumente.4. Acum derulaţi lista de constroale plasând cursorul pe săgeata din partea de

 jos a formularului şi selectaţi opţiunea Microsoft Web Browser Control.5. Adăugaţi acest control în formularul dumenavoastră, aşa cum procedaţi cu

orice alt control. S-ar putea să fie necesară redimensionarea formularului pentru a face loc noului control. Denumiţi controlul ctlBrowser.

6.Adăugaţi un buton de comandă, denumiţi-l cmdWeb şi completaţi titlul(Caption) View Web Page (Vizualizare pagină Web).

7. Editaţi codul pentru evenimentul Click  al noului buton, adăugândurmătoarea linie de cod:

Această instrucţiune foloseşte metoda Navigate a controlului Browser pentrua naviga către hiperlegătură.

8. Închideţi formularul şi salvaţi-l.9. Deschideţi tabelul Company şi adăugaţi următoarea adresă în câmpul

WebSite pentru produsul Bacchanalia:

Această adresă indică pagina iniţială a produsului Bacchanalia, memoratălocal pe hard-discul calculatorului dumneavoastră.

10. Acum deschideţi formularul frmMaintCompany în modul de afişareForm şi selectaţi înregistarea Bacchanalia; executaţi clic pe butonul ViewWeb Page. Browserul va afişa imediat pagina Web corespunzătoare.

Din păcate, există o serie de probleme legate de controlul Browser şi deInternet Explorer 3.0. Probabil aţi observat că dimensionarea este inadecvată, astfel că

Pag. 290

ctlBrowser.Navigate HyperlinkPart)Me!Website, acAddress)

file://C:\\BegVBA\\bacch.htm

Page 286: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 286/295

  paginile Web au un aspect necorespunzător şi nu execută corect operaţia deîmprospătare. Ar fi mult mai bine dacă aţi indica un sit Web prin http, şi nu prin file.Aceste neajunsuri sunt cunoscute şi sperăm că vor fi rezolvate curând.

Totuşi, controlul Web Browser poate vizualiza documente HTML care includ: Elemente HTML standard şi îmbunătăţiri HTML, cum ar fi cadrele

mobile şi foile afişate în cascadă Alte controale ActiveX Majoritatea produselor de completare Netscape Scripturi, cum sunt Microsoft Visual Basic Scripting Edition(VBScript) sau JavaScript Elemente multimedia, de exemplu secvenţe audio şi video Imagini virtuale tridimensionale create cu Virtual Reality ModelingLanguage (VRML) Documente Microsoft Office

Cred că acest control este mult mai util pentru aplicaţiile intranet, care vă oferă posibilitatea de combinare a conţinutului. Pentru cei care au deja aplicaţii Access, dar dezvoltă aplicaţii noi bazate pe Internet/intranet, controlul Browser poate constitui unsprijin important în trecerea la o aplicaţie combinată.

13.8.Rezumat

În acest capitol au fost prezentate câteva facilităţi oferite de Access 97 pentrulucrul în Internet. Utilizarea pe scară largă a Internetului în viaţa de zi cu zi şi interesul

 public general constituie premise pentru dezvoltarea şi îmbunătăţirea unor astfel decaracteristici.

Subiectele principale din acest capitol au fost: Hiperlegăturile şi utilizarea lor în Access Importul şi exportul documentelor HTML Crearea unui browser Web în Access

Pag. 291

Page 287: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 287/295

CAP: 1. NOŢIUNI GENERALE DESPRE BAZE DE DATE.............................................................6

1.1 BAZĂ DE DATE. BAZE DE DATE RELAŢIONALE........................................................................................61.1.1 Chei primare, chei secundare.................................................................................................6 

1.1.2 Relaţii.....................................................................................................................................7 1.1.3 Teoria normalizării.................................................................................................................7 1.2 SISTEME DE GESTIUNE A BAZELOR  DE DATE...........................................................................................8

1.2.1 Limbaje de interogare. SQL....................................................................................................91.3 MODELUL RELAŢIONAL....................................................................................................................10

1.3.1. Scurtă descriere a modelului relaţional...............................................................................101.3.2 Reguli de fidelitate ale bazelor de date................................................................................11

BIBLIOGRAFIE.......................................................................................................................................15

CAP:2. BAZE DE DATE, TABELE ŞI RELAŢII ...............................................................................15

2.1 CREAREA UNEI BAZE DE DATE............................................................................................................162.2. CREAREA TABELELOR ......................................................................................................................17

2.2.1 Crearea manuală a tabelelor................................................................................................182.2.2 Datasheet View: avantaje.....................................................................................................182.2.3 Design View: .......................................................................................................................192.2.4 Definirea coloanelor.............................................................................................................202.2.5 Stabilirea proprietăţilor câmpurilor.....................................................................................212.2.6 Lookup wizard......................................................................................................................232.2.7 Value List..............................................................................................................................27 2.2.8 Definirea cheilor primare şi a indecşilor..............................................................................282.2.9 Crearea unei tabele folosind experţii Access......................................................................30

2.3 STABILIREA RELAŢIILOR   ÎNTRE  TABELE.............................................................................................302.3.1. Fereastra Relationships.......................................................................................................302.3.2 Crearea relaţiilor dintre tabele............................................................................................322.3.3 Proprietăţile relaţiilor..........................................................................................................342.3.4. Tipuri de asociere................................................................................................................342.3.5 Asigurarea integrităţii referenţiale.......................................................................................36 2.3.6. Modificarea relaţiilor existente...........................................................................................36 2.4.1 Importul datelor...................................................................................................................36 2.4.2 Exportul datelor....................................................................................................................37 2.4.3. Formate standard................................................................................................................38

CAP:3. INTEROGĂRI.............................................................................................................................393.1. FOLOSIREA FERESTREI QBE.............................................................................................................39

3.1.1. Specificarea surselor de date...............................................................................................403.1.2. Proprietăţile interogărilor...................................................................................................40

3.2. TIPURI DE INTEROGĂRI.....................................................................................................................433.2.1. Interogări agregat...............................................................................................................433.2.2. Interogări de tip totals ........................................................................................................433.2.2.1 Sortarea rezultatelor unei interogări de tip totals..............................................................46 3.2.2.2 Stabilirea criteriilor..........................................................................................................47 3.2.3. Interogări de tip Crosstab ...................................................................................................48

3.2.3.1 Crearea totalurilor pe linii................................................................................................493.2.3.2 Limitările intergărilor Crosstab........................................................................................503.2.4. Interogări pentru definirea şi modificarea datelor..............................................................513.2.4.1. Interogări de tip Make Table............................................................................................51

Pag. 292

Page 288: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 288/295

3.2.5. Interogări de tip Append.....................................................................................................523.2.6 Interogări de tip Update.......................................................................................................523.2.7 Interogări de tip Delete.......................................................................................................533.2.8 Interogări cu parametri.......................................................................................................53

3.3. EXPRESII ŞI FUNCŢII ÎN INTEROGĂRI....................................................................................................533.3.1. Părţile componente ale expresiilor......................................................................................54Operatori.......................................................................................................................................54Constante.......................................................................................................................................55

 Funcţii...........................................................................................................................................56 3.4. LUCRUL CU DATE ŞI ORE..................................................................................................................563.5. FUNCŢIA IIF ÎN EXPRESII.................................................................................................................583.6. STRATEGII DE PARCURGERE A TABELELOR  DE BAZĂ..............................................................................583.7. GREŞELI FRECVENTE........................................................................................................................593.8. IMPORTANŢA COMPACTĂRII...............................................................................................................60

CAP: 4. CREAREA ŞI LUCRUL CU FORMULARELE...................................................................61

4.1 SURSELE DE ÎNREGISTRĂRI ALE FORMULARELOR ....................................................................................61

4.2. CREAREA UNUI FORMULAR  SIMPLU.....................................................................................................624.3. SECŢIUNILE UNUI FORMULAR ...........................................................................................................644.4. LUCRUL CU FORMULARELE...............................................................................................................664.5. DESPRE CONTROALE........................................................................................................................68

4.5.1. Tipuri de controale..............................................................................................................69Controale neataşate.......................................................................................................................69Controale ataşate..........................................................................................................................69Controale calculate.......................................................................................................................704.5.2. Casete combinate, casete listă şi grupuri de opţiuni............................................................70

FIGURA IV.10 ...................................................................................................................................73

4.6. SUBFORMULARE..............................................................................................................................73CAP: 5. MODELUL ORIENTAT PE EVENIMENTE........................................................................75

...........................................................................................................................................................765.1. TIPURI DE EVENIMENTE ÎN ACCESS....................................................................................................76

5.1.1. Evenimente generate de accesarea datelor..........................................................................76 5.1.2. Evenimente legate de focus..................................................................................................785.1.3. Evenimente legate de tastatură............................................................................................795.1.4. Evenimente legate de activitatea cu mouse-ul......................................................................795.1.5. Evenimente legate de tipărire..............................................................................................805.1.6. Evenimentele ferestrelor......................................................................................................81

5.1.7. Evenimente generate de erori..............................................................................................825.1.8. Evenimentele legate de timer...............................................................................................82

5.2. ORDINEA PRODUCERII EVENIMENTELOR  ÎN ACCESS...............................................................................825.2.1. Ordinea producerii evenimentelor legate de controale........................................................825.2.2. Ordinea producerii evenimentelor legate de lucrul cu înegistrările unui formular.............835.2.3 Ordinea producerii evenimentelor legate de formulare........................................................835.2.4. Ordinea producerii evenimentelor legate de tastatură şi mouse..........................................845.2.5. Ordinea producerii evenimentelor rapoartelor....................................................................85

5.3. TRATAREA EVENIMENTELOR  .............................................................................................................85

.....................................................................................................................................................................86

CAP:6. MACROCOMENZI....................................................................................................................86

6.1. CREAREA UNEI MACROCOMENZI.........................................................................................................87

Pag. 293

Page 289: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 289/295

6.2. GRUPURI DE MACROCOMENZI............................................................................................................88Grupurile de macrocomenzi sunt utile, de exemplu, atunci când doriţi să păstraţi toatemacrocomenzile unui formular în acelaşi obiect, astfel încât numărul obiectelor din pagina

 Macro a ferestrei Database să fie mai mic. Pe de altă parte, o macrocomandă poate apela altămacrocomandă în cadrul unei condiţii, caz în care veţi prefera să le includeţi pe amândouă înacelaşi obiect, pentru a fi mai simplu de depanat..........................................................................89O macrocomandă din grup poate fi executată utilizând numele grupului, urmat de un punct şi denumele macrocomenzii:.................................................................................................................89

6.3. MACROCOMENZI IMBRICATE.............................................................................................................896.3.1. Condiţii în macrocomenzi....................................................................................................90

6.4. MACROCOMENZI SPECIALE................................................................................................................906.4.1. Macrocomanda AutoKeys....................................................................................................906.4.2. Macrocomanda AutoExec....................................................................................................926.5. Crearea meniurilor şi a barelor cu instrumente personalizate...............................................936.6. Rularea şi depanarea macrocomenzilor.................................................................................95

CAP:7. VISUAL BASIC FOR APPLICATIONS (VBA).....................................................................97

7.1 MEDIUL DE PROGRAMARE ACCESS.....................................................................................................97Ce conţin modulele........................................................................................................................97 (General).......................................................................................................................................98Opţiuni..........................................................................................................................................98

 Declaraţii (Declarations)..............................................................................................................99 Proceduri pentru tratarea evenimentelor......................................................................................99

7.2 PROCEDURI.....................................................................................................................................997.2.1 Declararea procedurilor.......................................................................................................997.2.2. Lucrul cu argumente opţionale..........................................................................................1017.2.3. Funcţii predefinite.............................................................................................................101

7.3. VARIABILE...................................................................................................................................102

7.3.1 Tipuri de date.....................................................................................................................1027.3.2 Declararea variabilelor......................................................................................................1037.3.2.2 Option Explicit.................................................................................................................106 7.3.3 Constante............................................................................................................................107 7.3.4 Vizibilitatea şi durata de viaţă a variabilelor.....................................................................1087.3.4.1 Variabile statice...............................................................................................................1097.3.4.2 Variabile publice.............................................................................................................110

7.4. I NSTRUCŢIUNI DE CONTROL.............................................................................................................1137.4.1 Instrucţiunea If…Then........................................................................................................1137.4.2 Instrucţiunea If…Then…Else..............................................................................................1147.4.3 Instrucţiunea ElseIf.............................................................................................................115

7.4.4 Instrucţiunea Select Case....................................................................................................1157.4.5 Instrucţiunea IIf (Immediate If)...........................................................................................116 

7.5 I NSTRUCŢIUNI ITERATIVE.................................................................................................................1177.5.1 Instrucţiunea For…Next.....................................................................................................117 7.5.2 Instrucţiunea Do…Loop.....................................................................................................1187.5.3 Întreruperea iterării............................................................................................................119

7.6 MATRICE......................................................................................................................................1197.6.1 Matrice statice....................................................................................................................119

 Indici...........................................................................................................................................1227.6.2 Matrice dinamice................................................................................................................1227.6.3 Detectarea matricelor ........................................................................................................1237.6.4 Matrice multidimensionale.................................................................................................1257.6.4.1 Matrice multidimensionale dinamice...............................................................................1257.6.4.2 Accesarea componentelor unei matrice multidimensionale ............................................126 

Pag. 294

Page 290: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 290/295

7.6.5 Ştergerea matricelor dinamice............................................................................................127 7.6.6 Folosirea matricelor ca parametri pentru proceduri..........................................................1287.7 Lucrul cu biblioteci DLL şi cu funcţii Windows API..............................................................1297.7.1 Declararea funcţiilor API...................................................................................................1297.7.1.1 Domeniul de vizibilitate al funcţiei API...........................................................................1307.7.1.2 Denumirea funcţiei API...................................................................................................1307.7.1.3 Specificarea bibliotecii DLL............................................................................................1307.7.1.4 Clauza Alias.....................................................................................................................1307.7.1.5 Argumente........................................................................................................................131Şiruri de caractere ca argumente................................................................................................131

 Matrice ca argumente..................................................................................................................132Transformarea tipurilor de date ale argumentelor......................................................................132Tipuri-utilizator...........................................................................................................................132

 Pointeri nuli.................................................................................................................................133

CAP:8. LUCRUL CU OBIECTE..........................................................................................................134

 Proprietăţi...................................................................................................................................134

 Metode ........................................................................................................................................134Clase............................................................................................................................................1358.1 OBIECTELE DIN ACCESS 97.............................................................................................................135

 Application..................................................................................................................................135Container.....................................................................................................................................1358.1.1 Colecţii...............................................................................................................................136 Obiectul DBEngine (motorul Jet Engine)....................................................................................139Colecţia Errors (Erori)................................................................................................................139Colecţia Workspaces (Sesiuni de lucru)......................................................................................139Colecţia Databases (Baze de date)..............................................................................................139Colecţia Users (Utilizatori).........................................................................................................140

Colecţia Groups (Grupuri)..........................................................................................................140Colecţia QueryDefs (Interogări).................................................................................................140Colecţia TableDefs (Tabele)........................................................................................................140Colecţia Indexes (Indecşi)...........................................................................................................140Colecţia Fields (Câmpuri)...........................................................................................................140Colecţia Recordsets (Seturi de înregistrări)................................................................................140Colecţia Relations (Relaţii).........................................................................................................141Colecţia Parameters (Parametri)................................................................................................141Colecţia Properties (Proprietăţi).................................................................................................1418.1.2 Containere şi documente....................................................................................................141

8.2 LUCRUL CU VARIABILE DE TIP OBIECT...............................................................................................142

Când folosim semnul exclamării (!) şi când punctul (.)...............................................................1448.3 COLECŢII IMPLICITE........................................................................................................................144

Container.....................................................................................................................................1448.4 LUCRUL CU PROPRIETĂŢILE OBIECTELOR ............................................................................................145

8.4.1 Tipuri de proprietăţi...........................................................................................................1458.4.2. Accesul la proprietăţi........................................................................................................145....................................................................................................................................................1458.4.3. Stabilirea proprietăţilor.....................................................................................................145

8.5. CREAREA ŞI MANIPULAREA OBIECTELOR  CU DAO.............................................................................1468.5.1. Crearea obiectelor.............................................................................................................146 8.5.1.1. Crearea unei tabele........................................................................................................1488.5.1.2 Crearea unui index..........................................................................................................1488.5.1.3 Crearea unei relaţii.........................................................................................................1518.5.1.4. Crearea proprietăţilor-utilizator....................................................................................152

Pag. 295

Page 291: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 291/295

8.5.2. Modificarea obiectelor......................................................................................................1538.6. OBIECTE DEFINITE DE UTILIZATOR ....................................................................................................153

8.6.1. Proprietăţile şi metodele obiectului...................................................................................1538.6.2 Crearea instanţelor obiectului............................................................................................157 8.6.3. Durata de viaţă a obiectelor..............................................................................................158

8.7 LUCRUL CU OBIECTE DE TIP R ECORDSET............................................................................................1588.7.1. Tipuri de seturi de înregistrări...........................................................................................1608.7.1.1. Seturi de înregistrări de tip tabelă..................................................................................1618.7.1.2. Seturi de înregistrări de tip dynaset................................................................................1618.7.1.3. Seturi de înregistrări de tip snapshot..............................................................................1628.7.2. Actualizarea datelor unui set de înregistrări ....................................................................1628.7.3. Parcurgerea seturilor de înregistrări ...............................................................................1638.7.4. Regăsirea numărului de înregistrări ale unui set de înregistrări ......................................1638.7.5. Poziţia absolută şi poziţia procentuală..............................................................................1648.7.6. Poziţiile de început şi de sfârşit ale setului de înregistrări (BOF şi EOF).........................1648.7.7. Regăsirea valorilor câmpurilor unui set de înregistrări ...................................................1658.7.8. Căutarea înregistrărilor....................................................................................................167 

8.7.8.1. Căutări în seturi de înregistrări de tip tabelă.................................................................167 8.7.8.2. Căutări în seturi de înregistrări de tip dynaset şi snapshot............................................1688.7.8.3. Criterii ce conţin şiruri de caractere şi date...................................................................1708.7.9 Semne de carte....................................................................................................................1718.7.10 Metoda Clone (clonare)....................................................................................................1728.7.11 Proprietatea RecordsetClone ...........................................................................................1728.7.12 Sortarea şi filtrarea unui set de înregistrări.....................................................................1738.7.13 Editarea înregistrărilor unui set de înregistrări...............................................................1758.7.13.1. Modificarea înregistrării curente.................................................................................176 8.7.13.2 Adăugarea unei noi înregistrări la un set de înregistrări..............................................176 8.7.13.3 Ştergerea unei înregistrări a unui set de înregistrări.....................................................177 

8.8. OBIECTE SPECIALE........................................................................................................................177CAP:9. CREAREA ŞI LUCRUL CU RAPOARTELE......................................................................178

9.1 CREAREA UNUI RAPORT...................................................................................................................1799.1.1. Crearea rapoartelor cu ajutorul programelor Wizard.......................................................1799.1.2. Crearea manuală a rapoartelor ........................................................................................183

9.2. SURSA DE DATE A RAPORTULUI.......................................................................................................1839.3. SECŢIUNILE UNUI RAPORT...............................................................................................................1849.4. PROPRIETĂŢILE UNUI RAPORT..........................................................................................................1859.5. SORTAREA ŞI GRUPAREA DATELOR ...................................................................................................1869.6. FOLOSIREA FUNCŢIILOR  AGREGAT ÎN CADRUL RAPOARTELOR ................................................................188

9.7. EDITAREA RAPOARTELOR ................................................................................................................189CAP:10. FOLOSIREA DATELOR EXTERNE.................................................................................191

10.1 COPIEREA ÎN SAU DIN ALTE APLICAŢII..............................................................................................19110.1.1 Baze de date......................................................................................................................19110.1.2 Foi de calcul tabelar........................................................................................................19410.1.3 Fişiere de text...................................................................................................................196 10.1.4 Fişiere de text cu caractere delimitatoare........................................................................197 10.1.5 Fişiere de text cu lăţime fixă.............................................................................................198

10.2 COMPUNEREA MESAJELOR  POŞTALE.................................................................................................19810.3 EXPORTUL ALTOR  OBIECTE............................................................................................................19910. 4 POŞTA ELECTRONICĂ...................................................................................................................20110.5 DATE EXTERNE............................................................................................................................20310.6 TABELE LEGATE...........................................................................................................................204

Pag. 296

Page 292: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 292/295

 Diferenţe între tabelele legate şi cele locale................................................................................207 10.7 ODBC......................................................................................................................................208

CAP: 11.TRATAREA ERORILOR, DEPANAREA ŞI TESTAREA .............................................209

11.1 A NTICIPAREA ERORILOR ................................................................................................................209PROIECTUL.........................................................................................................................................209

Tabele..........................................................................................................................................210 Interogări....................................................................................................................................210 Formulare şi rapoarte ................................................................................................................211Gruparea funcţiilor.....................................................................................................................211

11.3 TEHNICI ORIENTATE PE OBIECT PENTRU PREVENIREA APARIŢIEI ERORILOR ..............................................211 Încapsularea................................................................................................................................211 Refolosirea..................................................................................................................................212Comanda Option Explicit............................................................................................................212Verificarea sintaxei.....................................................................................................................213Comentarii ..................................................................................................................................213

11.4 TESTAREA .................................................................................................................................214

Testarea funcţională....................................................................................................................214Testarea modului de utilizare......................................................................................................214Testarea distructivă.....................................................................................................................215

 Întreţinerea..................................................................................................................................21511. 5 TIPURI DE ERORI.........................................................................................................................215

 Erori de sintaxă...........................................................................................................................216  Erori de execuţie.........................................................................................................................217  Erori de semantică......................................................................................................................218 Alte erori.....................................................................................................................................223

11.6. DEPANAREA .............................................................................................................................223 Execuţia programului..................................................................................................................224

 Puncte de întrerupere..................................................................................................................224Continuarea execuţiei..................................................................................................................224Stoparea execuţiei.......................................................................................................................224

 Reiniţializarea execuţiei..............................................................................................................225 Execuţia codului pas cu pas.........................................................................................................225 Repetarea execuţiei liniei de cod.................................................................................................226 Saltul peste liniile de cod.............................................................................................................226 

 Modificarea codului....................................................................................................................226 Stiva de apeluri............................................................................................................................227 

 Fereastra de depanare (Debug)...................................................................................................227  Elemente de urmărire..................................................................................................................228

11.7 UTILIZAREA SISTEMULUI DE ASISTENŢĂ (HELP)................................................................................233Tratarea erorilor.........................................................................................................................236 

 Erori în Visual Basic...................................................................................................................237 Utilizarea instrucţiunilor Exit Function şi Exit Sub în rutinele de tratare a erorilor...................243

 Erori în formulare şi rapoarte.....................................................................................................244 Erori DAO...................................................................................................................................244 Erori definite de utilizator...........................................................................................................245Stiva de erori...............................................................................................................................246 

11.7 DEPANAREA CODULUI DE DEPANARE...............................................................................................251Controlul de versiune..................................................................................................................251Controlul de versiune în Access 97..............................................................................................252Visual SourceSafe........................................................................................................................252

 Programul de completare Access SourceSafe..............................................................................253

Pag. 297

Page 293: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 293/295

CAP: 12.OPTIMIZAREA BAZEI DE DATE.....................................................................................255

12.1 EFICIENŢA .................................................................................................................................25512.2 R EDUCEREA SUPRAÎNCĂRCĂRII MEMORIEI.........................................................................................256

12.2.1 Alegerea corectă a tipurilor de date.................................................................................25812.2.2 Gruparea procedurilor în module.....................................................................................25912.2.3 Eliminarea comentariilor şi secvenţelor de cod inutile.....................................................259

12.2.4. Eliberarea memoriei ori de câte ori este posibil..............................................................26012.2.5 Nu încărcaţi în memorie module / biblioteci care nu sunt necesare..................................26012.2.6 Salvarea bazei de date ca fişier MDE...............................................................................26012.2.7 O ultimă recomandare - cumpăraţi mai multă memorie...................................................261

12.3 CREŞTEREA VITEZEI DE EXECUŢIE...................................................................................................26112.3.1 Cronometrarea execuţiei codului......................................................................................26212.3.2 Folosirea constante..........................................................................................................26512.3.3 Folosiţi tipuri specifice de obiecte (asociere iniţială).......................................................26512.3.4 Folosiţi variabile, nu proprietăţi......................................................................................266 12.3.5 Folosiţi funcţii şir.............................................................................................................267 12.3.6 Evitaţi folosirea structurilor lente.....................................................................................268

12.3.8.Folosiţi operaţii aritmetice cu întregi ori de câte ori este posibil.....................................26912.3.9 Folosiţi cod in-line............................................................................................................26912.3.10 Folosiţi structura For Each….........................................................................................27012.3.11 Folosiţi judicios instrucţiunea DoEvents........................................................................27112.3.12 Folosiţi metoda Requery, nu acţiunea Requery...............................................................27212.3.13 Folosiţi cuvântul cheie Me..............................................................................................273

12.4 CREŞTEREA VITEZEI DE EXECUŢIE A OPERAŢIILOR  CU BAZA DE DATE.....................................................27312.4.1 Folosiţi indexuri..............................................................................................................27312.4.2. Folosiţi semne de carte....................................................................................................27412.4.3. Folosiţi ca sursă pentru formulare interogări salvate.....................................................274

12.5. CREŞTEREA VITEZEI APARENTE......................................................................................................27512.5.1 Un formular simplu de început.........................................................................................27512.5.2 Folosiţi indicatoare care ilustrează progresul operaţiei...................................................276 12.5.3 Ştergeţi codul din modulele de formulare.........................................................................277 12.5.4 Preîncărcaţi şi ascundeţi formularele...............................................................................277 12.5.5. Stocaţi datele în memoria locală......................................................................................27812.5.6. Consideraţii referitoare la lucrul în reţea........................................................................278

12.6. ULTIMELE RETUŞURI....................................................................................................................27912.6.1 Compactarea bazei de date...............................................................................................28012.6.2 Compilarea tuturor modulelor..........................................................................................28012.6.3 Deschiderea bazelor de date în mod exclusiv...................................................................281

12.7 R EZUMAT

...................................................................................................................................281CAP: 13 .INTERNET.............................................................................................................................283

13.1 CE ESTE I NTERNETUL?..................................................................................................................28313.2 PROTOCOALE...............................................................................................................................28413.3 DATE DE TIP HIPERLEGĂTURĂ (HYPERLINK ).....................................................................................28413.4. CUM SE UTILIZEAZĂ HIPERLEGĂTURILE?.........................................................................................28513.5 HIPERLEGĂTURI ÎN VBA..............................................................................................................28613.6. PUBLICAREA ÎN WEB...................................................................................................................286

13.6.1 Documente HTML statice ................................................................................................286 13.6.2 Aplicaţia wizard HTML Export.........................................................................................287 

13.6.3 Internet Data Connector...................................................................................................287 13.6.4.Active Server Pages..........................................................................................................28813.7. CREAREA UNUI BROWSER .............................................................................................................290

Pag. 298

Page 294: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 294/295

13.8.R EZUMAT...................................................................................................................................291

INTODUCERE........................................................................................................................................300

Pag. 299

Page 295: Curs Baze de Date

7/12/2019 Curs Baze de Date

http://slidepdf.com/reader/full/curs-baze-de-date-55a92bd686df4 295/295