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.