Programarea în Access

 

 

La fel ca orice SGBD serios, Microsoft Access include si un limbaj de programare, Access Basic (pentru versiunea 2.0) respectiv Visual Basic pentru aplicatii pentru versiunile de Access 95 si 97. Acest capitol oferã o imagine de ansamblu asupra limbajelor Access Basic si Visual Basic.

Pentru început vom încerca sã rãspundem la douã întrebãri: Ce sunt Visual Basic pentru aplicatii si Access Basic? De ce le folosim?

Deoarece Access Basic este derivat din Visual Basic, o sã ne ocupãm mai mult de Visual Basic pentru aplicatii. Visual Basic pentru aplicatii, prescurtat uzual VBA, pune la dispozitie un limbaj complex pentru dezvoltarea aplicatiilor în cadrul programelor din Microsoft Office. Aceasta înseamnã cã nucleul limbajului, componentele sale si mediul sunt aceleasi ca în Microsoft Access for Windows 95/97, Microsoft Visual Basic, Microsoft Excel si Microsoft Project.

Aplicatiile mai simple din Access pot fi scrise folosind comenzi macro. Desi comenzile macro sunt bune pentru crearea rapidã de prototipuri de functii si pentru dezvoltarea majoritãtii aplicatiilor de bazã, dezvoltarea unor aplicatii serioase în Access se face folosind limbajul Access Basic, respectiv VBA.

Marile avantaje pe care le oferã limbajele de programare mai sus amintite, fatã de comenzile macro, ar fi:
• Implementarea tratãrii erorilor;
• Executia procesului tranzactional;
• Crearea unor structuri ciclice pentru parcurgerea seturilor de înregistrãri;
• Apelarea functiilor Windows API;
• Crearea prin program a obiectelor bazei de date;
• Utilizarea constantelor si a variabilelor;

De asemenea, Access Basic si VBA usureazã scrierea bibliotecilor de functii reutilizabile, precum si proiectarea si depanarea proceselor complexe de cãtre programatori. În concluzie, desi comenzile macro pot da solutii rapide problemelor simple, limitãrile lor determinã necesitatea folosirii limbajelor de programare pentru dezvoltarea solutiilor mai complexe.

Module si proceduri

Codul Access Basic si VBA este scris în unitãti numite proceduri. O procedurã contine o secventã de cod Access Basic sau VBA care executã o operatie sau calculeazã o valoare. Existã douã feluri de proceduri:
• Subrutine (
Sub)
• Functii (
Function)

O subrutinã (sub-procedurã) este o rutinã care rãspunde la aparitia unui eveniment sau executã o anumitã actiune. O functie este un tip special de rutinã, datoritã faptului cã poate întoarce o valoare. Aceste subrutine si functii sunt pãstrate în module. Modulele furnizeazã o cale de a organiza procedurile. Cu toate cã toate procedurile pot fi înglobate într-un singur modul, este mai convenabil sã le divizãm în grupuri logice, si fiecare grup sã-l stocãm în module separate. Modulele pot fi globale sau specifice unui anumit formular sau raport. Modulele specifice unui formular sau raport sunt în general numite coduri din spatele formularelor (Code Behind Forms - CBF).

Existã douã feluri de rutine, rutinele evenimentelor si rutine definite de utilizator. Procedurile evenimentelor sunt create automat atunci când scrieti codul evenimentului pentru un control. De exemplu, rutina Private Sub OKButton_Click() este creatã atunci când plasati instructiuni de cod în evenimentul Click al butonului numit OKButton.

De asemenea, utilizatorii îsi pot crea rutine proprii. Acestea nu sunt specifice unui anumit obiect sau eveniment. Depinzând de modul si de locul în care au fost create, ele pot fi apelate de oriunde din aplicatie sau numai dintr-un modul individual de cod, formular sau raport. Iatã un mic exemplu de subrutinã:
Sub SayHello()
‘Subrutinã care afiseazã pe ecran textul “ Hello world!, from Access.”
MsgBox “Hello world!, from Access.”
End Sub

