Obiecte de tip modul
Daca tabelele, interogarile, formularele si rapoartele reprezinta componentele principale ale unei baze de date Access, modulele constituie liantul care le uneste.
Modulele sunt fuctii si subrutine scrise în limbajul standard Visual Basic for Applications (VBA). Ele asigura toate functionalitatile unei baze de date; în majoritatea aplicatiilor de baze de date, au loc foarte multe actiuni pe care nu le vedeti pe ecran. Calculele, validarea datelor, efectele grafice si comunicatia între obiectele bazei de date sunt tratate, de obicei, de secvente de cod scrise special pentru aceste operatii si memorate în module.
Practic, prin includerea modulelor de cod într-o baza de date, aceasta se transforma dintr-un depozit de stocare a informatiilor într-o aplicatie, într-un mediu în care utilizatorul efectueaza operatii cu date.
Începând cu MicroSoft Office 95, toate aplicatiile Office (Word, Excel, Access, etc) folosesc un limbaj comun, denumit VBA, care este adaptat corespunzator caracteristicilor fiecarei aplicatii. De exemplu, în VBA sub Word, se pot scrie de obicei secvente de cod care au efect asupra unui bloc de text selectat; conceptul de text selectat nu are nici o relevanta în Access, fiind specific aplicatiei Word.
Desi, modul general de lucru cu limbajul VBA este acelasi în toate aplicatiile Office, mediul de programare nu este chiar standard. Cu exceptia programului Access, toate aplicatiile bazate pe limbajul VBA utulizeaza pentru scrierea modulelor de cod un mediu de programare standard, numit Visual Basic Editor. Mediul de programare din Access este putin diferit, si este numit Code Builder.
Desi în fereastra Database din Access avem doar o singura eticheta numita Modules, exista doua tipuri de module Access:
Module standard - sunt programe de sine statatoare, carora li se atribuie nume si pot exista independent de orice alt obiect din baza de date; acestea pot fi gestionate si editate din fereastra Database, toate aparând în pagina Modules;
Module de clasa - sunt module asociate cu alte obiecte din baza de date (formulare sau rapoarte) sau cu controale din aceste abiecte. Un modul care efectueaza o actiune dupa ce utilizatorul executa Click pe un buton de comanda dintr-un formular, este implementat, de obicei, ca modul de clasa asociat cu butonul de pe formular. Modulele de clasa nu sunt afisate în fereastra Database.
Pentru a vizualiza un modul de clasa asociat cu un formular, raport, tabel sau interogare:
se deschide obiectul respectiv în modul Design;
se selecteaza optiunea Code din meniul View.
Daca modulul este asociat unui control al unui formular sau raport:
se deschide formularul sau raportul respectiv în modul Design si se selecteaza controlul respectiv;
se deschide fereastra Properties a controlului respectiv (View / Properties) si se selecteaza eticheta Event; daca lânga un nume de eveniment apare expresia [Event Procedure] înseamna ca exista module de clasa asociate cu evenimentul corespunzator acelui control; pentru a vizualiza codul asociat cu o procedura se executa Click pe butonul Builder care apare alaturi (.).
Un modul este o colectie de declaratii si proceduri (de tip Function sau Sub) VBA, descrise împreuna ca un întreg.
Pentru a crea un modul, în fereatra Database, eticheta Modules, se actioneaza butonul New. Spre deosebire de celelalte obiecte ale unei baze de date, în cazul modulelor nu avem la dispozitie un program expert, si rezultatul va fi deschiderea unei ferestre Code Builder (Generator de cod) libera. Aceasta contine doua sectiuni:
de declaratii (Declarations);
procedurilor (Procedures).