Cum se pot apela procedurile? Foarte simplu. Procedurile evenimentelor sunt apelate automat când are loc un eveniment pentru un obiect. De exemplu, când utilizatorul executã click pe un buton de comandã, este executat codul evenimentului Click pentru acel buton de comandã. În mod obisnuit, pentru apelarea procedurilor definite de utilizator, se foloseste cuvântul cheie Call, ca în exemplul urmãtor:
Call SayHello

Apelul se poate face însã si fãrã cuvântul cheie Call, astfel: SayHello. Totusi, aceastã metodã contravine standardelor, deoarece cuvântul cheie Call indicã faptul cã se apeleazã o rutinã definitã de utilizator sau o rutinã eveniment. Cuvântul cheie Call face ca instructiunea sã fie mai clarã si mai usor de citit. Deci vã recomandãm sã folositi cuvântul cheie Call.

De asemenea, nu e o idee rea sã vã comentati codul. O puteti face fie folosind cuvântul cheie Rem, fie apostroful.

Atât subrutinele cât si functiile pot primi argumente (parametri), dar numai functiile pot returna valori. Subrutina din exemplul urmãtor primeste doi parametri, txtFirst si txtLast.
Private Sub sendMsg_Click()
Call Initials (txtFirstName, txtLastName)
End Sub
Sub Initials( sFisrt As String, sLast As String )
MsgBox”Intialele dvs. sunt “ & Left$(sFirst, 1) & Left$(sLast, 1)
End Sub

Codul precedent transmite pur si simplu valori si apoi opereazã cu ele. Exemplul urmãtor ilustreazã folosirea unei functii care întoarce o valoare:
Private Sub nameFunc_Click()
Dim sInitials As String
sInitials =ReturIni( txtFisrtName, txtLastName )
MsgBox”Intialele dvs. sunt “ & sInitlals
EndSub
Function ReturIni( sFirstName As String, sLastName As String )
ReturIni = Left$(sFirstName,1) & Left$(sLastName, 1)
End Function

Variabile, constante, tipuri de date

Deseori avem nevoie sã stocãm valori temporare când efectuãm operatii în Access Basic sau Visual Basic. De exemplu, poate dorim sã calculãm câteva valori, sã le comparãm si în functie de rezultatul comparatie sã executãm diferite operatii. Pentru aceasta trebuie sã pãstrãm valorile ca sã le putem compara, dar deoarece avem nevoie de ele doar atâta timp cât ruleazã codul nostru nu trebuie sã le stocãm în tabele. Access Basic si Visual Basic, ca si majoritatea limbajelor de programare, folosesc variabile pentru stocarea valorilor.
Când creati variabile trebuie sã luati în considerare mai multe lucruri. Modul în care declarati o variabilã determinã domeniul de valabilitate, durata de valabilitate si alte caracteristici ale acesteia.

Declararea variabilelor.

Sunt mai multe metode de declarare a variabilelor în limbajele Access Basic si VBA. Trei metode sunt gresite si numai una e corectã. De exemplu, ati putea declara pur si simplu:
x = 10

Folosind aceastã metodã, practic nu declarati deloc variabila. În mod obisnuit, veti declara variabilele în timp ce le folositi. Aceastã metodã este foarte periculoasã, deoarece poate cauza multe probleme. Ati putea, de asemenea, sã introduceti:
Dim iCounter

Instructiunea Dim declarã o variabilã. Singura problemã a acestei metode este cã nu ati declarat compilatorului tipul variabile. În acest caz, variabila va avea tipul de datã Variant.

O altã gresealã obisnuitã este declararea mai multor variabile pe aceeasi linie:
Dim iCounter, iAge, iWegiht as Integer

În acest caz, numai ultima variabilã este declaratã ca o variabilã Integer, celelalte variabile sunt declarate Variant.

Cea mai eficientã si mai lipsitã de erori metodã de declarare a variabilelor este de a transmite cât mai exact compilatorului tipul de date al variabilelor, ca în exemplul:
Dim iCounter as Integer
Dim sName as String

Asa cum puteti vedea, acest tip de declaratie contine atât numele variabilei, cât si tipul datelor pe care le contine. Acest lucru permite compilatorului sã intercepteze erori de genul memorãrii unui sir într-o variabilã de tip întreg. La o implementare corespunzãtoare, prin selectarea celui mai scurt tip de date folosit pentru fiecare variabilã, puteti reduce resursele necesare executãrii programului dumneavoastrã. Deci, cu toate cã cele patru variante de declare a unei variabile sunt corecte din punctul de vedere al compilatorului, ultima metodã este cea mai indicatã. Urmati-o, si vã veti scuti de multã bãtaie de cap.

Revenind un pic la prima metodã de declarare, cea în care practic noi nu declarãm variabila înainte de a o folosi. De exemplu, avem functia:
Function SafeSqr(num)
TempVal = Abs(num)
SafeSqr = Sqr(TempVal)
End Function

În functie s-a utilizat variabila TempVal fãrã sã fie declaratã. De fapt, limbajul de programare declarã o variabilã pentru noi cu numele de TempVal, deci variabila se poate folosi fãrã sã fie declaratã explicit. Cu toate cã aceastã metodã pare a fi interesantã si folositoare, totusi poate genera erori subtile în cod, greu de detectat, dacã din gresealã se scrie gresit numele variabilei. De exemplu, dacã functia ar fi arãtat astfel:
Function SafeSqr(num)
TempVal = Abs(num)
SafeSqr = Sqr(TemVal)
End Function

La prima vedere functia este asemãnãtoare cu prima, dar din gresealã la a doua folosire a variabile TempVal, s-a scris TemVal, deci s-a creat o noua variabilã. Prin urmare aceastã functie va returna întotdeauna valoarea zero.

Pentru a evita aceastã problemã, putem stipula ca, compilatorul sã genereze mesaj de eroare atunci când întâlneste o variabilã nedeclaratã explicit. Pentru a face asta, trebuie introdus în sectiunea de declaratii a modulului instructiunea Option explicit. Utilizatorii de Access 95 sau 97 nu trebuie sã-si batã capul cu aceastã problemã, deoarece la crearea unui nou modul, instructiunea Option explicit este adãugatã automat în modul. Atentie deci, utilizatori de Access 2.0!

Tipuri de date VBA.

Limbajul VBA oferã mai multe tipuri de date pentru variabile.

Domeniul si durata de valabilitate a variabilelor.

Variabilele pot fi declarate local, la nivel de modul sau publice:
Variabile locale. Variabilele locale sunt disponibile numai în subrutina în care au fost declarate.

Iatã un exemplu ilustrativ:
Private Sub OkButton_Click
Dim sAnimal As String
sAnimal = “Caine”
Call ChangeAnimal
End Sub

Private Sub ChangeAnimal
SAnimal = “Pisica”
End Sub

Aceastã secventã de cod ar putea sã fie tratatã în douã moduri. Dacã este valabilã instructiunea Option Explicit, ceea ce înseamnã cã variabilele trebuie sã fie declarate înainte de folosire, acest cod va returna o eroare de compilare. În caz contrar, variabila sAnimal poate fi schimbatã în “Pisicã” numai în cadrul subrutinei ChangeAnimal.
Variabile statice. Exemplul urmãtor ilustreazã diferenta dintre variabilele locale si cele statice.

Variabilele locale sunt initializate la fiecare apel al codului. De fiecare datã când lansati în executie urmãtoarea procedurã, variabila iCounter ia valoarea 1:
Private Sub local_Click()
Dim iCounter As Integer
iCounter = iCounter + 1
End Sub

De fiecare datã când acest cod este executat, instructiunea Dim reinitializeazã variabila iCounter. Este putin diferitã de urmãtoarea secventã de cod, care ilustreazã folosirea variabilei statice:
Private Sub static_Click()
Static iCounter As Integer
iCounter = iCounter + 1
End Sub

De fiecare datã când acest cod este executat, variabila cu numele iCounter este incrementatã si retinutã.

Pânã acum, aceastã discutie s-a limitat la variabilele care au domeniul în interiorul unei proceduri individuale. Variabilele de nivel modul pot fi vizualizate din orice rutinã apartinând modulului în care au fost declarate. Variabilele de nivel modul sunt declarate prin plasarea unei comenzi Dim în sectiunea General Declarations a formularului, raportului sau modulului de cod.
[General Declarations]
Option Explicit
Dim miCounter As Integer