Sectiunea Declarations (de declaratii) contine instructiuni care configureaza optiunile globale pentru acel modul si comunica programului Access tipul datelor fiecarei variabile folosite în cod. Instructiunile de dimensionare a varabilelor (Dim, care declara tipul oricarei variabile pe care o folositi) plasate în aceasta sectiune sunt disponibile pentru orice procedura din acest modul; daca instructiunile Dim sunt plasate în interiorul unei proceduri, variabila nu poate fi folosita decât în cadrul procedurii respective. Instructiunile Options (de optiuni) sunt declarate tot în aceasta sectiune deoarece sunt necesare pentru a determina cum va fi rulat modulul.
Pentru a adauga optiuni (instructiuni) noi, plasati cursorul în aceasta sectiune (care este delimitata în partea de jos de o bara orizontala) si începeti sa tastati. Programul Access nu va permite sa introduceti aici cod de procedura (instructiuni care executa o actiune) ci doar instructiuni care configureaza dimensiunea unor variabile sau anumite optiuni.
Sectiunea Procedures (proceduri) este cea în care introduceti codul propriu-zis prin tastarea instructiunilor dorite.
Caseta Object este o caseta combinata cu lista derulanta, continând numele obiectelor sau controalelor din obiecte care pot avea cod asociat. Aveti posibilitatea sa vizualizati modulele de clasa asociate cu diferite obiecte sau controale. În lista derulanta vor aparea toate controalele din formulare sau rapoarte, permitîndu-va sa introduceti o secventa de cod noua sau sa editati codul existent pentru orice control din formular sau raport. În modulele standard, aceasta caseta nu contine decât o intrare denumita General.
Caseta Procedure contine lista ordonata alfabetic a tuturor subrutinelor sau functiilor definite pâna în momentul respectiv în modulul curent (indiferent daca este standard sau de clasa). Aici apare si sectiunea Declarations. Daca selectati o procedura în aceasta caseta, ajungeti rapid la instrunctiunea de început a procedurii respective, pe care puteti sa o vizualizati sau sa o editati. Aceasta lista contine doar procedurile din modulul curent (fie el de clasa sau standard).
Butoanele Procedure View si Module View schimba modul de afisare a codului în fereastra Code Builder. Prima, optiune implicita, afiseaza într-o singura lista toate procedurile (declaratii, functii, subrutine) din modulul curent. Executia unui Click pe al doilea buton, are ca efect comutarea în modul de afisare Module View, ce determina listarea fiecarei proceduri într-o sectiune separata, la care se poate ajunge prin selectarea procedurii individuale în caseta Procedure.
Programul Access coloreaza automat codul VBA pe baza urmatoarelor reguli:
text albastru - reprezinta cuvinte rezervate în Access, cum ar fi: Function, True, If, etc; majoritatea liniilor dintr-o procedura încep cu un cuvânt rezervat sau cu un nume de functie recunoscut de Access;
text negru - caracterizeaza corpul codului (instructiuni obisnuite);
text verde - evidentieaza comentariile introduse de programator pentru a prezenta scopul unei anumite secvente de cod; în limbajul VBA puteti sa creati comentarii inserând un apostrof (') înaintea unui fragment oarecare de text, text ce va fi ignorat de compilatorul Access;
text rosu - contine erorile care nu pot fi interpretate de compilatorul Access, cum ar fi comenzile scrise gresit sau instructiunile incomplete; în mod implicit, programul Access cauta aceste tipuri de erori în timp ce introduceti textul de la tastatura si va avertizeaza când faceti o asemenea eroare de sintaxa; textul respectiv ramâne colorat în rosu pâna la corectarea erorii; aceasta verificare se seteaza sau deseteaza din meniul Tools / Options / Module optiunea AutoSintaxCheck.
Întregul cod VBA este scris în proceduri - blocuri (secvente) de cod, cu început si sfârsit bine determinat. În cadrul modulelor, procedurile sunt de sine statatoare; nu se pot imbrica. Totusi, un cod bine scris, consta, în general, din mai multe proceduri scurte, usor de înteles, care se apeleaza între ele. Acest tip de programare poarta numele de programare modulara, iar codul este usor de înteles si de întretinut.
În Access, majoritatea actiunilor pe care doriti sa le programati sunt simple si clare. De exemplu, puteti sa scrieti o secventa de cod pentru configurarea proprietatilor unui formular sau pentru salvarea rezultatelor unei interogari într-un tabel. Daca este posibil, limitati lungimea procedurilor, astfel încât acestea sa nu ocupe mai mult de un ecran atunci când sunt afisate în fereastra Code Builder. Uneori, aceasta cerinta este imposibil de îndeplinit, dar, în general, veti putea împarti codul în proceduri care sa încapa (fiecare în parte) pe un ecran.
Înainte de a începe scrierea propriu-zisa a codului, este bine sa îl planificati folosind pentru organizarea procedurilor stilul denumit pseudocod.
Exemplu:
Sa se scrie un program care sa instruiasca un robot sa cumpere alimente de la magazin. Pentru a programa robotul, mai întâi trebuie sa va organizati tot procesul în minte, apoi scrieti pe scurt, actiunile efective pe care ar trebui sa le execute robotul:
Actiuni principale:
mergi_la_magazin
cumpara_alimente
vino_acasa
Fiecare actiune principala contine mai multe actiuni secundare:
mergi_la_magazin
scrie_lista_cumparaturi
urca_în_masina
condu_pâna_la_magazin
cumpara_alimente
intra_în_magazin
cauta_alimentele_din_lista
plateste
iesi_din_magazin
vino_acasa
urca_în_masina
condu_pâna_acasa
descarca_alimente
Detaliind si mai mult aceste actiuni, veti ajunge la nivelul la care puteti sa scrieti instructiuni în limbajul de programare al robotului, obtinând codul care determina executia efectiva a actiunilor.
În VBA exista doua tipuri de proceduri:
Acestea sunt proceduri care nu returneaza nici o valoare. Ele au un început bine definit (o instructiune Sub) si un sfârsit bine definit (o instructiune EndSub); subrutinele pot avea parametri (argumente), numele si tipul acestora se scriu pe prima linie a subrutinei; sintaxa pentru scrierea unei subrutine este:
[Static] [Private] Sub nume_proc [(lista_argumente)]
<instructiuni>
[Exit Sub]
<instructiuni>
EndSub
unde
Static - variabilele locale sunt memorate între doua executii:
Private - procedura este accesata numai din interiorul modulului curent;
lista_argumente - lista variabilelor transmise în momentul apelarii procedurii;
Exit Sub - forteaza iesirea din subrutina.
Apelul unei subrutine se realizeaza pe structura:
[Call] nume_proc([lista_argumente])
Nota: cuvintele scrise cu litere italice sunt cuvinte rezervate de programul Access, cele scrise între paranteze patrate sunt optionale.
Exemplu Sub condu (destinatie as string)
Acestea sunt proceduri care returneaza o valoare procedurii care le-a apelat; ele au un început (o instructiune Function) si un sfârsit (End Function) bine definit; prima linie a unei functii defineste, de obicei, tipul de data al valorii pe care o va returna; functiile pot avea parametri, incluzând numele si tipul parametrului pe prima linie a functiei; sintaxa pentru scrierea unei functii este:
[Static] [Private] Function nume_proc [(lista_argumente)] [As Tip_data]
<instructiuni>
[Exit Function]
<instructiuni>
EndFunction
unde
As Tip_data - indica tipul rezultatului returnat de catre functie.
Exemplu Function condu (destinatie as string) as Boolean
În limbajul VBA, fiecare dintre liniile din schita de pseudocod poate reprezenta o procedura, deoarece se presupune ca foloseste codul care efectueaza o anumita actiune.
Sintaxa VBA este destul de cpmplicata, dar Access pune la dispozitia utilizatorului un sistem de asistenta (Help) on-line foarte cuprinzator si util. Pentru a afla informatii despre un cuvânt cheie sau o metoda VBA, scrieti cuvântul respectiv în fereastra Code Builder si apasati tasta F1 pentru a afisa textul de asistenta în context.
Pentru crearea unei proceduri (functii sau subrutine), procedati astfel:
În sectiunea Procedures a ferestrei Code Builder, scrieti
Sub (Function) nume_proc
Access va insera automat o linie orizontala înainte de declaratia procedurii si introduce automat instructiunea End Sub, respectiv End Function pe alta linie.
Scrieti în sectiunea Declarations declaratiile de variabile si optiunile.
Introduceti instructiunile codului propriu-zis între instructiunea Sub (Function) si End Sub (End Function).
Pentru a salva un modul standard, selectati optiunea Save din meniul File. Access va cere un nume, care apare apoi în fereastra Database, eticheta Modules.
Pentru a salva un modul clasa, salvati obiectul la care acesta este atasat. În ambele cazuri se poate folosi butonul Save din bara de butoane standard.
Care este diferenta dintre o subrutina si o functie?
Unele proceduri din schita de pseudocod prezentata anterior nu asteapta un ranspuns (feedback). De exemplu, sa presupunem ca procedura scrie_lista_de_cumparaturi va fi executata întotdeauna cu succes si, prin urmare, poate fi implementata ca subrutina. Dar ce se va întâmpla daca masina nu va porni? În acest caz, nu puteti face cumparaturile. Deci, va trebui sa implementam aceasta procedura ca o functie, adica o procedura care returneaza o valoare. Functia condu_pâna_la_magazin va returna valoare True daca ajungeti cu bine la magazin si False daca se întâmpla ceva si nu ajungeti la destinatie. În cazul în care procedura condu_pâna_la_magazin returneaza valoare False, va puteti opri în acel punct - drumul s-a terminat.
Transmiterea parametrilor în proceduri
În schita de pseudocod exista doua linii care difera foarte putin: condu_pâna_acasa si condu_pâna_la_magazin. Este vorba de aceeasi activitate, dar care are destinatii diferite. În majoritatea limbajelor de programare, aceasta trebuie implementata ca o functie sau subrutina cu parametru specificat la început, servind la transmiterea informatiilor de care are nevoie pentru o executie corecta. În mod obisnuit, scrieti parametri între paranteze, dupa numele procedurii, astfel ca acestea devin:
condu (magazin)
si
condu (acasa)
Puteti scrie o procedura condu, care sa astepte la apelare specificarea unei destinatii. Aceasta va include o variabila corespunzatoare destinatiei si va dace întotdeauna referire la destinatie prin numele variabilei, si nu dupa numele propriu-zis al destinatiei. În acest fel, procedura nu trebuie scrisa decât o singura, iar programul o poate folosi pentru orice destinatie.
Se obisnuieste utilizarea unor functii cu parametri, mai ales în cazul în care sunt folosite pentru efectuarea unor calcule.
Sa luam ca exemplu o procedura ce calculeaza pretul unor produse din cosul de cumparaturi:
Option Explicit /* declararea variabilelor*/
Dim id_produs, produs_în_cos As Integer
Dim cost_total, taxa, total As Currency
Sub plateste ()
While (produse_în_cos >0)
id_produs=ridica_produs
cost_total=cost_total+cost(id_produs) /*functie cu parametru*/
împacheteaza_produs
produse_în_cos= produse_în_cos-1
Wend
taxa = calculeaza_taxa (cost_total)
total = cost_total + taxa
End Sub
Function ridica_produs() As Integer
End Function
Function cost (ByVal id As Integer) As Currency
End Function
Sub împacheteaza_produs() As Currency
End Sub
Function calculeaza_taxa (ByVal baza As Currency) As Currency
End Function
Linia 1 - exista mai multe optiuni pe care le puteti configura pentru a schimba modul în care Access interpreteaza codul. Instructiunea Option Explicit, inclusa în mod implicit de Access, va obliga sa declarati tipul tuturor variabilelor folosite, ceea ce, oricum, este un bun obicei.
Linia 2 si 3 - instructiunea Dim (dimensiune) comunica interpretorului ce variabile intetionati sa folositi, astfel încât acesta sî poata rezerva spatiul de stocare necesar în memoria calculatorului; în acest caz, am declarat doua variabile de tip întreg si trei variabile de tip monetar (Currency), care sunt, de fapt, numere în virgula mobila cu doua zecimale.
Linia 4 - instructiunea Sub începe o subrutina. Parantezele goale sunt inserate automat de Access pentru a evidentia faptul ca aceasta subrutina nu are parametri.
Linia 5 While este un cuvânt cheie VBA care initiaza un ciclu de instructiuni. Aceasta structura ciclica, care începe la linia 5 si se termina cu instructiunea Wend de pe linia 10, va fi executata cât timp conditia specificata (produse_în_cos >0) este adevarata. Presupunem ca numarul de produse din cos a fost calculat anterior si ca valoarea a fost memorata în variabila produse_în_cos. Atunci când nu mai exista nici un produs în cos, variabila produse_în_cos va avea valoarea zero, iar executia va continua dupa instructiunea Wend. Este bine sa indentati liniile care formeaza blocul de instructiuni dintr-un ciclu, pentru a evidentia faptul ca sunt grupate.
Linia 6 - atribuie valoarea returnata de functia ridica_produs variabilei id_produs. Functia ridica_produs ar trebui sa faca o mica vrajitorie, adica sa ia produsul din cos si sa-l identifice, apoi sa returneze numarul de identificare al produsului catre procedura apelanta.
Linia 7 - foloseste functia cost pentru a cauta pretul produsului selectat de robot din cos. Comunicati functiei cost produsul care va intereseaza, transmitându-i ca parametru identificatorul produsului.
Linia 8 - subrutina împacheteaza_produs determina introducerea produsului într-o punga.
Linia 9 - variabila produse_în_cos este decrementata, scazând 1 din valoarea ei si atribuindu-i noua valoare.
Linia 10 - instructiunea Wend termina ciclul început la lini 5.
Linia 11 - ajungeti la aceasta linie numai dupa încheierea structurii ciclice. Linia foloseste o functie înca nescrisa, calculeaza_taxa, pentru a determina TVA-ul (pretul total este transmis ca parametru) si returneaza aceasta valoare, care este memorata în variabila taxa
Linia 12 - variabila total este calculata ca suma dintre costul produselor (cost_total) si taxa (taxa
Linia 13 - instructiunea End Sub termina o subrutina. Dupa ea, Access traseaza automat o linie, astfel încât codul sa fie mai clar.
Liniile 14 si 15 - aceasta functie necompletata este numita stub (cotor); apare aici si va trebui sa fie completata ulterior. Cuvintele cheie As Integer comunica Access ca aceasta functie va returna o valoare întreaga.
Liniile 16 si 17 - este o alta functie stub. Instructiunea ByVal id As Integer semnifica faptul ca acestei functii îi va fi transmis un parametru de tip întreg si ca acel întreg va fi numit id cât timp va fi executata functia. Cuvântul cheie ByVal semnifica faptul ca o modificare a valorii variabilei id din aceasta functie nu va afecta procedura apelanta.
Liniile 17-21 - alte functii stub
Aceasta procedura Access relativ simpla (care, probabil, va fi un modul standard) foloseste majoritatea elementelor de cod VBA. Toate procedurile VBA pe care le veti întâlni vor fi similare cu aceasta.
Codul modular si refolosirea lui
Ati observat, probabil, ca doua dintre liniile de instructiuni ale robotului care face cumparaturi sunt identice. Urcarea în masina (si, implicit, închiderea usii si pornirea masinii) reprezinta aceeasi actiune, indiferent unde se petrece, iar daca scrieti codul corect, îl puteti refolosi ori de câte ori robotul are nevoie de masina. Aceasta facilitate este numita refolosirea codului si va permite sa economisiti, din timpul alocat pentru programare.
In acest caz, nu trebuie sa scrieti dacât o singura data instructiunile pentru urcarea în masina, iar robotul le poate urma ori de câte ori vreti sa tipariti raportul respectiv. Daca va gânditi putin, va veti da seama ca evenimentele care au loc de fiecare data când selectati o optiune de meniu înseamna, de fapt, refolosirea aceluiasi cod. Codul optiunilor de meniu este scris modular si, prin urmare, poate fi refolosit.
|