Valoarea variabilei poate fi schimbatã de orice subrutinã sau functie din modulul respectiv. De exemplu, urmãtoarea subrutinã schimbã valoarea variabilei de nivel modul miCounter la 20. Retineti conventia de numire a variabilei prin folosirea literei m ca prefix al numelui acesteia. Aceasta o face sã fie cunoscutã ca o variabilã de nivel modul. Ar trebui sã folositi declaratii de nivel modul numai pentru variabilele care trebuie sã fie vãzute de mai multe rutine. Ar trebui sã încercati sã declarati majoritatea variabilelor dumneavoastrã de tip local. Aceastã metodã face codul dumneavoastrã mai modular si mai usor de depanat.
Private Sub module_Click()
miCounter = 20
End Sub

Variabile publice. O variabilã poate fi accesatã de oriunde din aplicatia dumneavoastrã.

Variabilele publice se folosesc de obicei pentru identificatorii de acces, valori de configurare pentru mediul de lucru si alte variabile care trebuie sã fie vizibile pentru întreaga aplicatie. Declaratiile variabilelor publice trebuie sã fie plasate în sectiunea General Declarations a modulului de cod. O declaratie de variabilã publicã aratã ca în exemplul urmãtor:
Option Explicit
Public piCounter As Integer

Retineti folosirea prefixului p, care indicã tipul public al variabilei. Secventa de cod urmãtoare, plasatã în evenimentul Click al butonului de comandã OKButton schimbã valoarea variabilei publice piCounter la 150.
Private Sub OKButton_Click()
miCounter = 150
End Sub

Pentru utilizatorii de Access 2.0, cuvântul cheie Public nu existã, echivalentul sãu fiind Global. O variabilã publicã se poate declara în orice modul de cod, cu conditia sã fie precedat de cuvântul cheie Public sau Global. Astfel se pot declara mai multe variabile globale în mai multe module, lucru destul de neplãcut, pentru cã dacã doriti sã vedeti declaratia unei variabile globale trebuie sã cãutati în mai multe module. Un lucru destul de elegant ar fi crearea unui modul separat pentru declaratii, numit de exemplu Declarations, si în care sã nu faceti nimic altceva decât sã vã declarati variabilele globale. Însã, pe cât posibil evitati folosirea variabilelor globale.

Constante.

O constantã este un nume semnificativ pe care îl dati unui sir sau numãr. Constantele pot fi folosite numai pentru valori care nu se schimbã în timpul executiei aplicatiei. De exemplu, rata impozitului ar putea fi constantã în timpul executiei aplicatiei. Constantele sunt utilizate pentru a creste lizibilitatea codului dumneavoastrã si pentru a usura întretinerea programului respectiv.
În limbajul Access Basic si VBA existã douã tipuri de constante. Primul este numit constantã proprie(intrinsecã). Constantele de acest tip fac parte din limbajul propriu zis. Ca programator în Access, puteti folosi constante furnizate de Microsoft Access, Visual Basic si obiecte pentru acces la date (DAO = Date Access Objects). De asemenea, puteti folosi constante din orice bibliotecã de obiecte pe care o utilizati în aplicatia dumneavoastrã. Al doilea tip de constantã este cea simbolicã sau definitivã de utilizator. Acesta este tipul de constantã pe care o declarati dumneavoastrã, ca programator.

O constantã definitã de utilizator este declaratã folosind cuvântul cheie Const. Constantele pot fi declarate în subrutine sau functii sau în sectiunea General Declarations a unui modul. Iatã si un mic exemplu:
Function TotalAmount(SaleAmount As Curreny)
Const TaxRate = 0.0875
TotalAmount = SaleAmount * TaxRate
End Function

Tablouri

Un tablou este format dintr-o serie de variabile referite prin acelasi nume. Fiecare element al unui tablou este diferentiat de celelalte printr-un numãr index unic. Tablourile ajutã în multe situatii la crearea unui cod mai simplu si mai mic. Tablourile au o limitã superioarã si o limitã inferioarã. Toate elementele unui tablou trebuie sã fie continue.

Domeniul de valabilitate al unui tablou poate fi public, modul sau local. Ca si la celelalte variabile, acest lucru depinde de locul în care a fost declarat tabloul si dacã este folosit cuvântul cheie Public sau Global. Limita superioarã a unui tablou este zero (ca valoare prestabilitã). Toate elementele unui tablou trebuie sã fie de acelasi tip.

Existã trei modalitãti de a declara un tablou cu mãrime fixã, în functie de domeniul de valabilitate pe care doriti sã-l aibã:
• Pentru a crea un tablou global sau public se foloseste comanda
Global sau Public.
• Pentru a crea un tablou la nivel de modul se foloseste comanda
Dim în sectiunea de declaratii din modul
• În cadrul unei proceduri, se foloseste comanda
Static( se poate folosi si Dim dacã toatã procedura a fost declaratã staticã )

În Access Basic respectiv VBA existã douã tipuri de tablouri: statice si dinamice.

Tablouri statice.

Când declarati un tablou static, indicati compilatorului limita superioarã si tipul de date pe care le va contine tabloul. Urmãtoarea secventã de cod creeazã un tablou care va contine sase variabile de tip sir:
Dim sName (5) As String

Acest tabloul este static în sensul cã dimensiunea sa nu poate fi modificatã în timpul executiei aplicatiei. Secventa de cod dã un exemplu despre modul în care puteti sã faceti o buclã într-un tablou:
Sub Fixed_Array ()
Dim sName (5) As String
Dim i As Integer
sNames(0) =”Catalin”
sNames(1) = “Adrian”
For i = 0 To Ubound(sName)
MsgBox(sNames(i) )
Next i
End Sub

Tablouri dinamice.

Deseori nu cunoasteti numãrul elementelor pe care trebuie sã le continã un tablou. În acest caz, trebuie sã declarati un tablou dinamic. Tablourile dinamice pot fi redimensionate în timpul executiei aplicatiei. Acest lucru face ca programul dumneavoastrã sã fie mai eficient, deoarece în cazul unui tablou static, VBA face o pre-alocare de spatiul de memorie pentru toate elementele, indiferent dacã acestea contin sau nu date.

Pentru a crea un tablou dinamic, declarati tabloul fãrã sã atribuiti o limitã superioarã, ca în exemplul urmãtor:
Sub Dynamic_Array()
Dim sNames() As String
Dim i As Integer
ReDim sNames(1)
sNames(0) = “Catalin”
sNames(1) = “Adriana”
For i = 0 To Ubound(sName)
MsgBox(sNames(i) )
Next i
End Sub

Probleme apar când încercati sã redimensionati tabloul:
Sub Dynamic_Array()
Dim sNames() As String
Dim i As Integer
ReDim sNames(1)
sNames(0) = “Catalin”
sNames(1) = “Adriana”
ReDim sNames(2)
SNames(2) = “Ana”
For i = 0 To Ubound(sName)
MsgBox(sNames(i) )
Next i
End Sub

Vã asteptati probabil ca toate cele trei elemente ale tabloului sã continã date. De fapt, instructiunea ReDim reinitializeazã toate elementele si numai elementul al doilea va contine o valoare. Acest fenomen poate fi evitat prin folosirea cuvântului cheie Preserve. Codul va arãta cam asa:
Sub Dynamic_Array()
Dim sNames() As String
Dim i As Integer
ReDim sNames(1)
sNames(0) = “Catalin”
sNames(1) = “Adriana”
ReDim Preserve sNames(2)
SNames(2) = “Ana”
For i = 0 To Ubound(sName)
MsgBox(sNames(i) )
Next i
End Sub

În acest exemplu, toate valorile memorate în tablou sunt pãstrate. Sunt si pãrti ascunse ale folosirii acestui cuvânt cheie. Temporar, acest procedeu necesitã mai multã memorie deoarece în timpul procesului de redimensioanare, VBA creazã un întreg tablou nou. Toate valorile sunt din tabloul original într-un tablou nou si apoi tabloul original este sters din memorie. Dacã prelucrati tablouri foarte mari, aceastã metodã poate cauza probleme.