vba_sc3_extras1

54
Şerban CRIŞCOTĂ Programarea în VISUAL BASIC for Application

Upload: ion-ursu

Post on 03-Jul-2015

3.371 views

Category:

Documents


6 download

TRANSCRIPT

Page 1: VBA_SC3_Extras1

Şerban CRIŞCOTĂ

Programarea în VISUAL BASIC for Application

Page 2: VBA_SC3_Extras1

I-2

C U P R I N S

CAP.I ELEMENTELE DE BAZA ALE LIMBAJULUI DE PROGRAMARE VBA - VISUAL BASIC FOR APPLICATION I-5

I.1. Noţiuni generale despre VBA.............................................................................................................. I-5 I.1.1. Utilizarea limbajului de programare VBA....................................................................................... I-5 I.1.2. Necesitatea utilizării codului VBA în aplicaţii Access.................................................................... I-5 I.1.3. Modulele de cod VBA în Access..................................................................................................... I-6 I.1.4. Elementele generale ale limbajului VBA ........................................................................................ I-7 I.1.5. Structura rutinelor VBA .................................................................................................................. I-7 I.1.6. VBA – mediul de dezvoltare şi depanare ........................................................................................ I-7

I.2. Tipuri de date ..................................................................................................................................... I-12 I.2.1. Tipuri de date elementare .............................................................................................................. I-12

I.2.1.1. Date numerice întregi ..............................................................................................................................I-12 I.2.1.2. Date numerice reale .................................................................................................................................I-12 I.2.1.3. Tipul de date BOOLEAN – logic..............................................................................................................I-12 I.2.1.4. Tipul de date STRING – şir de caractere .................................................................................................I-13 I.2.1.5. Tipul de date DATE – data calendaristică şi timpul ................................................................................I-14

I.2.2. Tipuri de date structurate ............................................................................................................... I-14 I.2.2.1. Tipul de date ARRAY – tablou..................................................................................................................I-14 I.2.2.2. TYPE – Crearea tipurilor de date definite de utilizator...........................................................................I-14

I.2.3. Tipul de date VARIANT ............................................................................................................... I-15

I.3. Variabile.............................................................................................................................................. I-16 I.3.1. Declararea variabilelor................................................................................................................... I-16 I.3.2. Caractere folosite ca Type-declaration .......................................................................................... I-16 I.3.3. Option Explicit (declararea explicită a variabilelor)...................................................................... I-16 I.3.4. Variabile Locale şi Globale ........................................................................................................... I-17 I.3.5. Variabile Publice şi Private ........................................................................................................... I-18 I.3.6. Variabile Statice ............................................................................................................................ I-18 I.3.7. Variabile – domeniul şi durata de valabilitate ............................................................................... I-19 I.3.8. Declararea şi folosirea variabilelor ARRAY................................................................................. I-19

I.4. Constante ............................................................................................................................................ I-21

I.5. Limbajul VBA – Instrucţiuni executabile........................................................................................ I-22 I.5.1. Instrucţiunea de atribuire ............................................................................................................... I-22 I.5.2. Structurile de control ..................................................................................................................... I-24

I.5.2.1. Structura secvenţială................................................................................................................................I-24 I.5.2.2. Structura alternativă ................................................................................................................................I-24

I.5.2.2.a) Structura alternativă simplă...............................................................................................................I-24 I.5.2.2.b) Structura alternativă multiplă ............................................................................................................I-25

I.5.2.3. Structura repetitivă ..................................................................................................................................I-27 I.5.2.3.a) Structura repetitivă cu test. Instrucţiunea Do…Loop........................................................................I-27 I.5.2.3.b) Structura repetitivă cu contor. Instrucţiunea For…Next ...................................................................I-28

I.6. Rutine – proceduri şi funcţii ............................................................................................................. I-29 I.6.1. Ce este o rutină şi ce elemente o definesc?.................................................................................... I-29 I.6.2. Transmiterea datelor prin parametri .............................................................................................. I-30 I.6.3. Crearea (definirea) unei rutine....................................................................................................... I-31

I.6.3.1. Proceduri (Subrutine) ..............................................................................................................................I-31 I.6.3.2. Funcţii ......................................................................................................................................................I-32

I.6.4. Apelarea unei rutine....................................................................................................................... I-32 I.6.4.1. Apelarea unei proceduri (subrutine)........................................................................................................I-32 I.6.4.2. Apelarea unei funcţii ................................................................................................................................I-33

I.6.5. Domeniul de vizibilitate al rutinelor.............................................................................................. I-33 I.6.6. Durata de viaţă a rutinelor ............................................................................................................. I-33 I.6.7. Rutine definite de utilizator. Introducerea codului VBA ............................................ I-33 I.6.8. Procedurile evenimentelor ............................................................................................................. I-34 I.6.9. Utilizarea combinată a procedurilor eveniment cu rutinele utilizator ........................................... I-35 I.6.10. Parametri opţionali ...................................................................................................................... I-36

Page 3: VBA_SC3_Extras1

I-3

I.7. Biblioteci standard de proceduri şi funcţii ...................................................................................... I-36 I.7.1. Funcţii matematice ........................................................................................................................ I-37

I.7.1.1. Int(număr); Fix(număr) ...........................................................................................................................I-37 I.7.1.2. Abs(număr)...............................................................................................................................................I-37 I.7.1.3. Sgn(număr)...............................................................................................................................................I-37 I.7.1.4. Sqr(număr) ...............................................................................................................................................I-38 I.7.1.5. Exp(număr) ..............................................................................................................................................I-38 I.7.1.6. Log(număr) ..............................................................................................................................................I-38 I.7.1.7. Rnd [(număr)] ..........................................................................................................................................I-38 I.7.1.8. Sin(număr) ...............................................................................................................................................I-39 I.7.1.9. Cos(număr) ..............................................................................................................................................I-39 I.7.1.10. Tan(număr) ............................................................................................................................................I-39 I.7.1.11. Atn(număr) .............................................................................................................................................I-39 I.7.1.12. Calculul funcţiilor matematice derivate.................................................................................................I-39

I.7.2. Funcţiile TEXT – pentru stringuri ................................................................................................. I-39 I.7.2.1. Asc(string)................................................................................................................................................I-39 I.7.2.2. Chr(CodCaracter)....................................................................................................................................I-40 I.7.2.3. AscB(string); AscW(string); ChrB(CodCh); ChrW(CodCh) .................................................I-40 I.7.2.4. LCase(string) ...........................................................................................................................................I-40 I.7.2.5. UCase(string)...........................................................................................................................................I-41 I.7.2.6. LTrim(string); RTrim(string); Trim(string) .............................................................................................I-41 I.7.2.7. Len(String | NumeVariabila)....................................................................................................................I-41 I.7.2.8. Left(string, lungime).................................................................................................................................I-41 I.7.2.9. Right(string, lungime) ..............................................................................................................................I-42 I.7.2.10. Mid(string, start [,lungime]) ..................................................................................................................I-42 I.7.2.11. InStr([start,]string1,string2[,compare]) ................................................................................................I-43 I.7.2.12. String(număr,caracter) ..........................................................................................................................I-43 I.7.2.13. Space(număr) .........................................................................................................................................I-43 I.7.2.14. Format(expresie[,format]) .....................................................................................................................I-44

I.7.3. Funcţii pentru tablouri (array) - UBound şi LBound..................................................................... I-45 I.7.4. Funcţii de conversie....................................................................................................................... I-45

I.7.4.1. Str(Număr) ...............................................................................................................................................I-45 I.7.4.2. Val(string) ................................................................................................................................................I-45

I.7.5. Funcţii pentru mesaje..................................................................................................................... I-46 I.7.5.1. MsgBox(prompt[,buttons][,title]) ............................................................................................................I-46 I.7.5.2. InputBox(prompt[,title][,default][,X][,Y])...............................................................................................I-47

I.7.6. Funcţii cu tipul: Date/ Time........................................................................................................... I-48 I.7.6.1. DatePart(interval,date) ............................................................................................................................I-48 I.7.6.2. DateDiff(interval,date1,date2) .................................................................................................................I-48 I.7.6.3. DateAdd(interval,number,date) ...............................................................................................................I-49 I.7.6.4. Day(date); Month(date); Year(date) ........................................................................................................I-49 I.7.6.5. Second(date); Minute(date); Hour(date) .................................................................................................I-49 I.7.6.6. Now(); Date(); Time() ..............................................................................................................................I-49 I.7.6.7. DateSerial(year, month, day) ...................................................................................................................I-49 I.7.6.8. TimeSerial(hour, minute, second) ............................................................................................................I-49

I.7.7. Funcţii: structuri de control ........................................................................................................... I-50 I.7.7.1. IIf(condiţie, TruePart, FalsePart) ............................................................................................................I-50 I.7.7.2. Choose(index, caz-1[,caz-2,... [,caz-n]]) .................................................................................................I-50 I.7.7.3. Switch(expr-1,value-1[,expr-2,value-2… [,expr-n,value-n]]..])................................................I-50

I.7.8. Funcţii de inspecţie........................................................................................................................ I-51 I.7.8.1. IsNull(expresie) ........................................................................................................................................I-51 I.7.8.2. IsEmpty(NumeVariabila) .........................................................................................................................I-51 I.7.8.3. IsMissing(NumeParametru) .....................................................................................................................I-51 I.7.8.4. VarType(NumeVariabilă).........................................................................................................................I-52

I.7.9. Funcţiile agregate SQL.................................................................................................................. I-52 I.7.10. Funcţiile agregate de domeniu..................................................................................................... I-53

Page 4: VBA_SC3_Extras1

I-4

Page 5: VBA_SC3_Extras1

I-5

Cap.I Elementele de bază ale limbajului de programare VBA - Visual Basic for Application

I.1. Noţiuni generale despre VBA

I.1.1. Util izarea limbajului de programare VBA

Basic este unul din cele mai vechi limbaje de programare. El a fost creat în ideea de a se realiza un limbaj de programare necesar unui specialist dintr-un anumit domeniu, care nu are cunoştinţe aprofundate despre sistemele de calcul.

Basic a fost implementat iniţial, în sistemele de operare, ca un interpretor, adică ca un sistem care în momentul în care preia o instrucţiune sursă Basic, o transformă imediat în instrucţiuni obiect (cod maşină) şi le execută. Pentru a îl face cât mai accesibil, au existat variante de Basic care au implementat şi comenzi specifice unui sistem de operare, ajungându-se până la a se realiza calculatoare dedicate pentru lucrul sub Basic, fără sisteme de operare.

Evident, fiind conceput pe aceste principii, aplicaţiile realizate nu erau performante, ele neutilizând eficient facilităţile unui sistem de calcul.

Treptat, s-a trecut la realizarea unor implementări, tehnic mai performante, prin realizarea de compilatoare pentru Basic sub diferite sisteme de operare, adică a unor module care transformă un fişier cu instrucţiuni sursă Basic într-un fişier care conţine instrucţiuni direct executabile, în cod obiect. În felul acesta s-au separat cele două acţiuni efectuate de un interpretor în acelaşi timp şi anume: compilarea programului sursă şi execuţia programului obiect.

Firma Microsoft a realizat o versiune de Basic, numită Visual Basic, care pe lângă principiile iniţiale s-a dorit a rezolva următoarea problemă – un limbaj de programare universal, unic, care să poată fi folosit atât în aplicaţiile de sistem (în locul limbajului C) cât şi în cele utilizator, performant atât din punct de vedere al limbajului (implementând conceptele de programare modulară, programare structurată şi programare la nivel de obiect) cât şi din punct de vedere al utilizării tuturor facilităţilor sistemului de operare.

Astfel s-au creat, pe baza aceluiaşi nucleu de programare Basic, trei sisteme: � Microsoft Visual Basic (VB), ca limbaj universal de programare; � Visual Basic for Application (Visual Basic pentru aplicaţii), prescurtat uzual VBA, ca un

limbaj complex pentru dezvoltarea aplicaţiilor în cadrul programelor din Microsoft Office. Aceasta înseamnă că nucleul limbajului, componentele sale şi mediul sunt aceleaşi în Access, Word sau Excel. VBA este aproape identic cu limbajul universal de programare Microsoft Visual Basic;

� Visual Basic Script (VB Script), utilizat în special pentru aplicaţiile Internet.

I.1.2. Necesitatea utilizării codului VBA în aplicaţii Access

Aplicaţiile mai simple din Access pot fi scrise fără a fi nevoie de vreo instrucţiune, eventual folosind comenzile macro. Deşi comenzile macro sunt foarte bune pentru rezolvarea rapidă a unor prelucrări necesare pentru dezvoltarea majorităţii aplicaţiilor de bază, realizarea unor aplicaţii complexe, profesioniste în Access se face folosind limbajul VBA. Acest lucru se datorează faptului că, spre deosebire de comenzile macro, VBA oferă posibilităţi de lucru specifice limbajelor de nivel înalt de programare orientată pe obiecte. Câteva dintre aceste posibilităţi sunt:

• tratarea erorilor prin proceduri speciale create de proiectant. În timpul execuţiei unei aplicaţii pot interveni diverse erori (de exemplu o împărţire la zero sau ieşirea din domeniul de definiţie al unei variabile etc.) pe care sistemul le tratează în general prin stoparea modulului unde apar sau chiar a întregii aplicaţii. VBA oferă posibilitatea ca la apariţia unei erori, controlul să fie dat unui modul de cod VBA, realizat de proiectant, care să rezolve în funcţie de context situaţia apărută, fără a mai fi necesară stoparea modulului respectiv sau a aplicaţiei.

• crearea unor structuri ciclice pentru parcurgerea seturilor de înregistrări. Datele unei tabele sau cereri de selecţie se pot manipula ca pe un fişier specific, numit set de înregistrări;

• execuţia proceselor tranzacţionale. Acestea reprezintă practic posibilitatea de a efectua actualizările într-un set de înregistrări, global, la un anumit moment. În cazul apariţiei unei erori se pot anula toate actualizările din procesul respectiv, setul de înregistrări rămânând nemodificat;

• apelarea funcţiilor Windows API, prin care se pot folosi module ale sistemului de operare;

Page 6: VBA_SC3_Extras1

I-6

• utilizarea variabilelor, constantelor şi a literalilor; • crearea şi manipularea prin program a obiectelor necesare aplicaţiei; • crearea de clase de obiecte; De asemenea VBA uşurează scrierea bibliotecilor de funcţii reutilizabile, precum şi proiectarea şi

depanarea proceselor complexe de către programatori. În concluzie, deşi comenzile macro pot da soluţii rapide problemelor simple, limitările lor

determină necesitatea folosirii limbajului VBA pentru dezvoltarea soluţiilor mai complexe.

I.1.3. Modulele de cod VBA în Access

Codul VBA este scris în unităţi numite rutine, care pot fi proceduri (subrutine) sau funcţii. Aceste proceduri şi funcţii sunt păstrate în obiecte numite module de cod, şi anume:

� Module specifice unui anumit formular sau raport. Modulele specifice unui formular sau raport sunt în general numite coduri din spatele formularelor (Code Behind Forms – CBF). Rutinele din acest loc pot fi vizibile (cunoscute, apelabile) doar din modulul respectiv de cod. Codul din spatele formularului sau raportului se poate accesa prin acţionarea pictogramei specifice codului VBA (după selecţia obiectului respectiv) sau prin apăsarea celor trei puncte (…) din dreptul unui eveniment al paginii respective a unui obiect aparţinând formularului sau raportului respectiv.

� Dacă procedura eveniment nu este creată, atunci automat un Wizard va crea structura acesteia, adică instrucţiunile de declarare şi sfârşit precum şi completarea listei de parametri dacă este cazul. Dacă procedura eveniment a fost creată anterior, atunci se va afişa porţiunea din pagina de cod a formularului sau raportului care conţine respectiva procedură.

� Modulele globale (generale), se pot afişa prin acţionarea paginii Module, din fereastra Database. Foarte important este faptul că rutinele scrise în această zonă pot fi vizibile (dacă sunt declarate Public) nu numai din toate modulele de cod ale aplicaţiei, dar chiar din obiecte ale aplicaţiei, din formulare, rapoarte, cereri sau tabele. Exemplu. Dacă în modulul global se găseşte o funcţie declarată public, cu numele 'Prag', aceasta va putea fi folosită în expresii din orice:

− modul general sau din spatele unui formular sau raport; − controale calculate din formulare sau rapoarte; − proprietăţi ale controalelor sau ale tabelelor (de exemplu Validation Rule, Default Value); − criterii din cereri; − câmpuri calculate din cereri; − practic de oriunde este acceptată o expresie. Orice modul de cod este format din două părţi: � În prima parte se introduc declaraţiile generale ale modulului, valabile în întreg modulul.

Acestea sunt: − Opţiunile modulului. De exemplu: Option Explicit, care forţează declararea tuturor variabilelor folosite în modul. − Declararea tipurilor, variabilelor şi constantelor, vizibile în tot modulul de cod.

� În a doua parte se introduc rutinele (proceduri sau funcţii) modulului de cod. O procedură (subrutină) este o rutină care execută o acţiune:

− la apariţia unui eveniment al unui obiect al aplicaţiei; − la apelarea (lansarea) ei dintr-o altă rutină VBA;

O funcţie este un tip special de rutină, datorită faptului că poate întoarce o valoare, chiar în numele ei.

Deci codul VBA poate fi găsit în rapoarte, formulare şi module de cod. În formulare şi rapoarte,

codul VBA poate fi plasat în rutinele (funcţii sau proceduri) definite de utilizator, ca şi în procedurile eveniment, pe când în modulele generale, codul VBA este plasat numai în rutinele definite de utilizator.

De fapt, pentru a construi cu succes rutine în cod VBA, sunt foarte importante două lucruri: • ce determină stabilirea domeniului de vizibilitate (valabilitate) al variabilelor şi rutinelor; • cum se transmit şi se întorc valorile din rutine;

Page 7: VBA_SC3_Extras1

I-7

În concluzie, putem spune că programarea în VBA nu este procedurală, adică nu avem de-a face cu un program clasic, cu început şi sfârşit, care rezolvă paşii unui algoritm. Codul VBA este practic format din rutine, care sunt executate numai atunci când se produc anumite evenimente. Deci codul VBA implică realizarea unui programări discontinue.

I.1.4. Elementele generale ale limbajului VBA

Definirea unui limbaj de programare (ca şi a VBA) se face în general prin configurarea următoarelor elemente de bază:

• tipuri de date; • variabile; • constante; • instrucţiuni:

− instrucţiunea de atribuire; − structuri de control;

• rutine (proceduri şi funcţii); • biblioteci. Dacă limbajul de programare este orientat la nivel de obiect, aşa cum este Visual Basic sau VBA,

atunci trebuie definite şi elemente referitoare la: • referirea obiectelor; • crearea modulelor de clase de obiecte; • crearea şi manipularea obiectelor (instanţe ale claselor de obiecte); • crearea şi manipularea colecţiilor de obiecte. Limbajele de programare dezvoltate mai pun la dispoziţie programatorilor: • proceduri specifice de tratare a erorilor; • modalităţi de verificare şi depanare a erorilor de programare; • proceduri de import/ export de obiecte exterioare aplicaţiei; • interacţiunea cu sistemul de operare; • manipularea datelor organizate în fişiere sau baze de date.

I.1.5. Structura rutinelor VBA

Scrierea rutinelor se face respectând următoarele reguli: • prima instrucţiune defineşte tipul rutinei, procedură sau funcţie; • ultima instrucţiune executabilă este End Sub | Function; • la început se pun de obicei (dar nu este obligatoriu) instrucţiunile declarative (tipuri de date,

variabile, constante); • toate instrucţiunile au o anumită sintaxă care ţine seama de numărul de rânduri pe care sunt

scrise; • semnul de continuare a unui rând este format din două caractere, spaţiu şi liniuţă cu shift ( _ ); • semnul pentru începutul unui comentariu este apostroful ('). Sfârşitul comentariului este la

sfârşitul rândului.

I.1.6. VBA – mediul de dezvoltare ş i depanare

Odată intrat într-un modul de cod, Access oferă proiectantului de aplicaţii un sistem complex pentru realizarea şi asistarea activităţii de programare în VBA. Printre cele mai utilizate instrumente ale acestui sistem sunt:

� Editarea rutinelor

Sunt oferite facilităţile curente de editare promovate de Microsoft în produsele sale. Există şi mai multe trucuri speciale destinate activităţii de programare, printre care:

− recunoaşterea cuvintelor cheie ale limbajului; − afişarea listelor cu proprietăţile şi metodele obiectelor utilizate; − marcarea recunoaşterii unei denumiri date de utilizator (unei variabile, rutine etc.) prin refacerea formei introduse la declararea acesteia;

� În VBA sistemul nu face deosebire între literele mari şi mici. Dacă la declararea unui obiect, sunt folosite combinaţii de litere mari şi mici, (după anumite convenţii), atunci când se vor introduce

Page 8: VBA_SC3_Extras1

I-8

denumirile respective cu acelaşi tip de literă, sistemul va reface forma iniţială a lor. În acest fel programatorul va sesiza imediat eventualele greşeli comise la introducerea denumirii obiectelor.

� Compilarea rutinelor

Există 3 comenzi de compilare (vezi figura): − compilarea întregii aplicaţii şi salvarea codului obiect rezultat; − compilarea întregii aplicaţii dar fără modificarea codului obiect existent; − compilarea numai a modulelor de cod deschise (încărcate în memorie).

Prezenţa erorilor de compilare este marcată punctual şi este însoţită de informaţiile necesare unei depanări rapide.

De asemenea, sistemul încă din faza de editare semnalează imediat erorile de compilare depistabile în acel moment (de exemplu cele referitoare la corectitudinea sintaxei instrucţiunilor).

� Execuţia după o comandă manuală (deci nu ca urmare a producerii unui eveniment) a rutinelor

O rutină fără parametri se poate executa direct din modulul de cod. Acest lucru se face: • prin plasarea cursorului pe instrucţiunea de la care se doreşte începerea execuţiei; în felul acesta

rutina se poate executa pornind de la oricare dintre instrucţiunile sale executabile; • prin acţionarea uneia dintre cele 4 comenzi de RUN (vezi figura) şi anume:

− Run: execuţia tuturor instrucţiunilor rutinei (eventual şi a rutinelor apelate) fără oprire; − Step Into: execuţia tuturor instrucţiunilor rutinei (eventual şi a rutinelor apelate) cu oprire după fiecare instrucţiune executată; − Step Over: execuţia tuturor instrucţiunilor rutinei (eventual şi a rutinelor apelate) cu oprire după fiecare instrucţiune executată în rutina apelantă, dar fără oprire în rutinele apelate; − Step Out: execuţia tuturor instrucţiunilor până la sfârşitul rutinei principale (apelante), dar cu oprire numai în rutinele de rang superior celei din care s-a dat această comandă; se foloseşte când se doreşte reluarea execuţiei dintr-o rutină apelată, dar fără oprire la instrucţiunile din aceasta.

� În rutine se pot introduce breakpoint-uri (puncte de oprire) printr-un click pe marginea formularului modulului de cod în dreptul instrucţiunii pe care se doreşte oprirea execuţiei. Acest marcaj se vizualizează printr-un punct de culoare maro. Ştergerea breakpoint-urilor se face printr-un nou click sau prin comanda specifică din meniu (vezi figura).

� Se pot introduce în sursă breakpoint-uri prin instrucţiunea STOP.

� Urmărirea traseului programului şi evoluţiei încărcării cu date a variabilelor, în vederea depanării.

Pentru depanare, aşa cum am mai arătat, programul se poate executa şi cu oprire după fiecare instrucţiune sau la un breakpoint. Pentru a marca acest lucru (program în execuţie şi oprit) sistemul va face galben fondul instrucţiunii pe care s-a oprit.

După oprirea programului pe o instrucţiune, se poate vedea valoarea pe care o are în acel moment o variabilă, prin plasarea cursorului pe aceasta.

� Este posibil ca în ieşirea virtuală, Debug Windows, să se introducă toate expresiile provenite de la instrucţiunea: Debug.Print expresie. Vizualizarea obiectului Debug Windows se poate face la un moment dat prin Ctrl + G sau prin pictograma specifică (vezi figura).

Page 9: VBA_SC3_Extras1

I-9

Meniul de execuţie şi depanare al VBA este prezentat mai jos:

Lansarea unei acţiuni de pe bara Debug se face printr-un click pe opţiunea dorită, sau în unele

cazuri, prin utilizarea grupurilor de comenzi rapide ce se găsesc în dreptul lor.

� Urmărirea execuţiei pas cu pas a unei rutine

• În Debug Windows | Locals se permite vizualizarea informaţiilor de stare în momentul lansării în execuţie a unei rutine.

Informaţiile vizează: − numele variabilelor folosite în cadrul rutinei curente; − valorile acestora în momentul execuţiei rutinei; − tipurile de date corespunzătoare variabilelor folosite.

� În momentul executării unei proceduri apelate, utilizatorul are posibilitatea vizualizării informaţiilor de stare din cadrul procedurii apelante.

Pentru o bună înţelegere prezentăm un exemplu (suma a două numere): Public Sub SumaNumere()

Dim A As Byte Dim B As Byte Dim C As Integer A = 10 B = 16 C = A + B MsgBox "Suma este" & C

End Sub

În continuare vom urmări grafic modul în care procedura este executată. Pas 1. Lansarea în execuţie a rutinei.

Afişează fereastra Debug. În aceasta se vor regăsi toate afişările făcute cu instrDebug.Print

Execută instrucţiune cu instrucţiune dar cursorul galben de execuţie se va opri numai pe:

Toate instr.

Nu va mai intra în rutinele apelate

Nu se va mai opri în rutina în care este

Resetează toate variabilele globale ale aplicaţiei.

Bara Visual Basic

Run Stop

Comenzi de compilare

Punctul de întrerupere(Breakpoint) Va determina oprirea rulării

programului acolo unde este întâlnit. Se recunoaşte prin culoarea maro a instrucţiunii şi a unui punct în faţa ei.

Cursorul de marcare a instrucţiunii care se va executa.

Page 10: VBA_SC3_Extras1

I-10

Se vor efectua următoarele două acţiuni: − se plasează cursorul în cadrul procedurii în locul de unde va porni execuţia acesteia (pe primul rând pentru execuţia de la început); − se execută instrucţiunea prin folosirea tastei Step Into ( sau F8).

Apariţia culorii galbene pe instrucţiunea Sub arată începutul execuţiei rutinei (cursorul a fost plasat iniţial pe această instrucţiune). Dacă se va deschide fereastra Debug Windows | Locals (Ctrl + G) se va vedea starea elementelor procedurii (nume variabile, valoarea acestora, tipul de date corespunzător).

Valoarea variabilelor A, B şi C este, în acest moment 0, deoarece, ele fiind de tip Byte şi respectiv Integer, se iniţializează cu 0.

Pas 2. Se accesează din nou Step Into (sau comanda rapidă F8).

Cursorul (culoarea galbenă) s-a mutat pe instrucţiunea A = 10. Execuţia rutinei a sărit peste cele trei instrucţiuni de declarare a variabilelor, deoarece acestea determină alocarea pentru variabile a spaţiului de memorie necesar înainte de execuţia rutinei şi anume în faza de compilare. Faptul că în panoul Locals, valoarea variabilei A este tot 0, arată că în momentul în care culoarea galbenă se găseşte pe o instrucţiune, aceasta nu este încă executată.

Pas 3. Se accesează din nou Step Into (sau comanda rapidă F8)

Culoarea galbenă s-a mutat pe instrucţiunea B = 16 iar în panoul Locals se observă că valoarea

variabilei A este în acest moment 10 iar valoarea variabilei B este tot 0 (instrucţiunea nu este executată).

Pas 4. Se accesează din nou Step Into (sau comanda rapidă F8).

Culoarea galbenă s-a mutat pe instrucţiunea C = A + B. Se observă că, deşi A are valoare 10 iar B are valoare 16, în acest moment, suma lor este tot 0, ceea ce confirmă încă o dată că în momentul în care culoarea galbenă se găseşte pe o instrucţiune, aceasta nu este executată, ci numai după ce culoarea galbenă a trecut de instrucţiunea respectivă ea se execută.

� Pentru vizualizarea valorii unei variabile în momentul execuţiei rutinei se poate utiliza şi o altă metodă prezentată deja: se poziţionează cursorul mouse-ului pe variabila căreia dorim să-i aflăm valoarea şi

Page 11: VBA_SC3_Extras1

I-11

se aşteaptă un interval scurt de timp. Se va observa apariţia unei casete imediat sub variabilă în care este specificată valoarea acesteia.

Pas 5. Se accesează din nou Step Into (sau comanda rapidă F8)

Dacă se poziţionează cursorul mouse-ului pe variabila C se observă cum valoarea acesteia în acest moment este 26 (suma valorilor celor două variabile A şi B: 10 + 16).

Pas 6. Se accesează din nou Step Into (sau comanda rapidă F8).

După executarea instrucţiunii <<MsgBox "Suma="& C>> va apărea un mesaj (o casetă) cu stringul "Suma=" la care este concatenată valoarea variabilei C (valoarea 26 – calculată anterior).

De asemenea dacă poziţionăm cursorul mouse-ului pe variabila C din cadrul instrucţiunii <<MsgBox "Suma=" & C>>, se afişează valoarea 26.

La o nouă accesare a butonului Step Into se observă dispariţia culorii galbene, semn că execuţia rutinei s-a încheiat.

În continuare vom crea un punct de întrerupere cu ajutorul mouse-ului prin click în partea stângă pe bara verticală în dreptul instrucţiunii dorite.

Dacă se operează la lansarea în execuţie a procedurii conform cu pasul nr. 1 se va observa apariţia culorii galbene pe prima instrucţiune (semn că execuţia rutinei a început). După lansarea în execuţie a rutinei, dacă se va folosi opţiunea RUN (comanda rapidă F5) se va observa că marcajul galben trece direct pe instrucţiunea care are punctul de întrerupere (sărind peste instrucţiunile A = 10, B = 16, C = A + B).

Analizând acum valorile variabilelor, observăm că s-au executat totuşi toate instrucţiunile până la

punctul de întrerupere. La o nouă accesare a opţiunii RUN se va afişa mesajul specific (Suma = 26) după care execuţia se va încheia.

Pentru demarcarea punctului de întrerupere vom face click pe acesta.

Bara verticală

Punctul de întrerupere

Page 12: VBA_SC3_Extras1

I-12

În concluzie, din cele prezentate putem afirma că mediul de depanare reprezintă un instrument foarte eficient în determinarea erorilor de execuţie şi a optimizării aplicaţiilor.

I.2. Tipuri de date

Prin dată se înţelege orice entitate asupra căreia poate opera calculatorul. În cod maşină datele se reprezintă sub forma unei secvenţe de cifre binare. În cazul limbajelor de nivel înalt se face abstracţie de detaliile de reprezentare a datelor, dezvoltând conceptul de tip de date. În memoria calculatorului orice dată apare ca o succesiune de biţi. Modul în care pentru o astfel de succesiune se asociază o valoare depinde de interpretarea ce i se dă. La nivelul limbajelor de programare o astfel de interpretare este reprezentată de tipul datelor.

Un tip de date este noţiunea folosită pentru a defini mulţimea valorilor pe care le pot avea datele ce aparţin acestui tip, dimensiunea efectivă pe care o ocupă în memorie datele, precum şi operaţiile ce se pot efectua asupra acestor date.

VBA pune la dispoziţia programatorului tipuri de date predefinite (standard), cum ar fi cele pentru numerele întregi, numerele reale, caractere sau booleene (logice), precum şi posibilitatea de declarare a unor tipuri de date proprii (definite de programator) cu ajutorul instrucţiunii Type.

Tipurile de date pot fi: − elementare (simple) – o variabilă de acest tip va conţine o singură valoare; − structurate – o variabilă de acest tip va conţine mai multe valori elementare.

I.2.1. Tipuri de date elementare

I.2.1.1. Date numerice întregi

Numele tipului de date

Memoria ocupată

Domeniul de valori

Numărul de valori

Valoarea iniţială

Ex. de nume variabilă

Byte (octet) 1 octet 0 … 255 2^8 0 btValue

Integer (întreg) 2 octeţi –32.768…+32.767 2^16 0 iCounter

Long (întreg lung)

4 octeţi – 2.147.283.648 +2.147.483.647

2^32 0 lAmount

Currency (valută)

8 octeţi +/– 922.337.203.

685.477,5808 15 cifre şi 4 zecimale

0 cValuta

Literalii numere întregi se scriu funcţie de sistemul de numeraţie folosit, astfel: − pentru sistemul zecimal: numărul respectiv; Ex.: 1000; –100; 33; − pentru sistemul hexazecimal: prefixul &H; Ex.: &HA1; &H9; − pentru sistemul octal: prefixul &O; Ex.: &O8; &O17.

� Un literal reprezintă o valoare, de tip numeric, string, dată etc., care se introduce direct în codul sursă VBA (de exemplu într-o expresie) fiind evaluată exact aşa cum este scrisă.

I.2.1.2. Date numerice reale

Numele tipului de date

Memoria ocupată

Domeniu Mantisa(M)

Domeniu Exponent(E)

Valoare iniţială

Ex. de nume variabilă

Single (precizie simplă) 4 octeţi aprox 7 cifre

zecimale E-45…E38 0 sngValue

Double (precizie dublă) 8 octeţi aprox 14 cifre

zecimale E-324…E308 0 dValue

� Datele numerice reale se exprimă sub forma: +/–M * 10^+/–E

I.2.1.3. Tipul de date BOOLEAN – logic

Numele tipului de date

Spaţiul de memorare

Domeniu de valori

Valoarea iniţială

Ex. de nume variabilă

Boolean (logic)

2 octeţi True (–1) False (0)

False (0) bRaspuns

� Tipul de date BOOLEAN este compatibil cu tipul de date INTEGER.

Page 13: VBA_SC3_Extras1

I-13

I.2.1.4. Tipul de date STRING – şir de caractere

Există două tipuri de date de tip String şi anume: − string de lungime variabilă, care poate conţine până la 2^31 caractere (aproximativ 2 miliarde); − string de lungime fixă, care poate conţine până la 2^16 caractere (aproximativ 64 de mii). Codul folosit este codul ANSI şi are date în intervalul 0-255. Primele 128 caractere (0-127) corespund literelor şi simbolurilor de pe o tastatură US, adică

codului ASCII. Dintre acestea primele 32 sunt caractere netipăribile, dar care pot avea efect în afişarea datelor. De

exemplu: • caracterul cu codul 7, Bell – semnal sonor; • caracterul cu codul 8, Back Space – caracter înapoi; • caracterul cu codul 9, Tab – salt la următorul marcaj; • caracterul cu codul 10, LF – trecerea la rând nou (următor); • caracterul cu codul 13, CR – face retur de car (început de rând).

Următoarele 128 caractere (128-255) corespund caracterelor speciale, diacriticelor, accente, simboluri valutare, litere în alfabete internaţionale etc.

Literalii string se scriu între ghilimele ("…."). La iniţializare variabilele de tip string vor avea valoarea şir vid, adică "".

Operatorul pentru concatenarea datelor este & (se poate folosi şi sem- nul +). La formarea numelor variabilelor de tip string, se foloseşte de obicei prefixul s. De exemplu sNume.

Codul ASCII

� În tabela de mai jos codurile ASCII sunt date în: • sistemul de numeraţie zecimal – în celule, înaintea fiecărui caracter; • sistemul de numeraţie hexazecimal – pe cele 2 margini, astfel:

− prima cifră hexazecimală pe primul rând; − a doua cifră hexazecimală pe prima coloană.

H 0 1 2 3 4 5 6 7

0 0 · 16 · 32 [space] 48 0 64 @ 80 P 96 ` 112 p

1 1 · 17 · 33 ! 49 1 65 A 81 Q 97 a 113 q

2 2 · 18 · 34 " 50 2 66 B 82 R 98 b 114 r

3 3 · 19 · 35 # 51 3 67 C 83 S 99 c 115 s

4 4 · 20 · 36 $ 52 4 68 D 84 T 100 d 116 t

5 5 · 21 · 37 % 53 5 69 E 85 U 101 e 117 u

6 6 · 22 · 38 & 54 6 70 F 86 V 102 f 118 v

7 7 Bell 23 · 39 ' 55 7 71 G 87 W 103 g 119 w

8 8 BS 24 · 40 ( 56 8 72 H 88 X 104 h 120 x

9 9 Tab 25 · 41 ) 57 9 73 I 89 Y 105 i 121 y

A 10 LF 26 · 42 * 58 : 74 J 90 Z 106 j 122 z

B 11 · 27 · 43 + 59 ; 75 K 91 [ 107 k 123 {

C 12 · 28 · 44 , 60 < 76 L 92 \ 108 l 124 |

D 13 CR 29 · 45 - 61 = 77 M 93 ] 109 m 125 }

E 14 · 30 · 46 . 62 > 78 N 94 ^ 110 n 126 ~

F 15 · 31 · 47 / 63 ? 79 O 95 _ 111 o 127 ·

� Deşi ne-am aştepta ca un caracter să ocupe un octet (8 bits) de memorie –codul ANSI are 256 = 2^8 de simboluri (caractere) –, totuşi spaţiul ocupat de un caracter în memorie este de 2 octeţi. Aceasta se datorează faptului că memorarea caracterelor se face în codul UNICODE, cod care ocupă 2 octeţi şi care conţine un număr de 2^16 simboluri. De exemplu în memorie caracterele ASCII, vor avea pe primul octet codul ASCII al caracterului iar în al doilea 0, iar caracterele ANSI cu cod mai mare de 127, vor avea în al doilea octet 1. Deci, în limbajul Visual Basic, caracterele se folosesc în codul ANSII (ASCII), deşi în memorie ele sunt în codul UNICODE.

Page 14: VBA_SC3_Extras1

I-14

I.2.1.5. Tipul de date DATE – data calendaristică şi timpul

Numele tipului de date

Spaţiul de memorare

Domeniu de valori

Ex. de nume variabilă

Date (data + timpul) 8 octeţi Data: 1/1/100 la 12/31/9999 Timp: 0:00:00 la 23:59:59 dtStartDate

Literalii date se scriu între diezi (#…. #). De exemplu: #January 1, 1993# sau #1 Jan 93#. Afişarea datelor şi timpului se face conform formatului specificat în S.O. Windows prin

comanda Regional Settings. De obicei se pune prefixul dt la numele unei variabilele de tip Date.

� Un număr poate fi convertit în tip Date, folosindu-se convenţia: − data calendaristică – se află în partea stângă a punctului zecimal; − timpul – în partea din dreapta punctului zecimal.

� Ora 24 este 0.0 iar ora 12 este 0.5;

� Numerele negative reprezintă date anterioare celei de 30/Decembrie/1899.

I.2.2. Tipuri de date structurate

Visual Basic include mecanismele necesare construirii unor tipuri noi, prin restrângeri sau combinări ale tipurilor deja definite.

Aceste mecanisme poartă numele de constructori de tipuri şi joacă un rol esenţial în programare.

I.2.2.1. Tipul de date ARRAY – tablou

Un Tablou – Array defineşte o mulţime de valori care sunt de acelaşi tip de dată. Un Array, deşi se materializează printr-o singură variabilă, poate stoca mai multe date de acelaşi tip în compartimentele (elementele) sale.

Structura unui asemenea tip poate avea o dimensiune sau mai multe. Un Array se caracterizează prin 3 elemente dintre care primele două definesc structura: − numărul de dimensiuni; − numărul de elemente (celule) ale fiecărei dimensiuni. Practic se foloseşte numărul de ordine al

primului (implicit 0) şi al ultimului element al fiecărei dimensiuni; − tipul de date al elementelor tabloului. Poate fi orice tip de date, eventual chiar tot array. Utilizarea tablourilor se face numai prin referirea fiecărui element în parte (folosind numele

tabloului indexat la elementul respectiv). Deci în VBA nu se pot efectua operaţii direct cu întreaga structură a tabloului; de exemplu o mutare de date dintr-un tablou în altul cu aceeaşi structură se poate face numai prin mutarea separată a tuturor elementelor tabloului.

� Tablourile de octeţi constituie o excepţie la ultima afirmaţie.

Exemplu. Pentru a stoca cheltuielile pe care le facem în fiecare zi a unui an vom declara o singură variabilă de tip Array, cu 365 elemente de tip numeric, decât 365 variabile individuale. Fiecare element din tablou va conţine o singură valoare. Implicit un tablou se indexează de la 0.

Declararea variabilei se va face: Dim cCheltuieli (364) As Currency Cu procedura de mai jos introducem valoarea 22 în primele 100 de zile: Sub ExempluArray ()

Dim cCheltuieli (364) As Currency Dim intI As Integer For intI = 0 to 99

cCheltuieli (intI) = 22 Next

End Sub

I.2.2.2. TYPE – Crearea tipurilor de date definite de utilizator

Există posibilitatea să se creeze structuri noi de date, definite de proiectant (utilizator), formate din combinări din alte tipuri de date.

Declararea unui nou tip de date se face cu instrucţiunea TYPE astfel: [Public | Private] Type NumeTip

NumeElement1 As type

Page 15: VBA_SC3_Extras1

I-15

NumeElement2 As type ...

End Type

Referirea la variabilele de un tip definit de utilizator, se poate face: − pentru întreaga structură (folosind numele variabilei); − pentru fiecare element în parte (folosind numele elementului respectiv calificat – cu semnul

punct – cu numele variabilei).

� Declararea unui tip de date nu se poate face decât la nivelul unui modul de cod. Deci nu se pot declara tipuri de date la nivelul unei rutine. Exemplu.

Option Compare Database Option Explicit Public Type Person 'se declară tipul de date la nivelul modulului

Nume As String Prenume As String Virsta As Integer

End Type

Sub TypeTest () Dim Primul As Person, Doilea As Person'se declară 2 var. de tip Person

Primul.Nume = "Ionescu" 'se folosesc elementele tipului Person Primul.Prenume = "Ion" Primul.Virsta = 21 Doilea = Primul 'se transferă întregul tip de dată Person MsgBox Doilea.Nume & " " & Doilea.Prenume & ", _ varsta=" & Doilea.Virsta & " ani"' afişează şi valoriea unei expresie

End Sub

� Caracterul (') se foloseşte pentru marcarea comentariilor.

� Caracterele ( _ ) se folosesc pentru continuarea unei instrucţiuni pe următorul rând.

I.2.3. Tipul de date VARIANT

Acest tip de date, specific limbajului Visual Basic, este deosebit de puternic fiind compatibil cu: − toate tipurile numerice; − tipul Date; − tipul String; − tipul Object. Deşi uşurează munca de programare, totuşi folosirea variabilelor de tip variant diminuează

performanţele programului, atât ca memorie ocupată cât şi ca timp de execuţie.

Numele tipului de date

Spaţiul de memorare

Domeniu Valoarea iniţială

Ex. de nume variabilă

Variant (numere)

16 octeţi ca la numeric Empty (Gol) vntValue

Variant (string)

22 octeţi ca la stringuri Empty (Gol) vntNume

Valorile EMPTY, NULL, STRING VID

− EMPTY – reprezintă valoarea pe care o are o variabilă variant care nu este iniţializată. Aceasta înseamnă că variabila a fost declarată dar nu a fost încă introdusă o valoare în ea. La prima introducere a unei date într-o variabilă de tip variant, aceasta se va configura în conformitate cu tipul respectiv de date.

− NULL – reprezintă o valoare pe care o ia o variabilă variant în care datele nu sunt valide. − String de lungime 0 (vid, gol) – string care nu conţine nici o valoare (nici un caracter), adică

este "".

� Tipul de date OBJECT – va fi prezentat în următorul capitol.

Page 16: VBA_SC3_Extras1

I-16

I.3. Variabile

Variabilele sunt nume de locaţii de memorie care conţin valori de un anumit tip, ce se modifică în timpul execuţiei programului. Variabilele se caracterizează prin:

• Domeniul de vizibilitate (valabilitate): se referă la momentul când acestea apar şi dispar din 'codul sursă'. Variabilele apar atunci când sunt declarate prima dată, după care apar şi dispar în funcţie de domeniul lor de vizibilitate. În momentul când variabilele apar (devin vizibile), li se pot atribui valori de un anumit tip şi pot fi folosite în cadrul instrucţiunilor. În rest, ele sunt invizibile şi nu se pot referi.

• Durata de viaţă (valabilitate): se referă la timpul cât variabila ocupă loc în memorie. Când se creează variabile trebuie avut în vedere mai multe lucruri. Modul şi locul în care se declară

o variabilă determină domeniul de vizibilitate, durata de viaţă şi alte caracteristici ale acesteia. Următoarele subiecte analizate vă vor face să înţelegeţi mai bine declararea variabilelor în limbajul Visual Basic.

I.3.1. Declararea variabilelor

Declararea variabilelor se face de obicei cu instrucţiunea declarativă DIM. Forma acestei instrucţiuni este:

Dim NumeVariabilă As TipulDeDateAlVariabilei • Numele variabilei respectă regulile folosite la formarea numelor. În practica programării, se

obişnuieşte să se pună un prefix convenţional la nume, care să indice tipul de date al variabilei. (Vezi exemplele de nume de variabile din modulul Tipuri de date).

• O variabilă poate fi declarată specificându-se următoarele tipuri de date: Byte, Integer, Long, Currency, Single, Double, Date, String (pentru variabile de lungime variabilă), String * length (pentru variabile de lungime fixă), Object, sau Variant, sau a unui tip de date definit cu declaraţia Type.

� Nespecificarea unui tip de date duce la crearea unor variabile de tip Variant. • Se pot declara mai multe variabile pe acelaşi rând, separate prin virgulă, dar este obligatorie

folosirea explicită a tipului de dată pentru fiecare variabilă. Exemplu. Dim intX As Integer, intY As Integer, intZ As Integer

O greşeală obişnuită este declararea mai multor variabile pe aceeaşi linie, fără a se specifica tipul pentru fiecare variabilă declarată ca în exemplul de mai jos.

Dim iCounter, iAge, iWeight As Integer În acest caz, numai ultima variabilă este declarată ca o variabilă de tip Integer (întreg). Celelalte

variabile sunt declarate de tipul Variant (tipul implicit al unei variabile este variant). Această eroare este foarte periculoasă, deoarece unele limbaje de programare (PASCAL), folosesc o

asemenea notare pentru a declara toate variabilele de pe aceeaşi linie de acelaşi tip.

I.3.2. Caractere folosite ca Type-declaration

Anumite variabile mai pot fi create automat de un anumit tip, folosindu-se în loc de specificaţia As, anumite caractere speciale, denumite caractere de tip, la sfârşitul numelui variabilei, în declaraţia Dim. Astfel:

Tipul de date Integer Long Currency Single Double String Variant

Caracterele de tip % & @ ! # $ implicit

Acest tip de declaraţii este importat din variantele mai vechi de Basic, dar nu este recomandabil. Exemplu. Următoarele declaraţii sunt echivalente.

Dim Nume As String ~ Dim Nume$ Dim Virsta As Integer ~ Dim Virsta% Dim Anul As Variant ~ Dim Anul

I.3.3. Option Explicit (declararea explicită a variabilelor)

Este o instrucţiune declarativă care poate fi inclusă în secţiunea General Declarations a unui modul de cod (prima parte a acestuia). Când Option Explicit este plasat într-un modul de cod, toate variabilele din interiorul acestuia trebuie să fie declarate înainte de folosire, în caz contrar producându-se o eroare de compilare.

Page 17: VBA_SC3_Extras1

I-17

Introducerea instrucţiunii declarative Option Explicit în fiecare modul, formular sau raport se poate face automat prin activarea opţiunii Require Variable Declarations (cere declaraţii de variabile) din meniul Tools | Options | Module. Este foarte important ca această instrucţiune (Option Explicit) să fie plasată în toate modulele de cod. Asiguraţi-vă că aţi configurat opţiunea la valoarea True!

Dacă proprietatea specificată mai sus nu este setată (False), atunci practic variabilele pot să nu fie de loc declarate. Declararea acestora se face implicit, în funcţie de datele cu care se încarcă la prima folosire variabila (ca în limbajul FORTRAN).

De exemplu, instrucţiunea: x=10 ar genera şi declararea unei variabile de tip întreg. Folosirea acestei metode este foarte periculoasă, deoarece poate cauza multe probleme. În concluzie, cea mai eficientă şi mai sigură metodă de declarare a variabilelor este de a folosi în

totalitate instrucţiunea declarativă Dim, pentru fiecare variabilă, ca în exemplul următor: Dim iCounter As Integer Dim sName As string Aşa cum se vede, acest tip de declaraţie conţine atât numele variabilei, cât şi tipul datelor pe care le

poate conţine. Acest lucru permite compilatorului să intercepteze erori de genul memorării unui şir într-o variabilă de tip întreg.

De asemenea, prin selectarea celui mai scurt tip de date pentru fiecare variabilă, se reduc substanţial resursele necesare executării programului.

I.3.4. Variabile Locale ş i Globale

În funcţie de locul de declarare, variabilele pot fi: − locale – variabile declarate în interiorul rutinei, care sunt vizibile (domeniul de valabilitate)

numai în aceasta; − globale (modale) – variabile declarate în secţia de declaraţii generale de la începutul unui

modul de cod. În acest caz variabila va fi vizibilă în toate rutinele modulului respectiv de cod.

Exemplu. Fie declararea variabilei: Dim sName As String Dacă această declaraţie se face: • într-o rutină – ea va putea fi folosită numai în aceasta, fiind o variabilă locală; • în secţiunea de declaraţii generale ale modulului de cod – ea este globală şi va putea fi utilizată

în toate rutinele modulului respectiv, dar nu şi în alte module de cod (această caracteristică o au numai variabilele declarate Public în modulul general de cod).

Deci variabilele globale sunt vizibile din orice rutină aparţinând modulului în care au fost declarate. Valoarea variabilei poate fi schimbată de orice subrutină sau funcţie din modulul respectiv.

În următorul exemplu variabila globală miCounter: − ia valoarea 20 în procedura Fac20; − ia valoarea 10 în procedura Fac10; − este afişată valoarea care se găseşte în ea în procedura Afisez.

Option Explicit ' [General Declarations]

Dim miCounter As Integer

Private Sub Fac20 () miCounter = 20

End Sub Private Sub Fac10 ()

miCounter = 10 End Sub Private Sub Afisez ()

MsgBox miCounter End Sub

� Reţineţi câteva observaţii: − convenţia de numire a variabilei modale prin folosirea literei m ca prefix al numelui acesteia.

Aceasta o face să fie uşor recunoscută de programator ca o variabilă de nivel modul (globală); − folosiţi declaraţiile de nivel modul numai pentru variabilele care trebuie să fie văzute din mai

multe rutine;

Page 18: VBA_SC3_Extras1

I-18

− încercaţi să evitaţi (atunci când este posibil) utilizarea variabilelor globale. Această metodă face codul mai modular şi mai uşor de depanat.

I.3.5. Variabile Publice ş i Private

O variabilă publică poate fi accesată (este vizibilă, are domeniul de valabilitate) de oriunde din aplicaţie. Variabilele publice se folosesc de obicei ca identificatori de acces, valori de configurare pentru mediul de lucru şi alte date care trebuie să fie vizibile pentru întreaga aplicaţie. Declaraţiile variabilelor publice trebuie să fie plasate în secţiunea General Declarations a modulului general de cod.

Pentru declararea variabilelor publice se foloseşte cuvântul cheie PUBLIC, în loc de DIM.

Exemplu. O declaraţie de variabilă publică arată aşa: Option Explicit Public piCounter As Integer

De obicei, convenţional se indică tipul public al unei variabile, folosind prefixul p la numele acesteia.

Rutina următoare, ataşată evenimentului Click al butonului de comandă cmdPublic, după ce face 50 variabila publică piCounter, o afişează.

Private Sub cmdPublic_Click () piCounter = 50 Msgbox piCounter

End Sub Se poate folosi cuvântul cheie PRIVATE, în loc de DIM, pentru a declara variabile private în secţiunea

de declaraţii generale a modulului de cod, adică variabile care nu sunt vizibile decât de rutinele aparţinând modulului respectiv de cod. Exemplu. Private MyName As String

� Cuvântul cheie DIM este echivalent cu PRIVATE atunci când se folosesc la declararea variabilelor în modulele de cod. Este totuşi indicată folosirea expresiei private, pentru a face codul mai lizibil (mai uşor de citit şi mai rapid de interpretat).

I.3.6. Variabile Statice

Variabile statice se pot declara numai în rutine, prin folosirea cuvântului cheie STATIC, în loc de cuvântul cheie DIM. Variabilele statice au proprietatea de a-şi păstra valoarea între două apeluri ale rutinei în care au fost declarate.

Exemplul următor ilustrează diferenţa dintre variabilele locale şi cele statice. Deoarece variabilele locale sunt iniţializate la fiecare apel al codului, de fiecare dată când executaţi această procedură, se va afişa numărul 1.

Private Sub cmdLocal_Click () Dim iCounter As Integer iCounter = iCounter + 1 MsgBox iCounter

End Sub De fiecare dată când acest cod este executat, instrucţiunea declarativă Dim defineşte variabila

iCounter şi o iniţializează cu 0. Ea este puţin diferită faţă de următoarea secvenţă de cod, care ilustrează folosirea variabilelor

statice: Private Sub cmdLocal_Click ()

Static iCounter As Integer iCounter = iCounter + 1 MsgBox iCounter

End Sub De fiecare dată când acest cod este executat, variabila cu numele iCounter este incrementată şi

reţinută. Deci la prima execuţie se va afşa 1, la a doua se va afişa 2, la a treia se va afişa 3 etc.

� Practic o variabilă statică este definită numai la primul apel al rutinei în care a fost declarată. Deoarece, fiind statică, nu mai este distrusă la terminarea rutinei, la următoarea apelare nu va mai fi definită şi va avea deci valoarea anterioară apelului.

Page 19: VBA_SC3_Extras1

I-19

I.3.7. Variabile – domeniul ş i durata de valabilitate

Aşa cum am arătat, domeniul de valabilitate sau vizibilitate a variabilelor este determinat de cuvântul utilizat în declararea variabilei: Dim, Private, Public şi de locul unde acesta e plasat, determinând ca variabila respectivă să fie locală, modală (globală) sau publică şi să poată fi folosită numai într-o rutină, la nivelul unui modul de cod sau în toate modulele de cod.

Ar trebui să faceţi tot posibilul ca majoritatea variabilelor din codul dumneavoastră să fie locale, deoarece acestea sunt ferite de o eventuală modificare (accidentală) de către alte rutine.

Durata de viaţă sau valabilitate a variabilelor reprezintă, aşa cum am mai arătat, timpul cât variabila are alocat spaţiu în memorie. Fără alte instrucţiuni speciale, o variabilă se creează în momentul în care modulul în care este declarată, este apelată şi dispare (se distruge, eliberează spaţiul de memorie ocupat) în momentul terminării modulului respectiv.

Astfel: − o variabilă locală, declarată într-o procedură eveniment, va fi alocată numai în timpul execuţiei

procedurii respective (bineînţeles dacă nu este statică); − o variabilă globală, declarată într-un modul de cod al unui formular, va fi alocată cât timp

formularul respectiv va fi în execuţie; − o variabilă publică, declarată într-un modul general de cod va fi alocată în tot timpul execuţiei

aplicaţiei.

I.3.8. Declararea ş i folosirea variabilelor ARRAY

Variabilele Array (tablou) se declară la fel ca orice altă variabilă folosindu-se instrucţiunile declarative Dim, Static, Private, sau Public. Diferenţa faţă de declararea unei variabile simple este aceea că la tablouri, între paranteze, trebuie să se specifice pentru fiecare dimensiune – în ordine şi separate prin virgulă dacă sunt mai multe dimensiuni – valoarea minimă (de obicei se omite fiind implicită) şi maximă a indicelui dimensiunii respective.

� Declararea tablourilor cu dimensiuni fixe - statice

Dim NumeTablou (N1 [, N2 [, N3…. ]) As TipDeDată Aşa cum se observă, marginea de jos a indicelui a fost omisă. Ea implicit se consideră a avea

valoarea 0. Totuşi marginea de jos a indicelui se poate fixa la valoarea 1, dacă este introdusă în modulul respectiv de cod, în secţiunea de declaraţii generale, instrucţiunea declarativă Option Base 1.

Exemplu. Declaraţia Dim MyArray (9, 10) As Integer va crea un tabel cu 2 dimensiuni, cu 10 şi respectiv 11 elemente, cu primul indice cu valori între (0 - 9) şi al doilea indice cu valori între (0 - 10), în care toate cele 110 elemente (celule) sunt de tip Integer.

� Ca orice declaraţie care nu specifică tipul, şi tablourile declarate fără tip sunt de tip Variant. În acest caz, fiind Variant, fiecare element va ocupa 16 bytes dacă este numeric sau 22 bytes dacă este string. Deci la tablouri mari se poate ajunge la un consum mare de memorie, ceea ce trebuie să determine o rezervă în folosirea tablourilor de Variant. Exemplu. În continuare se prezintă ce memorie vor ocupa tablourile.

Dim MyVariantArray (10) As Variant ' Tablou Variant – cel puţin _ 176 bytes (11 el. * 16 bytes). Dim MyIntegerArray (10) As Integer ' Tablou Integer foloseşte _ 22 bytes (11 elemenste * 2 bytes). Dim MyDoubleArray (10) As Double ' Tablou Double-precision _ 88 bytes (11 el. * 8 bytes). Dim MyVariantArray (10) ' Tablou Variant – cel puţin _ 176 bytes (11 el. * 16 bytes). Dim MyIntegerArray (99, 99) As Integer ' Tablou Integer foloseşte _ 100 * 100 * 2 bytes (20.000 bytes). Dim MyDoubleArray (99, 99) As Double ' Tablou Double-precision.. _ 100 * 100 * 8 bytes (80.000 bytes). Dim MyVariantArray (99, 99) ' Tablou Variant – cel puţin _ 160.000 bytes (100 * 100 * 16 bytes). Se pot declara tablouri specificându-se explicit şi marginea de jos a indicelui. Dim NumeTablou (J1 To N1 [, J2 To N2 …. ]) As TipDeDată

� Cu J s-a notat marginea de jos a indicelui, iar cu N marginea de sus a indicelui.

Page 20: VBA_SC3_Extras1

I-20

� Declararea tablourilor cu dimensiuni variabile – dinamice

În timp ce tablourile cu dimensiuni fixe vor ocupa din etapa de compilare o anumită dimensiune de memorie care nu mai poate fi modificată în timpul execuţiei, tablourile dinamice pot să-şi modifice dimensiunile în timpul execuţiei.

Un tablou dinamic se declară la fel, cu Static, Dim, Private sau Public, fără însă a se specifica nimic între paranteze.

Dim NumeTablou () As TipDeDată Exemplu. Dim sngArray () As Single

� Cu instrucţiunea executabilă ReDim (cu o structură asemănătoare cu cea a lui Dim), care se poate plasa oriunde în cod după declararea unui tablou dinamic, se va redimensiona în momentul execuţiei acesteia tabloul cu noile dimensiuni, eventual putându-se schimba şi tipul de date. Exemplu. ReDim sngArray(11) redimensionează tabloul, dar nu modifică tipul de date al elementelor şi provoacă pierderea datelor din tablou.

� Instrucţiunea ReDim provoacă pierderea datelor din tabloul pe care îl redimensionăm. Pentru a se evita acest lucru se poate folosi clauza Preserve. Folosirea acestei clauze nu permite însă modificarea numărului de dimensiuni sau a marginii de jos ai indecşilor. Exemplu. ReDim Preserve sngArray(UBound(sngArray)+10)

− va redimensiona tabloul, mărind cu 10 numărul lui de elemente şi va păstra datele ce erau în tablou înainte de executarea instrucţiunii;

− funcţia Ubound întoarce indicele superior maxim al unui tablou;

� Utilizarea tablourilor

Un tablou poate fi utilizat ca orice variabilă simplă de tipul respectiv. Referirea unui element al tabloului se face prin numele tabloului, urmat între paranteze de indicele (indicii) elementului respectiv.

Exemplu. Sub FillArrayMulti ()

Dim intI As Integer, intJ As Integer Dim sngMulti (1 To 5, 1 To 10) As Single For intI = 1 To 5

For intJ = 1 To 10 sngMulti (intI, intJ) = intI * intJ ' indroduce în fiecare element _ produsul indicilor elementului. ' afişează indicii elementului şi valoarea din acesta. MegBox " Tablou ( " & intI & ", " & intJ & " ) = " & sngMulti (intI, intJ)

Next intJ Next intI

End Sub

� Tablouri de octeţi

Un tablou de octeţi este un tablou dinamic de tipul BYTE. El poate fi utilizat ca orice tablou dinamic, dar mai are o proprietate care îl face util în lucrul cu

stringuri, şi anume: − un tablou de octeţi se poate referi şi direct, numai prin numele lui, fără indici. În felul acesta el

devine compatibil cu tipul de date string, permiţând transferurile directe de date între tablourile de octeţi şi stringuri.

� Trebuie remarcat că în această operaţie fiecare caracter al strigului va ocupa 2 elemente din tabloul de octeţi, deoarece, aşa cum am mai arătat, caracterele sunt memorate în UNICODE (deci pe 2 octeţi). Exemplu. Pentru înţelegerea acestei secvenţe trebuie studiate mai întâi, în capitolul despre funcţiile text, precizările făcute pentru codul UNICODE.

Public Sub TestMatOcteti () Dim Caracter As String, Sir As String * 3 Dim X() As Byte ' Tablou de octeţi, va avea 6 elemente deoarece pentru un caracter din _ string sunt necesare 2 elemente de 1 octet ReDim X(5)

Page 21: VBA_SC3_Extras1

I-21

Dim k As Integer, j As Integer, i As Integer Sir = "1AŞ" X = Sir For i = 0 To 2

j = i + 1 ' în "J" se va calcula numărul caracterului în string.. 1, 2, 3 _ necesar pt. funcţia MID Caracter = Mid (Sir, j, 1) ' în "Caracter" se vor introduce caracterele k = 2 * (i)'În K–poziţia în tablou a primului octet al caracterului:0,2,4 Debug.Print "Caracterul = " & Caracter & "; CodUnicode= " & AscW(Caracter) & "; CodAnsii= " & Asc(Caracter) & "; Octetul 1= " & X(k) & "; Octetul 2= " & X(k+1) ' Ceea ce se afişează cu Debug.Print se poate vizualiza prin comanda _ View | Debug Window MsgBox "Caracterul = " & Caracter & "; CodUnicode= " & AscW(Caracter) & "; CodAnsii= " & Asc(Caracter) & "; Octetul 1= " & X(k) & "; Octetul 2= " & X(k+1)

Next i For i = 0 To 5

Debug.Print "Octetul " & i & " = " & X(i) MsgBox "Octetul " & i & " = " & X(i)

Next i End Sub

După execuţie se va găsi afişat în Debug. Print: Caracterul = 1; CodUnicode= 49; CodAnsii= 49; Octetul 1= 49; Octetul 2= 0 Caracterul = A; CodUnicode= 65; CodAnsii= 65; Octetul 1= 65; Octetul 2= 0 Caracterul = Ş; CodUnicode= 350; CodAnsii= 170; Octetul 1= 94; Octetul 2= 1 Octetul 0 = 49 Octetul 1 = 0 Octetul 2 = 65 Octetul 3 = 0 Octetul 4 = 94 Octetul 5 = 1 În memoria internă, dacă o variabilă nestructurată ocupă mai mulţi octeţi (de exemplu o variabilă

integer ocupă 2 octeţi), atunci cel mai semnificativ dintre aceştia se găseşte la dreapta. Deci dacă într-o variabilă integer se găseşte valoarea:

266 (zecimal) = 0000.0001.0000.1010 (binar) = 01.0A (hexazecimal) Atunci aceasta se va găsi în memorie sub forma: (0000.1010) (0000.0001) – deci cu octetul cel mai

semnificativ (0000.0001) aşezat la dreapta. Din tabelul de mai jos, se observă cum se găseşte în memoria internă, într-o variabilă de tip tablou de

octeţi, datele dintr-un string.

Caracterele din string ‘1’ ‘A’ ‘Ş’

Cod ANSI 1octet/caracter - zecimal 49 65 170

Cod UNICODE 2 octeţi/caracter-zecimal 49 65 350

Memorie -Tabloul X 6 octeţi - binar

0011.0001 0000.0000 0100.0001 0000.0000 0101.1110 0000.0001

Memorie -Tabloul X 6 octeţi - hexa 31 00 41 00 5E 01

Memorie -Tabloul X 6 octeţi - zecimal 49 0 65 0 94 1

I.4. Constante

Prin declararea unei constante, se poate atribui unui nume, o valoare. Aceasta se face prin instrucţiunea declarativă Const.

După declarare, o constantă nu îşi mai poate modifica valoarea. Forma instrucţiunii declarative CONST este:

[Public | Private] Const NumeConstantă [As TipData] = Valoare

O constantă se comportă practic ca o variabilă, iniţializată cu o anumită valoare, care nu se mai poate schimba în timpul execuţiei aplicaţiei.

Page 22: VBA_SC3_Extras1

I-22

Regulile aplicate variabilelor privind domeniul şi durata de valabilitate sunt efective şi în cazul constantelor. Deci vom avea:

− constante locale sau globale, în funcţie de locul de declarare (în rutină sau secţiunea de declaraţii generale a modulului de cod);

− constante publice sau private, dacă folosim sau nu în faţa cuvântului cheie Const cuvintele cheie Private, Public.

Exemplu. Public Const conAge As Integer = 34 ' conAge este o constantă _ Publică, Integer, cu valoarea 34.

Constantele se pot declara în două moduri şi anume: − cu tip explicit, şi anume: Boolean, Byte, Integer, Long, Currency, Single, Double, Date, String,

sau Variant, ca în exemplul de mai sus; − cu tip implicit, în care clauza As lipseşte iar tipul va fi determinat de tipul datei cu care se încarcă

constanta. De exemplu dacă avem declaraţiile: Const Ziua = "Miercuri" Const Virsta = 44

atunci prima constantă va fi de tip string, iar a doua integer. Ca şi la variabile, se pot declara mai multe constante pe acelaşi rând, cu specificarea (dacă este

explicită) a tipului pentru fiecare constantă în parte. Const conAge As Integer = 34, conWage As Currency = 35000, _ conNume="Soare" În exemplul de mai sus primele două constante sunt declarate explicit, Integer respectiv Currency,

iar a treia, implicit, string.

I.5. Limbajul VBA – Instrucţiuni executabile

Limbajele de programare au un set de instrucţiuni care constituie lista completă a posibilităţilor de care dispune programatorul pentru a determina rezolvarea unei probleme (aplicaţie) pe un sistem de calcul.

Instrucţiunile unui limbaj de programare sunt de două feluri: − Instrucţiuni declarative, care practic nu determină executarea unei acţiuni de către sistemul de

calcul, ci numai nişte indicaţii care se dau compilatorului. De exemplu instrucţiunile de declarare ale tipurilor de date, variabilelor sau constantelor (Dim, Const, Type etc.), opţiunile de compilare (Option Explicit, Option Base, Option Compare Database, etc.)

− Instrucţiuni executabile, care reprezintă descrierea unei acţiuni pe care o va efectua sistemul de calcul, în special privind datele aplicaţiei (If, For, Do etc.).

Execuţia unei instrucţiuni reprezintă efectuarea operaţiei specificate de codul instrucţiunii, interpretate la un moment dat de unitatea centrală a unui sistem de calcul sau de un procesor. De obicei, execuţia instrucţiunii presupune obţinerea operanzilor din memoria internă sau din registrele unităţii centrale, formarea rezultatului şi depunerea acestuia într-un registru al unităţii centrale sau în memoria internă.

Ca exemplu de operaţii pe care le face unitatea centrală a sistemului de calcul sunt operaţiile de adunare, scădere, citire, scriere, comparaţie, etc.

Limbajele moderne de programare au un set redus de instrucţiuni complexe: − declararea structurilor de date; − instrucţiunea de atribuire – prin care se calculează expresii; − structurile de control – prin care se determină "traseul" printre instrucţiuni, adică ordinea în care

se execută instrucţiunile; − declararea şi apelarea rutinelor; − crearea modulelor de clase de obiecte; − crearea şi manipularea obiectelor. Practic, instrucţiunile executabile ale limbajelor moderne de programare sunt instrucţiunea de

atribuire şi instrucţiunile prin care se realizează structurile de control. Alte operaţii necesare unei aplicaţii (ca de exemplu executarea operaţiilor de Input/ Output), sunt realizate prin rutine din bibliotecile de obiecte, funcţii şi proceduri disponibile limbajului respectiv de programare.

I.5.1. Instrucţ iunea de atribuire

Forma acestei instrucţiuni este: NumeVariabilă = Expresie

Page 23: VBA_SC3_Extras1

I-23

Acţiunea acestei instrucţiuni constă în calcularea expresiei (din dreapta semnului =) şi depunerea rezultatului în variabilă (din stânga semnului =).

Pentru a se executa cu succes instrucţiunea, este necesar ca rezultatul expresiei să aparţină unui tip de date compatibil cu cel al variabilei. În caz contrar se va produce o eroare de execuţie (pe care le vom trata în alt capitol).

� Totuşi compilatorul încearcă trecerea peste anumite incompatibilităţi, a căror rezolvare este evidentă, efectuând automat conversiile între tipuri diferite de date, dacă este posibil.

Exemplu.

Private Sub TestExpresie () Dim Vstr As String Dim Vnr As Integer

Vstr = "251" Vnr = 251 + 40 ' prelucrări normale Vstr = 251 + 40 ' nu produce eroare de execuţie; ' efectuează adunarea după care transformă constanta numerică 291 _ în stringul "291" Vnr = Vstr ' nu produce o eroare de execuţie; ' transformă stringul "291" în constanta numerică 291 Vstr = Vnr + "ABC" ' va produce eroare de execuţie – _ TYPE-MISMATCH; nu se poate efectua adunarea. Vstr = Vnr & "ABC" ' nu produce eroare. Vnr = "ABC" ' va produce eroare de execuţie – TYPE MISMATCH

End Sub

� Formarea expresiilor în Visual Basic

O expresie este formată din termeni asupra cărora se efectuează anumite operaţii. O expresie a cărei evaluare este o valoare logică (True sau False) se mai numeşte condiţie. • Termenii pot fi: variabile, constante, literali (valori date direct) sau funcţii (proprii sau din

biblioteci). • Operatorii sunt de trei tipuri şi anume: − aritmetici, care acţionând asupra unor termeni scalari (numere, stringuri, date calendaristice,

etc.) vor determina tot un rezultat de aceeaşi natură (scalar):

^ * / \ Mod + - & Ridicare la

putere Înmulţire

Împărţire reală

Împărţire întreagă

Restul împărţirii

Adunare Scădere Concate-

nare şiruri

5^2=25 5*2=10 5/2=2,5 10\3=3 10 Mod 3=1 5+2=7 5-2=3 "Ab" &

2="Ab2"

− relaţionali, care acţionând asupra unor termeni scalari (numere, stringuri, date calendaristice, etc. ) vor determina un rezultat logic (boolean):

< <= > >= = <>

mai mic mai mic sau egal

mai mare mai mare sau egal

egal ne egal

(1<1) =False (5<=5) =True (5>4) =True (5>=5) =True (5=5) =True (5<>5) = False

Is Like apartenenţa la o mulţime La fel ca = pt. stringuri/evaluează caracterele generice din al doilea string (5 Is [1, 2, 3]) = False ("ARAD" Like "AR*") = True

� Caracterele generice generează o mulţime de caractere astfel: ? Un singur caracter. ("a2B3a" Like "a?a") = False

* Zero sau mai multe caractere. ("a2B3a" Like "a*a") = True

# Un singur număr (0-9). ("a2a" Like "a#a") = True

[Listă char] ex. [A-R]

Un singur caracter din listă. ("F" Like "[A-Z]") = True

[!Listă caractere] Un singur char care nu este în listă. ( ("F" Like "[!A-Z]") = False

− logici, având valori logice (True, False) ca operanzi, vor determina un rezultat tot logic:

Page 24: VBA_SC3_Extras1

I-24

Op NOT Op 1 Op 2 AND Op 1 Op 2 OR Op 1 Op 2 XOR

True False True True True True True True True True False

False True True False False True False True True False True

False True False False True True False True True

False False False False False False False False False

Mai există două funcţii logice, mai puţin folosite, şi anume: • EQV – utilizată pentru verificarea echivalenţei logice a două expresii; • IMP – utilizată pentru verificarea implicării logice între două expresii.

� Operatorii sunt aşezaţi de la stânga la dreapta în ordinea priorităţii lor în execuţie, care este în general cea obişnuită din matematică. Parantezele rotunde sunt folosite pentru stabilirea unei ordini explicite a priorităţii în execuţie a operaţiilor.

� Aşa cum am mai arătat, dacă un termen al unei expresii este NULL, atunci şi rezultatul expresiei este tot NULL. Spunem că NULL-ul se propagă în expresii. Totuşi există o excepţie, şi anume la operatorul de concatenare a şirurilor, &: dacă un termen este NULL, iar celălalt nu este NULL, atunci rezultatul va fi chiar termenul diferit de NULL.

� Valoarea EMPTY în expresii este considerată, în funcţie de tipul de date pe care îl reprezintă, chiar valoarea cu care se iniţializează variabilele de tipul respectiv (astfel, în expresii, dacă un termen numeric este EMPTY, atunci se va considera = 0; dacă este logic = False; dacă este string = şir vid; etc.).

I.5.2. Structurile de control

Aşa cum am mai arătat, structurile de control stabilesc ordinea în care se execută instrucţiunile. Există trei structuri de control, şi anume: structura secvenţială, structura alternativă (decizională) şi structura repetitivă (în buclă, în ciclu).

I.5.2.1. Structura secvenţială

Reprezintă execuţia secvenţială a instrucţiunilor, în ordinea în care au fost scrise. Nu necesită folosirea unei instrucţiuni.

I.5.2.2. Structura alternativă

Reprezintă execuţia din mai multe grupuri de instrucţiuni introduse numai a unui singur grup, în funcţie de evaluarea unor condiţii.

I.5.2.2.a) Structura alternativă simplă

� Instrucţiunea: If... Then... Else

If condiţie Then Grup 1 de instrucţiuni

[Else Grup 2 de instrucţiuni]

End IF Structura If... Then... Else evaluează dacă condiţia este adevărată sau falsă. Dacă: • condiţia este adevărată, vor fi executate toate instrucţiunile dintre If şi Else (Grup 1 de

instrucţiuni); • condiţia este falsă, vor fi executate toate instrucţiunile dintre Else şi End If (Grup 2 de

instrucţiuni).

� Folosirea clauzei Else este opţională.

� O condiţie cu rezultatul NULL este tratată ca şi cum ar fi FALSE.

Exemplu. Private Sub cmdIf_Click () ' evenimentul click al unui buton de comandă

If IsNull(Me!txtValue) Then ' Condiţia testează dacă în controlul txtValue, este introdusă o valoare. Acest lucru se face cu funcţia IsNULL, studiată în alt modul

MsgBox "Trebuie sa introduceti o valoare" Else

MsgBox "Ati introdus:" & Me!txtValue

Page 25: VBA_SC3_Extras1

I-25

End If End Sub

� Un control în care nu este introdus nimic va avea valoarea NULL.

I.5.2.2.b) Structura alternativă multiplă

În locul folosirii a mai multor instrucţiuni If... Then... Else, atunci când decizia se ia prin evaluarea mai multor condiţii (Structura alternativă multiplă), este mult mai simplă, fără îndoială, utilizarea instrucţiunii Select Case sau a instrucţiunii If... Then... ElseIF…Else

� Instrucţiunea Select Case

Select Case NumeVariabilă Case Valoare1

Grup 1 de instrucţiuni [Case Valoare2

Grup 2 de instrucţiuni] [Case ValoareX

Grup X de instrucţiuni] ………………………

[Case Else Grup else de instrucţiuni]

End Select

Această instrucţiune evaluează mai multe condiţii formate prin verificarea egalităţilor între valoarea variabilei ataşate instrucţiunii (NumeVariabilă), şi valorile din dreptul cuvintelor cheie CASE (ValoareI). Deci:

Condiţia I va fi: NumeVariabilă=ValoareI Condiţiile sunt evaluate pe rând, în ordinea plasării lor în instrucţiune, până când se găseşte una

adevărată. După găsirea unei condiţii advărate atunci se va executa grupul corespunzător de instrucţiuni, după

care instrucţiunea Select Case se termină, programul continuând cu prima instrucţiune plasată după aceasta.

� Dacă toate condiţiile sunt false atunci se vor executa – dacă există – instrucţiunile dintre Else …. End Select (Grup else de instrucţiuni).

� Dacă mai multe condiţii sunt adevărate, atunci se va executa numai un singur grup de instrucţiuni şi anume cel aflat după prima condiţie găsită adevărată.

� În ValoareI se pot introduce: − reuniuni de mulţimi – operatorul virgulă (ex: 1, 2, 5); − intervale – operatorul TO (ex: 1 To 7); − submulţimi – operatorul IS (ex: Is > 7).

� Folosirea clauzei Case Else este opţională.

� O condiţie cu rezultatul NULL este tratată ca şi cum ar fi FALSE.

Exemplu. Sub TestCase()

Dim NumeV As Integer

NumeV = 5 Select Case NumeV

Case 7 'condiţia: NumeV=7 - False MsgBox "Grup 1 de instrucţiuni"

Case 5, 9 'condiţia: (NumeV=5) OR (NumeV=9) - True MsgBox "Grup 2 de instrucţiuni" 'execuţia instrucţiunii(lor) la care condiţia=True 'după execuţie, instrucţiunea Case se termină

Case 1 To 9 'condiţia: (NumeV>=1) AND (NumeV<=9) - True 'deşi şi această condiţie=true, acest grup nu va fi executat MsgBox "Grup 3 de instrucţiuni"

Page 26: VBA_SC3_Extras1

I-26

Case Else MsgBox "Grup else de instrucţiuni"

End Select End Sub

Exemplu. Procedura următoare este ataşată evenimentului Click a unui buton de comandă cu numele cmdCase, care se află într-un formular, în care se mai află şi un control textbox cu numele txtValue.

Această secvenţă se va executa numai atunci când se va face click pe butonul de comandă cu numele cmdCase.

Private Sub cmdCase_Click ()

Dim IResponse As Integer ' Me!NumeControl este o expresie prin care se accesează datele aflate _ într-un control plasat în formularul respectiv. ' Un control se comportă ca o variabilă de tip variant. ' Dacă controlul este NULL atunci nu este introdusă nici o valoare. If IsNull(Me!txtValue) Then

iResponse = 0 Else

IResponse = Val(Me!txtValue) 'VAL transformă în număr un string. End If Select Case iResponse

Case 0 MsgBox "Trebuie sa introduceti un numar"

Case 1 To 5 MsgBox "Ati introdus o valoare intre 1 si 5"

Case 7, 11, 21 MsgBox "Ati introdus 7, 11 sau 21"

Case Else MsgBox "Ati introdus un numar incorect"

End Select End Sub

Această procedură utilizează în prima parte o instrucţiune If pentru a evalua dacă txtValue este Null, caz în care se memorează un zero într-o variabilă numită iResponse. În caz contrar, valoarea conţinută în controlul txtValue este memorată în iResponse. Instrucţiunea Case evaluează conţinutul variabilei iResponse. Dacă valoarea este 0, este afişată o casetă de text cu mesajul "Trebuie să introduceţi un număr". Dacă valoarea este între 1 şi 5 inclusiv, este afişată o casetă de text conţinând mesajul "Aţi introdus o valoare între 1 şi 5". Dacă utilizatorul introduce 7, 11 sau 21, este afişat un mesaj corespunzător. În celelalte cazuri, utilizatorul primeşte un mesaj care indică introducerea unui număr incorect.

� Instrucţiunea If... Then... ElseIF…Else

If condiţie-1 Then [grup 1 de instrucţiuni]

ElseIf condiţie-n Then [grup n de instrucţiuni] ……………. …..

Else [grup else de instrucţiuni]

End If Instrucţiunea funcţionează similar instrucţiunii Select Case, numai că: − condiţiile introduse sunt independente, ne mai fiind obligatorie prezenţa unei variabile ca un

termen al condiţiei. Deci instrucţiunea va evalua pe rând, în ordine, condiţia 1, 2 etc. • Prima condiţie găsită adevărată va determina execuţia grupului respectiv de instrucţiuni şi

terminarea instrucţiunii. • Dacă toate condiţiile sunt false, vor fi executate toate instrucţiunile dintre Else şi End If (Grup

else de instrucţiuni).

� Folosirea clauzei Else este opţională.

Page 27: VBA_SC3_Extras1

I-27

� O condiţie cu rezultatul NULL este tratată ca şi cum ar fi FALSE.

Exemplu. Sub TestElseIf() Dim V1 As String Dim V2 As String

V1 = InputBox("V1=") V2 = InputBox("V2=") If V1 = "" Then 'nu se introduce valoare în V1- şir gol

MsgBox "In V1 nu este nici o valoare" ElseIf V2 = "" Then

MsgBox "In V1 este ceva, dar nu si in V2" Else

MsgBox "Valorile introduse:V1=" & V1 & "; V2=" & V2 End If

End Sub

I.5.2.3. Structura repetitivă

Reprezintă execuţia repetată a unui anumit grup de instrucţiuni, numit ciclu sau buclă, până când o condiţie ia o anumită valoare.

I.5.2.3.a) Structura repetitivă cu test. Instrucţ iunea Do…Loop

Execută în mod repetat un ciclu şi anume: • cât timp (While) o condiţie este TRUE sau • până când (Until) o condiţie devine TRUE Există două forme ale instrucţiunii Do, în funcţie de locul unde se găseşte plasată condiţia şi anume

la început sau sfârşit: Do [{While | Until} condiţie] Do

[grup instrucţiuni] [grup instrucţiuni] [Exit Do] sau [Exit Do] [grup instrucţiuni] [grup instrucţiuni]

Loop Loop [{While | Until} condiţie]

� Instrucţiunea Exit Do provoacă ieşirea forţată din ciclu. De obicei se execută în funcţie de evaluarea unei condiţii într-o instrucţiune IF.

� Este permisă folosirea instrucţiunii Do şi fără nici o condiţie. În acest caz este obligatorie inserarea în ciclul Do a unei instrucţiuni Exit Do sau Exit Sub | Function, pentru a nu se genera un ciclu fără sfârşit.

� Condiţia este evaluată în funcţie de locul unde este plasată în instrucţiune şi anume: − la prima formă a instrucţiunii (cea din stânga) – înaintea executării ciclului; − la a doua formă a instrucţiunii (cea din dreapta) – după executarea ciclului.

� Ciclul se execută minim de la: − prima formă a instrucţiunii (cea din stânga) – se poate ca ciclul să nu se execute de loc; − a doua formă a instrucţiunii (cea din dreapta) – ciclul se va executa minim o dată.

� O condiţie cu rezultatul NULL este tratată ca şi cum ar fi FALSE. Exemplu.

Private Sub cmdLoop1_Click ()

Dim iCounter As Integer iCounter = 1 Do While iCounter < 5

MsgBox iCounter ICounter = iCounter + 1

Loop End Sub

Procedura va afişa patru mesaje, cu numere de la 1 la 4. Această structură nu asigură întotdeauna executarea secvenţei de cod din interiorul buclei. Dacă în

iCounter este introdusă o valoare mai mare sau egală cu 5, codul din interiorul buclei nu va fi executat niciodată.

Page 28: VBA_SC3_Extras1

I-28

Dacă secvenţa de cod trebuie să fie executată necondiţionat cel puţin o dată, se va folosi următoarea structură: Exemplu.

Private Sub cmdLoop2_Click ()

Dim iCounter As Integer iCounter = 5 Do

MsgBox iCounter ICounter = iCounter + 1 Loop While iCounter < 5

End Sub

Procedura va afişa un mesaj cu numărul 5. Acest cod va fi executat cel puţin o dată, indiferent de valoarea din iCounter, deoarece evaluarea condiţiei se face după executatea ciclului.

� Structura Do While|Until... Loop face evaluarea condiţiei înainte de executarea ciclului şi de aceea nu asigură execuţia acestuia.

� Structura Do... Loop While|Until face evaluarea condiţiei după executarea ciclului şi de aceea execuţia acestuia este asigurată cel puţin o dată.

I.5.2.3.b) Structura repetitivă cu contor. Instrucţ iunea For…Next

Repetă un ciclu de un anumit număr de ori.

� Mai există o structură: FOR EACH... NEXT, care se aplică colecţiilor de obiecte sau tablourilor şi care va fi prezentată în următorul capitol. Această instrucţiune permite parcurgerea automată a tuturor elementelor unei colecţii sau tablou.

Forma instrucţiunii FOR este: For contor = start To end [Step pas] [grup instrucţiuni] [Exit For]

[grup instrucţiuni] Next [contor] în care: − contor – variabilă numerică folosită pentru stabilirea numărului de execuţii ale ciclului; − start – valoarea iniţială a contorului; − end – valoarea finală a contorului; − pas – valoarea cu care contorul se incrementează; poate fi pozitivă sau negativă (implicit este 1);

incrementarea se efectuează după execuţia fiecărui ciclu. Funcţionarea instrucţiunii FOR se face prin parcurgerea următoarelor etape: a) se determină în funcţie de valoarea (pozitivă sau negativă) pe care o are pasul (step), condiţia de

terminare a ciclului şi anume:

− Dacă PAS >=0, condiţia va fi: contor > end; − Dacă PAS < 0, condiţia va fi: contor < end;

b) se evaluează condiţia de terminare a ciclului;

c) în continuare, dacă condiţia este:

− FALSE – se execută ciclul şi se continuă instrucţiunea FOR cu etapa d); − TRUE – nu se execută ciclul şi se termină instrucţiunea FOR. Programul continuă cu instrucţiunile de după NEXT;

d) după executarea ciclului se adună pasul la contor. După această operaţie instrucţiunea FOR continuă cu repetarea evaluării condiţiei, adică cu etapa b).

� Deci, practic, la fiecare ciclu, contorul va parcurge toate valorile de la start la end. Dacă pasul este: • pozitiv, atunci:

− dinamica contorului va fi crescătoare, prin adăugarea valorii pasului la fiecare ciclu; − pentru ca să se execute cel puţin un ciclu, trebuie ca la început start<=end; − numărul de cicluri efectuate va fi: end-start+1.

• negativ, atunci:

Page 29: VBA_SC3_Extras1

I-29

− dinamica contorului va fi descrescătoare, prin scăderea valorii absolute a pasului la fiecare ciclu; − pentru ca să se execute cel puţin un ciclu, trebuie ca la început start>=end; − numărul de cicluri efectuate va fi: start-end+1.

� Instrucţiunea Exit For provoacă ieşirea forţată din ciclu şi continuarea programului cu instrucţiunile de după NEXT. De obicei se execută în funcţie de evaluarea unei condiţii într-o instrucţiune IF.

� Sunt admise imbricări ale structurilor For, dacă sunt folosite variabile contor diferite ca în exemplul următor:

For I = 1 To 10 For J = 1 To 10

For K = 1 To 10 ...

Next K Next J

Next I

� Într-un For trebuie evitată schimbarea valorii contorului.

� Structura For... Next este folosită atunci când sunt un număr exact de iteraţii de executat. Exemplu.

Private Sub cmdForNext_Click () Dim iCounter As Integer For iCounter = 1 To 5

MsgBox iCounter Next iCounter

End Sub Procedura va afişa cinci mesaje, cu numere de la 1 la 5.

� Observaţi că: − iCounter se auto-incrementează; − se pot folosi variabile atât pentru valoarea de start, cât şi pentru cea de sfârşit; − dacă valoarea de incrementare a contorului este diferită de 1, se dă după cuvântul cheie STEP,

printr-un literal sau o variabilă (pas). Exemplu.

Private Sub cmdForNext_Click () Dim iCounter As Integer

For iCounter = 5 To 1 Step -1 MsgBox iCounter

Next iCounter End Sub Procedura va afişa cinci mesaje, cu numere de la 5 la 1.

I.6. Rutine – proceduri şi funcţii

I.6.1. Ce este o rutină ş i ce elemente o definesc?

Rutina este o structură de sine stătătoare, asemănătoare unui program, prin care se efectuează o anumită acţiune. Ea este executată numai atunci când este lansată (apelată), de către un obiect al aplicaţiei care poate fi:

− programul – numai în cazul limbajului Visual Basic, dar nu şi în cel al VBA; − o altă rutină; − un eveniment al unui obiect al aplicaţiei; − un macro. Rutina poate fi apelată de un număr nelimitat de ori din diferite locuri. După execuţia unei rutine, controlul revine obiectului care a provocat apelarea rutinei. Toate declaraţiile (variabile, constante) făcute în interiorul rutinei sunt locale, fiind deci vizibile

numai din interiorul acesteia. De asemenea, durata de viaţă a datelor locale este numai în intervalul de timp cât rutina se află în execuţie. La terminarea rutinei, are loc automat eliberarea din memorie a tuturor variabilelor şi constantelor locale ale acesteia.

Page 30: VBA_SC3_Extras1

I-30

� În Visual Basic nu sunt permise imbricări de rutine. Deci într-o rutină nu se poate declara o altă rutină.

Diferit faţă de programe, rutina interacţionează cu obiectul care a provocat lansarea (apelarea) ei, prin transferarea de date din şi înspre acesta. Acest lucru se realizează în două moduri şi anume:

� Prin lista de parametri. Aceasta reprezintă practic nişte variabile, prin intermediul cărora se face:

− un transfer de date de la modulul care apelează la rutină – parametri de intrare – produs în momentul apelării rutinei; − un transfer de date de la rutină înspre modulul apelant – parametri de ieşire – produs în momentul terminării rutinei şi preluării controlului de către modulul apelant;

� Prin variabile globale sau publice. Aceste variabile fiind vizibile şi din modulul apelant şi din rutină, evident că prin ele se pot face transferuri de date în ambele sensuri între cele două obiecte.

• Definirea unei rutine se face prin atribuirea unui nume (obligatoriu) acesteia şi prin stabilirea listei de parametri (opţional). Parametrii definiţi în rutină se numesc parametri formali.

• Declararea parametrilor formali se face după regulile aplicate la declararea variabilelor. • Apelarea unei rutine se face prin numele ei. • La apelarea unei rutine, corespunzător fiecărui parametru formal, trebuie să existe o dată de

acelaşi tip în modulul apelant, care poate fi o variabilă, o constantă, o expresie sau un literal. Aceste date formează lista parametrilor actuali şi este declarată o dată cu apelarea rutinei. Evident parametrii actuali şi formali trebuie să fie de acelaşi tip şi să ocupe acelaşi loc în cele două liste.

• Parametrii de intrare ai rutinei pot fi în lista parametrilor actuali: variabile, constante, literali sau expresii.

• Parametrii de ieşire ai rutinei pot fi în lista parametrilor actuali numai variabile, deoarece aceştia prin definiţie îşi pot schimba valoarea în timpul execuţiei rutinei.

� Din punct de vedere al terminologiei se mai obişnuieşte să se folosească în loc de parametru termenul argument.

I.6.2. Transmiterea datelor prin parametri

Există două modalităţi de transmitere a datelor prin parametri şi anume, prin valoare sau prin adresă (referinţă).

� Apelarea rutinelor şi transmitera parametrilor prin valoare

Din figura următoare se obsevă că avem perechi de parametri, actuali şi formali, care reprezintă practic două variabile care se sincronizează de două ori: prima dată la apelarea rutinei şi a doua dată la terminarea rutinei.

Astfel la apelarea rutinei se face practic pentru fiecare pereche de parametri operaţia de transfer: ParametruFormal=ParametruActual (de ex: A1=X1 sau A2=X2 etc.)

iar la terminarea rutinei transferul invers: ParametruActual=ParametruFormal (de ex: T=B1 sau Y=B1 etc.)

Modul apelant ………. Instr N….. X1=…. Instr N+1.. X2=…. Apelare rutină - Rtest Parametri actuali:X1, X2, Y

Instr. ….= …Y ……….. Instr J…… M1=…. Instr J+1… M2=…. Apelare rutină - Rtest Parametri actuali:M1, M2, T Instr. ….= …T ……..

Rutina Nume: Rtest Parametrii formali: Intrare: A1, A2 Ieşire: B1 Instr1 ………... ..= A1 + A2 ' folosirea 'parametrilor de intrare ……….. B1= …… ' folosirea 'parametrilor de ieşire ……….. Sfârşit rutină

X1,X2

A1,A2

Y

B1

M1,M2

A1,A2

T

B1

Page 31: VBA_SC3_Extras1

I-31

Deci în acest caz se transferă anumite valori, în ambele sensuri, între perechile de parametri formal şi actuali. Spunem că transmisia parametrilor se face prin valoare.

� Apelarea rutinelor şi transmitera parametrilor prin adresă

În acest caz lucrurile se petrec altfel. Transferul se face numai la apelarea rutinei, dar nu se vor transfera valori, ci rutina va primi adresele parametrilor actuali. În acest fel în rutină parametrii formali se vor genera în memorie peste parametrii actuali. Deci rutina va lucra practic cu parametrii actuali, deşi va folosi numele parametrilor formali în expresii.

� În Visual Basic, dacă nu se fac precizări suplimentare, transmiterea parametrilor se face prin adresă (referinţă).

I.6.3. Crearea (definirea) unei rutine

Rutinele sunt de două feluri: proceduri (sau subrutine) şi funcţii. Diferenţa dintre ele constă în faptul că:

• Funcţiile au un parametru implicit de ieşire care este chiar numele funcţiei. • Procedurile sunt apelate prin instrucţiuni, iar funcţiile sunt apelate prin introducerea numelui

acesteia într-o expresie (ca şi cum ar fi o variabilă sau constantă).

� Funcţiile pot fi folosite direct oriunde este cerută o expresie, cu condiţia vizibilităţii ei din locul de apelare. Astfel putem folosi funcţii ca: parametri de intrare pentru rutine, la definirea proprietăţilor din controale, la cereri etc.

I.6.3.1. Proceduri (Subrutine)

[Private|Public][Static] Sub NumeProcedura [(ListaParametriFormali)] [declaraţii locale de: variabile, constante, etc. ] [instrucţiuni] [Exit Sub] [instrucţiuni]

End Sub

• Instrucţiunea Exit Sub provoacă, dacă este întâlnită, terminarea procedurii şi redarea controlului modulului apelant, la instrucţiunea care se găseşte imediat după cea de apelare. În mod normal procedurile se termină la instrucţiunea End Sub.

• Opţiunile Private sau Public au acelaşi rol ca cel prezentat la variabile. Astfel, procedura declarată Public în modulul general de cod va fi vizibilă din toate modulele de cod ale aplicaţiei, iar cea declarată Private va fi vizibilă numai din modulul în care este declarată. Dacă nu se foloseşte nici una din cele două opţiuni, procedura va fi considerată Public.

• Opţiunea Static determină ca toate variabilele locale declarate în procedură să funcţoineze ca variabilele statice.

• Toate instrucţiunile sunt permise în proceduri,folosind date care pot fi: − parametrii formali;

Parametri actuali

X1 X2 Y

a d r e s e

A1 A2 B1

Parametri formali

Modul apelant ………. Instr N….. X1=…. Instr N+1.. X2=…. Apelare rutină - Rtest Parametri actuali:X1,X2,Y

Instr. ….= …Y ……….. Instr J…… M1=…. Instr J+1… M2=…. Apelare rutină - Rtest Parametri actuali:M1,M2,T

Instr. ….= …T ………..

Rutina Nume: Rtest Parametrii formali: Intrare:A1,A2

Ieşire:B1 Instr1 ……….. ..= A1+A2 'folosirea 'parametrilor de intrare ……….. B1= ….. 'folosirea 'parametrilor de ieşire ……….. Sfârşit rutină

Parametri actuali

X1 X2 Y

a d r e s e

A1 A2 B1

Parametri formali

Page 32: VBA_SC3_Extras1

I-32

− variabilele şi constantele globale; − variabilele şi constantele locale;

� Este indicat ca să se evite, pe cât posibil, în crearea rutinelor, folosirea variabilelor globale. Pentru schimburile de date dintre rutină şi modulul apelant este recomandată utilizarea numai a parametrilor formali. Acest lucru se datorează faptului că o rutină care foloseşte multe variabile globale este de multe ori foarte puţin lizibilă, greu de depanat sau de întreţinut.

• Lista Parametrilor Formali – reprezintă o listă de variabile, declarate după regulile prezentate la variabile şi separate prin virgulă.

Un parametru se declară conform structurii de mai jos: [ByVal | ByRef] NumeParametru As TipDate

Opţiunile ByVal sau ByRef precizează modalitatea de transmitere a parametrului respectiv şi anume:

− ByVal – prin valoare; − ByRef – prin adresă (referinţă);

Implicit, transferul parametrilor se face prin adresă.

I.6.3.2. Funcţii

[Public|Private][Static]Function NumeF-cţie[(ParFormali)] [As TipFuncţie]

[declaraţii locale de: variabile, constante, etc. ] [instrucţiuni] [Exit Function] [instrucţiuni]

End Function

Se observă că singura deosebire esenţială faţă de proceduri se datorează faptului că numele funcţiei are două semnificaţii, fiind în acelaşi timp şi numele rutinei şi parametru de ieşire al rutinei. Din această cauză acestuia trebuie să i se precizeze tipul de date. Dacă acest lucru nu se face atunci tipul funcţiei se va considera implicit Boolean.

Deci o funcţie, după ce este executată, se va comporta practic ca o variabilă – care s-a încărcat cu valoarea parametrului de ieşire – putând fi introdusă direct în partea dreaptă a oricărei expresii.

� În loc de Exit Sub şi End Sub, la funcţii sunt Exit Function şi End Function, evident cu acelaşi rol.

Exemplu. Următorul exemplu reprezintă o funcţie care va testa două valori primite ca parametri şi va întoarce suma sau diferenţa dintre ele.

Function TestF (Numar1 As Integer, Numar2 As Integer) As Integer

If Numar1 > Numar2 Then TestF = Numar1 - Numar2 ' valoarea de retur se introduce în numele_ funcţiei

Else TestF = Numar1 + Numar2 ' valoarea de retur se introduce în numele_ funcţiei

End If End Function

……. Se va folosi această funcţie astfel…. MsgBox TestF (20, 5) ' afişează 15

MsgBox TestF (2, 5) ' afişează 7

I.6.4. Apelarea unei rutine

� Orice funcţie poate fi apelată ca o procedură, dar o procedură nu poate fi folosită ca o funcţie (în partea din dreapta a unei expresii).

I.6.4.1. Apelarea unei proceduri (subrutine)

Există două modalităţi de apelare a unei proceduri: � prin instrucţiunea Call:

Call NumeProcedură (ListaParametrilorActuali) � direct, folosind numele procedurii, urmat eventual de lista parametrilor actuali:

NumeProcedură ListaParametrilorActuali

� Parametrii se separă prin virgulă.

Page 33: VBA_SC3_Extras1

I-33

� Diferenţa între cele două forme este că la apelarea cu Call, parametrii actuali ai procedurii trebuie scrişi între paranteze, pe când la apelarea directă prin numele procedurii nu se foloseasc parantezele.

I.6.4.2. Apelarea unei funcţ ii

O funcţie se apelează dintr-o expresie, folosindu-se numele ei urmat de lista parametrilor actuali incluşi între paranteze. Numele funcţiei, se va comporta în expresie ca o variabilă, încărcată după execuţia funcţiei cu o valoare, ca şi cum ar fi un parametru de ieşire al unei proceduri. Spunem că funcţia întoarce (returnează) o valoare după execuţia ei. Această valoare va participa la evaluarea expresiei respective.

� O procedură nu poate fi folosită într-o expresie în locul unei funcţii, deoarece nu întoarce valori prin numele ei (chiar dacă are parametri de ieşire).

� Funcţiile pot fi apelate şi ca pe o procedură în oricare din cele două modalităţi prezentate.

Exemplu. Refacem exemplul prezentat înainte folosind o procedură TestS în locul funcţiei TestF. Sub TestS (Numar1 As Integer, Numar2 As Integer, Rezultat As Integer)

If Numar1 > Numar2 Then Rezultat = Numar1 - Numar2 ' valoarea calculată se introduce în _ parametrul de ieşire

Else Rezultat = Numar1 + Numar2 ' valoarea calculată se introduce în _ parametrul de ieşire

End If End Sub

……. Se va folosi această procedură astfel…. Dim Rez As Integer Call TestS (20, 5, Rez) ' calculează în Rez MsgBox Rez ' afişează 15 TestS 2, 5, Rez ' calculează în Rez MsgBox Rez ' afişează 7

I.6.5. Domeniul de vizibilitate al rutinelor

Regulile prezentate la variabile privind această problemă sunt valabile şi pentru rutine. Codul VBA este scris numai în unităţi numite rutine. Aceste rutine sunt păstrate fie în modulul

general (global) de cod, fie în modulele specifice din spatele formularelor sau rapoartelor (Code Behind Forms – CBF).

Domeniul de valabilitate sau de vizibilitate a rutinei este determinat de cuvântul utilizat în declararea acesteia: Private sau Public şi de locul unde rutina e plasată.

O rutină este publică dacă este declarată Public şi este plasată în modulul general de cod. Ea este vizibilă în toată aplicaţia.

Restul rutinelor sunt locale şi sunt vizibile numai din modulul unde au fost declarate.

I.6.6. Durata de viaţă a rutinelor

Durata de viaţă a unei rutine, adică timpul în care ea se găseşte în memorie, este în funcţie de locul unde a fost declarată şi anume:

• pe toată durata aplicaţiei dacă se găseşte în modulul general de cod; • cât timp este în execuţie un formular sau raport, dacă se găseşte în codul din spatele acestuia.

I.6.7. Rutine definite de utilizator. Introducerea codului VBA

� Pentru a crea o rutină definită de utilizator într-un modul general (global) de cod, urmaţi paşii de mai jos:

• executaţi clic pe marcajul de tabulare Modules din fereastra bazei de date;

• începeţi un modul nou sau selectaţi un modul existent şi executaţi clic pe opţiunea Design;

• selectaţi opţiunea Insert Procedure (inserează rutină) de pe bara cu instrumente sau selectaţi opţiunea Procedure din meniul Insert. Va apărea pe ecran caseta de dialog prezentată anterior.

• introduceţi numele rutinei şi selectaţi tipul acesteia: funcţie, procedură (subrutină) sau proprietate (se va prezenta în alt capitol).

Page 34: VBA_SC3_Extras1

I-34

Indicaţi dacă doriţi ca rutina să fie publică (pentru întreaga aplicaţie) sau privată (numai pentru acest modul). De asemenea, specificaţi dacă toate variabilele locale din rutină sunt statice sau nu. Terminaţi definirea rutinei cu clic pe OK.

� Pentru a crea o rutină definită de utilizator în modulul de cod din spatele unui formular sau raport se procedează la fel, în afară de afişarea modulului, care se face astfel:

• în timp ce vă aflaţi în modul de afişare Design al unui formular sau raport, vizualizaţi codul din spatele formularului sau raportului executând clic pe butonul Code de pe bara de instrumente sau prin selectarea opţiunii Code din meniul View, sau prin pictograma specifică de pe bara de instrumente.

I.6.8. Procedurile evenimentelor

Procedurile evenimentelor sunt apelate automat când are loc un eveniment pentru un anumit obiect.

De exemplu, când un utilizator execută click cu mouse-ul pe un buton de comandă dintr-un formular, este executat automat, dacă există, codul evenimentului Click pentru acel buton de comandă, cod care se va găsi plasat sub forma unei proceduri eveniment în modulul de cod din spatele formularului respectiv.

Procedura unui eveniment al unui control este creată automat (prima şi ultima instrucţiune a procedurii, adică Sub şi End Sub) când se selectează dintre proprietăţile controlului evenimentul respectiv. Numele procedurii va fi obligatoriu stabilit de sistem, în funcţie de numele controlului şi al evenimentului respectiv. De asemenea, dacă este cazul, este ataşată, tot de către sistem, lista parametrilor formali.

Exemplu. Într-un formular se găseşte un control de tip buton de comandă, cu numele cmdOkay (şi proprietatea Caption="Apasa") şi trei controale de tip textbox, cu numele txtNume, txtVirsta şi txtSex. Instrucţiunea de declarare a procedurii eveniment: Private Sub cmdOkay_Click, ca şi aceea de sfârşit (End Sub), sunt create automat atunci când se selectează evenimentul Click din lista proprietăţilor butonului de comandă cmdOkay. În continuare programatorul introduce codul sursă al procedurii eveniment:

Private Sub cmdOkay_Click ()

If IsNull(Me!txtNume) Or IsNull(Me!txtVirsta) _ Or isNull(Me!txtSex) Then

MsgBox "Trebuie introduse numele, virsta şi sexul" Exit Sub 'Dacă nu sunt date în toate cele trei textbox-uri se afişează _ mesajul şi se termină procedura

Else 'Afişează val. din txtNume şi ce întoarce funcţia CalculVirsta MsgBox "Numele d-tra este: " & Me!txtNume & _

Chr(10) & Chr(13) & "Virsta dv este acum de: " & _ CalculVirsta(Int(Val(Me!txtVirsta)), Me!txtSex) & " ani"

End If End Sub

Procedura de mai sus va fi executată de fiecare dată când se va face click pe butonul de comandă cmdOkay al formularului.

Dacă în toate cele trei controale textbox sunt introduse date, atunci se afişează un mesaj ca în figura alăturată; altfel se va afişa mesajul: "Trebuie introduse numele, vârsta şi sexul"

� Procedura foloseşte următoarele funcţii ce se găsesc în bibliotecile sistem (prezentate în continuarea acestui capitol):

• IsNull(pm) – întoarce TRUE dacă parametrul pm este Null; • Chr(10) – întoarce caracterul LF - Line Feed (rând nou); • Chr(13) – întoarce caracterul CR - Carriage Return (retur de

car); • Val(pm) – întoarce valoarea numerică din stringul pm; • Int(pm) – întoarce partea întreagă din pm.

� Un control se comportă ca o variabilă de tip variant. Datele din control pot fi accesate cu sintaxa Me!NumeControl, dar numai din codul din spatele formularului respectiv. Dacă nu sunt date introduse în control, atunci valoarea acestuia este Null.

Page 35: VBA_SC3_Extras1

I-35

Procedura eveniment utilizează o funcţie utilizator, declarată în acelaşi modul de cod din spatele formularului respectiv, care are doi parametri formali de intrare şi anume: V – în care se va transfera valoarea numerică întreagă din textbox txtVirsta şi S – în care se va transfera valoarea din textbox txtSex.

Function CalculVirsta (V As Integer, S As Variant) As Integer If V > 35 And S = "F" Then

CalculVirsta = V - 10 ElseIf V > 25 And S = "F" Then

CalculVirsta = V - 5 ElseIf V > 20 And S = "F" Then

CalculVirsta = V - 2 ElseIf S = "M" Then

CalculVirsta = V + 5 Else

CalculVirsta = V End If

End Function

� Pentru a edita codul evenimentului, executaţi următorii paşi:

• executaţi click pe control (cmdOkay) în modul de afişare Design şi apoi pe butonul Properties din bara cu instrumente sau executaţi click cu butonul drept al mouse-ului pe obiect şi selectaţi opţiunea Properties din meniul contextual;

• executaţi click pe marcajul de tabulare al proprietăţilor evenimentului (Event); • selectaţi proprietatea pentru care doriţi să scrieţi instrucţiuni de cod (de exemplu, evenimentul

On Click); • selectaţi [Event Procedure] din lista derulantă; • executaţi clic pe butonul (…). Cursorul dumneavoastră va fi plasat în codul evenimentului pentru

obiectul respectiv. Automat sistemul va crea instrucţiunea de declarare a procedurii, – eventual cu lista de parametri formali, dacă este cazul – şi instrucţiunea de sfârşit a procedurii. Proiectantul va introduce acum codul VBA necesar tratării evenimentului.

I.6.9. Util izarea combinată a procedurilor eveniment cu rutinele utilizator

Am arătat că atât subrutinele, cât şi funcţiile pot primi argumente (parametri), dar numai funcţiile pot întoarce valori.

Exemplu. Subrutina următoare primeşte doi parametri, txtFirst şi txtLast. Aceasta afişează apoi un mesaj cu primul caracter al fiecăruia dintre cei primiţi.

Private Sub Initialele (sFirst As String, sLast As String) MsgBox "Initialele dumneavostră sunt: " & _ Left (sFirst, 1) & Left (sLast, 1) ' Funcţia Left întoarce caracterele_ de la începutul unui string

End Sub

• Ea va fi apelată din procedura eveniment On Click a butonului de comandă cmdNume. Private Sub cmdNume_Click ()

Initialele Me !txtFirstName, Me!txtLastName End Sub Observaţi că textul din controalele txtFirstName şi txtLastName din formularul curent (Me) sunt

transmise subrutinei cu numele Initialele. Parametrii sunt recepţionaţi ca sFirst şi sLast. Primul caracter din stânga al fiecărui parametru este afişat în caseta de mesaje.

Codul precedent transmite pur şi simplu valori şi apoi operează cu ele.

Exemplu. În continuare se ilustrează folosirea unei funcţii care întoarce o valoare. Private Function ReturnInit (sFName As String, sLName As String) As String

ReturnInit = Left (sFName, 1) & Left (sLName, 1) End Function • Ea va fi apelată din procedura eveniment On Click a butonului de comandă cmdNume. Private Sub cmdNume_Click ()

Dim sInitials As Integer sInitials = ReturnInit (Me!txtFirstName, Me!txtLastName) MsgBox "Initialele dumneavostra sunt: " & sInitials

Page 36: VBA_SC3_Extras1

I-36

End Sub Reţineţi că acest exemplu apelează o funcţie ReturnInit, trimiţând valorile celor două casete de text

ca parametri ai funcţiei. Funcţia asociază numelui funcţiei (ReturnInit) o valoare egală cu primele două caractere ale şirurilor. Apoi, funcţia întoarce această valoare rutinei apelante (cmdNume_Click) şi o atribuie variabilei sInitials.

I.6.10. Parametri opţionali

Visual Basic vă permite să utilizaţi parametri opţionali. Cu alte cuvinte, nu este necesar să ştiţi câţi parametri vor fi transmişi. Funcţia numită ReturnInit din secvenţa de cod următoare primeşte ultimii doi parametri ca opţionali. Apoi evaluează prezenţa sau nu a parametrilor şi acţionează în consecinţă.

Function ReturnInit (sFName As String, Optional sMI, Optional sLName) As String If IsMissing (sMI) Then ' IsMissing întoarce True dacă s-a apelat _ funcţia fără parametrul sMI

SMI = InputBox ("Introduceţi initiala cuvantului din mijloc") End If If IsMissing (sLName) Then ' IsMissing întoarce True dacă s-a _ apelat funcţia fără parametrul sLName

SLName = InputBox ("Introduceţi ultimul nume") End If ReturnInit = sLName & " " & sMI & " " sFName

End Function

• Această funcţie poate fi apelată de exemplu în felul următor: sName = ReturnInit ("Bill",, "Gates") Aşa cum aţi putut vedea, lipseşte al doilea parametru. În loc să rezulte o eroare de compilare,

funcţia ReturnInit va sesiza acest lucru şi prin funcţia InputBox va cere utilizatorului introducerea valorii respective.

• Sau mai poate fi apelată şi: sName = ReturnInit ("Bill", "X", "Gates") În acest caz funcţia, prin folosirea lui IsMissing, va sesiza prezenţa tuturor celor trei parametri

actuali.

� Lucrul cu parametri opţionali, deci care pot să lipsească la apelarea rutinei, necesită: − declararea ca opţional a parametrului, prin folosirea clauzei Optional, în faţa numelui

parametrului. O restricţie a limbajului este faptul că numai ultimii parametri pot fi declaraţi opţionali. − testarea prin funcţia IsMissing, dacă a fost sau nu introdus la apelare parametrul respectiv în lista

parametrilor actuali. Dacă nu se doreşte introducerea în lista parametrilor actuali a unui parametru opţional, atunci se va scrie numai separatorul (virgula) parametrului respectiv. Funcţia IsMissing este valabilă numai pentru parametri de tip variant.

− pentru parametrii declaraţi opţional, se poate introduce o valoare implicită, cu care se va iniţializa parametrul dacă acesta lipseşte din lista parametrilor actuali.

Dacă se folosesc parametri opţionali, declararea acestora în lista parametrilor formali este: [Optional] NumeParametru As TipDate [ = ValoareImplicita ]

I.7. Biblioteci standard de proceduri şi funcţii

O bibliotecă este un obiect de sine stătător care permite realizarea unei colecţii de funcţii, proceduri, clase de obiecte, colecţii de obiecte şi obiecte.

Noile tehnologii şi standarde introduse de Microsoft permit ca modulele unei biblioteci să fie utilizate de toate aplicaţiile client de pe platforma S.O. care respectă standardele de utilizare ale acestora. În Visual Basic, există posibilitatea creării mai multor tipuri de biblioteci.

Microsoft Office, oferă mai multe biblioteci, care pot fi utilizate în Access, Visual Basic sau alte aplicaţii. Pentru aceasta trebuie ca în prealabil aplicaţia client să înregistreze şi să creeze referinţa (adresa) către biblioteca respectivă. Acest lucru se face prin comanda References. Implicit, o aplicaţie are chiar din faza de instalare create referinţele către cele mai utilizate biblioteci specifice.

Aplicaţiile Access au referinţe create către anumite biblioteci, ale căror module pot fi utilizate oriunde acestea sunt permise.

În acest subcapitol, vor fi prezentate în special cele mai utilizate funcţii şi proceduri ale acestor biblioteci.

Page 37: VBA_SC3_Extras1

I-37

Un bun programator trebuie să cunoască şi să folosească cât mai multe din obiectele puse la dispoziţie de biblioteci. De exemplu dacă se realizează o aplicaţie care la un moment dat trebuie să calculeze sinusul dintr-o valoare, un programator neexperimentat ar putea să creeze un modul care să rezolve acest lucru, pe când un bun programator, ştiind că există în biblioteci funcţia Sin, care calculează sinusul unei valori, va rezolva imediat această problemă, folosind pur şi simplu funcţia respectivă.

Pentru a putea utiliza o funcţie dintr-o bibliotecă, programatorul trebuie să cunoască trei lucruri: − numele funcţiei; − parametrii şi ce reprezintă fiecare; − ce reprezintă valoarea pe care o întoarce funcţia (adică ce operaţii efectuează funcţia).

În crearea expresiilor, în Access se poate folosi un constructor de funcţii – Expressions Builder, lansat de obicei din meniul contextual (Build). Acesta este foarte util, prezentând toate funcţiile, parametrii acestora, modulul de Help, operaţiile permise etc.

În concluzie, în codul VBA, în controalele din formulare sau rapoarte, în proprietăţile tabelelor sau cererilor, se pot folosi în crearea expresiilor atât funcţiile definite (create) de utilizator cât şi funcţiile din bibliotecile către care există referinţe. Toate acestea se pot vizualiza prin Expressions Builder (prin cele două foldere din Functions, aşa cum se vede din figură).

Access are referinţe implicite către o bibliotecă de funcţii şi proceduri, foarte bogată şi cuprinzătoare, din care vor fi prezentate în continuare cele mai utilizate.

I.7.1. Funcţii matematice

I.7.1.1. Int(număr); Fix(număr)

Ambele funcţii întorc partea întreagă a numărului introdus ca parametru de intrare. Tipul de dată al rezultatului va fi acelaşi cu cel al parametrului de intrare. Ambele funcţii Int şi Fix îndepărtează partea fracţionară a numărului şi întorc valoarea întreagă

care rezultă. Diferenţa între Int şi Fix se manifestă numai în cazul numerelor negative. Astfel: • Int întoarce primul număr negativ de tip întreg mai mic sau egal cu numărul; Int (–8. 4) = –9; • Fix întoarce primul număr negativ de tip întreg mai mare sau egal cu numărul; Fix (–8. 4) = –8.

Exemplu. Dim Nr ' variabilă declarată fără specificarea tipului de dată-VARIANT.

Nr = Int (99. 8) ' Întoarce 99. Nr = Fix (99. 2) ' Întoarce 99. Nr = Int (-99. 8) ' Întoarce -100. Nr = Fix (-99. 8) ' Întoarce -99.

I.7.1.2. Abs(număr)

Întoarce valoarea absolută a numărului introdus ca parametru de intrare. Tipul de dată al rezultatului va fi acelaşi cu cel al parametrului de intrare.

Exemplu. Dim Nr

Nr = Abs (50. 3) ' Întoarce 50. 3. Nr = Abs (-50. 3) ' Întoarce 50. 3.

I.7.1.3. Sgn(număr)

Întoarce un Variant (Integer) care reprezintă semnul unui număr.

Dacă parametrul este: < 0 > 0 = 0

Sgn întoarce: –1 1 0

Exemplu. Dim Semn aA Variant

Page 38: VBA_SC3_Extras1

I-38

Const Valoare1= 12, Valoare2= -2. 4, Valoare3= 0

Semn = Sgn (Valoare1) ' Întoarce 1. Semn = Sgn (Valoare2) ' Întoarce -1. Semn = Sgn (Valoare3) ' Întoarce 0.

I.7.1.4. Sqr(număr)

Întoarce o valoare de tip Double (virgulă mobilă dublă precizie) care reprezintă radicalul (square root) unui număr pozitiv (≥ 0). Exemplu.

Dim Radical

Radical = Sqr(4) ' Întoarce 2. Radical = Sqr(23) ' Întoarce 4. 79583152331272. Radical = Sqr(0) ' Întoarce 0. Radical = Sqr(-4) ' Generează o eroare de execuţie.

I.7.1.5. Exp(număr)

Întoarce o valoare de tip Double care reprezintă constanta e ridicată la o putere (în care e este baza logaritmului natural). Exemplu.

Dim Unghi, SinHiper Unghi = 1. 3 ' Defineşte unghiul în radiani SinHiper = (Exp (Unghi) - Exp (-1 * Unghi) ) / 2' Calcul sin hiperbolic

I.7.1.6. Log(număr)

Întoarce o valoare de tip Double care reprezintă logaritmul natural al unui număr (> 0). Logaritmul natural este logaritmul în baza e. Constanta e~2,718282.

Exemplu. Dim Unghi, Logaritm

Unghi = 1.3 ' Defineşte unghiul în radiani Logaritm=Log(Unghi+Sqr(Unghi*Unghi+1))' inversul sin hiperbolic

I.7.1.7. Rnd [(număr)]

Întoarce o valoare de tip Single (virgulă mobilă simplă precizie) care va conţine un număr aleator. Valoarea întoarsă de Rnd este:

Dacă parametrul este: Rnd generează

< 0 Acelaşi număr de fiecare dată, folosind parametrul ca valoare de iniţializare.

> 0 Următorul număr din secvenţă. = 0 Cel mai recent număr generat.

Fără (de obicei) Următorul număr din secvenţă.

Argumentul (parametrul) este opţional şi poate fi un Single sau o expresie numerică corectă. Funcţia Rnd întoarce o valoare în intervalul [0.. 1). Valoarea parametrului determină cum Rnd generează un număr aleator. Pentru o anumită valoare iniţială, este generată aceeaşi secvenţă de numere, deoarece fiecare apel

succesiv al funcţiei Rnd foloseşte numărul generat anterior ca valoare pentru calculul următorului număr din secvenţă.

Înainte de prima folosire a funcţiei Rnd, dacă se doreşte generarea unei secvenţe de numere aleatoare, atunci generatorul de numere aleatoare trebuie iniţializat cu o valoare întâmplătoare. Pentru aceasta se va folosi procedura Randomize, fără parametri, care va folosi pentru iniţializarea generatorului de numere aleatoare ceasul sistemului de calcul.

� Dacă se doreşte generarea unor numere întregi, în intervalul [a.. b], se foloseşte formula: Int(a + (b - a + 1) * Rnd) Exemplu.

Dim Valoare

Randomize Valoare=Int(1+(6*Rnd)) ' Generează o valoare aleatoare între 1 şi 6.

Page 39: VBA_SC3_Extras1

I-39

I.7.1.8. Sin(număr)

Întoarce o valoare de tip Double care este sinusul unui unghi în radiani. Rezultatul va fi în intervalul [–1.. 1]. Pentru a transforma gradele în radiani se înmulţesc gradele cu pi/180. Invers se vor înmulţi radianii

cu 180/pi.

Exemplu. Dim Unghi, Cosecanta

Unghi = 1.3 ' Defineşte unghiul în radiani. Cosecanta = 1 / Sin(Unghi) ' Calculează cosecanta.

I.7.1.9. Cos(număr)

Întoarce o valoare de tip Double care este cosinusul unui unghi în radiani.

Exemplu. Dim Unghi, S

Unghi = 1. 3 ' Defineşte unghiul în radiani. S = 1 / Cos (MyAngle) ' Calculează secanta.

I.7.1.10. Tan(număr)

Întoarce o valoare de tip Double care este tangenta unui unghi în radiani. Pentru a transforma gradele în radiani se înmulţesc gradele cu pi/180. Invers se vor înmulţi radianii

cu 180/pi.

Exemplu. Dim Unghi, Cotangenta

Unghi = 1. 3 ' Defineşte unghiul în radiani Cotangenta = 1 / Tan (Unghi) ' Calculează cotangenta

I.7.1.11. Atn(număr)

Întoarce o valoare de tip Double care reprezintă arctangenta unui număr. Exemplu. pi = 4 * Atn(1) ' Calculează valoarea lui pi.

I.7.1.12. Calculul funcţiilor matematice derivate

Secant Sec (X) = 1 / Cos (X)

Cosecant Cosec (X) = 1 / Sin (X) Cotangent Cotan (X) = 1 / Tan (X) Inverse Sine Arcsin (X) = Atn (X / Sqr (-X * X + 1) ) Inverse Cosine Arccos (X) = Atn (-X / Sqr (-X * X + 1) ) + 2 * Atn (1) Inverse Secant Arcsec (X) = Atn(X / Sqr(X*X –1)) + Sgn( (X)–1) * (2*Atn(1)) Inverse Cosecant Arccosec (X) = Atn(X / Sqr(X*X-1)) + (Sgn(X)–1) * (2*Atn(1)) Inverse Cotangent Arccotan (X) = Atn (X) + 2 * Atn (1) Hyperbolic Sine HSin (X) = (Exp (X) – Exp (-X) ) / 2 Hyperbolic Cosine HCos (X) = (Exp (X) + Exp (-X) ) / 2 Hyperbolic Tangent HTan (X) = (Exp (X) – Exp (-X) ) / (Exp (X) + Exp (-X) ) Hyperbolic Secant HSec (X) = 2 / (Exp (X) + Exp (-X) ) Hyperbolic Cosecant HCosec (X) = 2 / (Exp (X) – Exp (-X) ) Hyperbolic Cotangent HCotan (X) = (Exp (X) + Exp (-X) ) / (Exp (X) – Exp (-X) ) Inverse Hyperbolic Sine HArcsin (X) = Log (X + Sqr (X * X + 1) ) Inverse Hyperbolic Cosine HArccos (X) = Log (X + Sqr (X * X – 1) ) Inverse Hyperbolic Tangent HArctan (X) = Log ( (1 + X) / (1 – X) ) / 2 Inverse Hyperbolic Secant HArcsec (X) = Log ( (Sqr (-X * X + 1) + 1) / X) Inverse Hyperbolic Cosecant HArccosec (X) = Log ( (Sgn (X) * Sqr (X * X + 1) + 1) / X) Inverse Hyperbolic Cotangent HArccotan (X) = Log ( (X + 1) / (X – 1) ) / 2 Logarithm to base N LogN (X) = Log (X) / Log (N)

I.7.2. Funcţiile TEXT – pentru stringuri

I.7.2.1. Asc(string)

Întoarce o valoare de tip Integer, în intervalul 0…255, care reprezintă codul în ASCII (ANSI) a primului caracter din şirul de caractere ce se află în argumentul (parametrul de intrare) funcţiei. Exemplu.

Dim Numar Numar = Asc ("A") ' Întoarce 65.

Page 40: VBA_SC3_Extras1

I-40

Numar = Asc ("a") ' Întoarce 97. Numar = Asc ("Apple") ' Întoarce 65.

I.7.2.2. Chr(CodCaracter) Întoarce o valoare de tip string care reprezintă caracterul asociat codului caracterului în ASCII

(ANSI), introdus ca argument al funcţiei.

� Codurile dintre 0-31 au ca corespondent în ASCII caractere netipăribile, care însă pot să determine anumite acţiuni în timpul afişării. De exemplu:

• Chr(10) întoarce caracterul Line Feed (LF) - trecerea pe linie nouă; • Chr(13) întoarce Carriage Return (CR) - trecerea la început de linie. Intervalul normal pentru parametrul CodCaracter este: 0-255.

Exemplu. Dim Caracter

Caracter = Chr (65) ' Întoarce A. Caracter = Chr (97) ' Întoarce a. Caracter = Chr (62) ' Întoarce >. Caracter = Chr (37) ' Întoarce %.

I.7.2.3. AscB(string); AscW(string); ChrB(CodCh); ChrW(CodCh)

Funcţiile AscB, AscW, ChrB, ChrW ţin seama că în memorie caracterele sunt codificate pe 2 octeţi în standardul UNICODE. Ele consideră şirul de caractere ca pe un tablou de octeţi, în care fiecare caracter ocupă doi octeţi (byte).

• Funcţia AscB – în loc să întoarcă codul pentru primul caracter, întoarce primul byte, din codul în UNICODE al primului caracter.

• Funcţia AscW – întoarce codul caracterului în UNICODE (pe 2 octeţi, în intervalul 0…2^16). • Funcţia ChrB – în loc să întoarcă un caracter al cărui cod (aflat în parametrul funcţiei) poate fi

pe 1 sau 2 bytes, ea va întoarce întotdeauna caracterul al cărui cod este pe primul byte. • Funcţia ChrW – întoarce un string care conţine caracterul al cărui cod este introdus în argument

în standardul UNICODE.

� Aceste funcţii au efect numai pe platformele care acceptă codul UNICODE. Dacă acesta nu este acceptat, atunci ele se comportă la fel ca funcţiile Asc respectiv Chr. Exemplu.

Public Sub TestUnicode () MsgBox Asc ("A") ' Întoarce Cod Ascii = 65

MsgBox AscB ("A") ' Întoarce primul byte din Codul Unicode = 65

MsgBox AscW ("A") ' Întoarce Codul Unicode = 65

MsgBox Asc ("Ş") ' Întoarce Cod Ascii = 170

MsgBox AscB ("Ş") ' Întoarce primul byte din Codul Unicode = 94

MsgBox AscW ("Ş") ' Întoarce Codul Unicode = 350

MsgBox Chr (65) ' Întoarce Caracterul = A

MsgBox ChrB (65) ' Întoarce Caracterul = A

MsgBox ChrW (65) ' Întoarce Caracterul = A

MsgBox Chr (170) ' Întoarce Caracterul = Ş

MsgBox ChrB (94) ' Întoarce Caracterul = ^

MsgBox ChrW (350) ' Întoarce Caracterul = Ş

End Sub Caracterul A Ş

Cod ANSI (1 octet) 65 170 Cod UNICODE (valoare) 65 350 Cod UNICODE (2 octeţi) 65 0 94 1

� Se observă că în codul UNICODE, primele 128 de coduri sunt ca în codul ASCII.

I.7.2.4. LCase(string)

Întoarce o valoare de tip Variant (String) în care literele mari au fost convertite în litere mici. Restul caracterelor rămân nemodificate.

Page 41: VBA_SC3_Extras1

I-41

Exemplu. Dim Valoare, ValoareMica

Valoare = "Nota EXAmen" ' String pentru a fi convertit. ValoareMica = LCase (Valoare) ' Întoarce "nota examen".

I.7.2.5. UCase(string)

Întoarce o valoare de tip Variant (String) în care literele mici au fost convertite în litere mari. Restul caracterelor rămân nemodificate. Exemplu.

Dim Valoare, ValoareMare Valoare = "Nota EXAmen" ' String pentru a fi convertit. ValoareMare = UCase (Valoare) ' Întoarce "NOTA EXAMEN".

I.7.2.6. LTrim(string); RTrim(string); Trim(string)

Întoarce o valoare de tip Variant (String) care este copia stringului, dar: − la funcţia LTrim: fără spaţiile de început; − la funcţia RTrim: fără spaţiile de sfârşit; − la funcţia Trim: fără spaţiile din ambele capete.

Exemplu. Dim Valoare, Modific

Valoare = " <-Trim-> " ' Iniţializează stringul. Modific = LTrim(Valoare) ' Modific = "<-Trim-> ". Modific = RTrim(Valoare) ' Modific = " <-Trim->". Modific = LTrim(RTrim(Valoare)) ' Modific = "<-Trim->". ' Utilizând funcţia Trim se obţine acelaşi rezultat. Modific = Trim(Valoare)' Modific = "<-Trim->"

I.7.2.7. Len(String | NumeVariabila)

Întoarce o valoare de tip Long cuprinzând: • dacă argumentul este un string, câte caractere are; • dacă argumentul este o variabilă, câte caractere pot să fie introduse în ea.

� Dacă argumentul este NULL, funcţia va întoarce tot NULL; această regulă, aşa cum am mai amintit, este comună şi celorlalte funcţii.

� Unul (şi numai unul) din cele două argumente posibile trebuie specificat.

� Se poate utiliza funcţia LenB, care ţine cont de reprezentarea în memorie în UNICODE a stringului. În loc să întoarcă numărul de caractere dintr-un string, LenB întoarce numărul de bytes (octeţi) utilizaţi pentru a reprezenta acel string. Exemplu.

Type CustomerRecord ' Defineşte tipul de date dorit de utilizator. ID As Integer 'Această definiţie este la nivelul modului de cod Name As String * 10 Address As String * 30

End Type '------------------------------ Dim Customer As CustomerRecord ' Declararea variabilelor. Dim MyInt As Integer, MyBan As Currency Dim MyString, MyLen

MyString = "Hello World" ' Iniţializează variabila. MyLen = Len(MyString) ' Întoarce 11. MyLen = Len(Customer) ' Întoarce 42. MyLen = Len(MyInt) ' Întoarce 2. MyLen = Len(MyBan) ' Întoarce 8.

I.7.2.8. Left(string, lungime)

Întoarce un sub-şir de caractere din partea stângă a stringului al căror număr este stabilit de lungime.

� Lungimea este o expresie numerică indicând câte caractere se vor întoarce. Dacă:

Page 42: VBA_SC3_Extras1

I-42

− Lungimea = 0 – se întoarce un string de lungime 0 – cunoscut cu numele de şir vid (""). − Lungimea >= Len(string) – se întoarce întregul string dacă lungimea este mai mare decât numărul de caractere din string.

Pentru a determina numărul de caractere dintr-un string se va utiliza funcţia Len. Exemplu.

Dim Sir, Subsir

Sir = "Nota examen" ' Defineşte stringul. Subsir = Left(Sir, 1) ' Întoarce "N". Subsir = Left(Sir, 7) ' Întoarce "Nota ex". Subsir = Left(Sir, Len(Sir)-2) ' Întoarce "Nota exam". Subsir = Left("Sir",1) ' Întoarce "S"

� A se face distincţie între variabila Sir care este încărcată cu valoarea "Nota examen" şi stringul "Sir" care este scris între ghilimele, el fiind astfel tratat ca o valoare de tip String.

I.7.2.9. Right(string, lungime)

Întoarce un sub-şir de caractere din partea dreaptă a stringului al căror număr este stabilit de lungime (vezi explicaţia anterioară). Exemplu.

Dim Sir, Subsir Sir = "Nota examen" ' Defineşte stringul. Subsir = Right(Sir, 1) ' Întoarce "n" (caracterul de la final)) Subsir = Right(Sir, 8) ' Întoarce "a examen". Subsir = Right(Sir, Len(Sir)-2) ' Întoarce "ta examen". Subsir = Right("Sir",1) ' Intoarce "r" (vezi observaţie funcţia left)

I.7.2.10. Mid(string, start [,lungime])

Întoarce o valoare de tip Variant (String) cuprinzând un număr specificat de caractere dintr-un string.

Parametrii reprezintă: − string (obligatoriu). Expresie string din care sunt întoarse caractere. Dacă stringul conţine

NULL, atunci NULL se va întoarce. − start (obligatoriu). Este de tip Long. Reprezintă poziţia caracterului din string de la care începe

partea ce va fi preluată. Dacă poziţia este mai mare decât numărul de caractere din string, Mid va întoarce un string vid ("") – de lungime 0. Numerotarea caracterelor începe de la 1.

− lungime (opţional); Este de tip Variant (Long). Reprezintă numărul de caractere ce vor fi întoarse. Dacă lipseşte sau dacă este mai mare decât numărul maxim de caractere care mai sunt până la sfârşitul stringului (inclusiv caracterul de început), vor fi întoarse toate caracterele de la poziţia de start până la sfârşit.

� Determinarea numărului de caractere din string se face cu funcţia Len. Exemplu.

Dim SirPrincipal, SubSir1, SubSir2, SubSir3 SirPrincipal = "Universitatea din Pitesti" ' Creează stringul. SubSir1 = Mid(SirPrincipal, 1, 13) ' Întoarce "Universitatea". SubSir2 = Mid(SirPrincipal, 19, 7) ' Întoarce "Pitesti". SubSir3 = Mid(SirPrincipal, 15) ' Întoarce "din Pitesti".

� Mid poate fi folosit şi în partea stângă a unei instrucţiuni de atribuire, caz în care va înlocui din string subşirul specificat, cu stringul specificat de expresia din dreapta instrucţiunii, dar în aşa fel încât să nu se modifice lungimea şirului de caractere.

Această facilitate nu este implementată şi la funcţiile Left sau Right. Exemplu.

Public Sub TestMid () Dim S As String

S = "123456789" Mid(S, 4, 2) = "A" MsgBox S ' Afişează 123A56789 Mid(S, 4, 2) = "AB" MsgBox S ' Afişează 123AB6789

Page 43: VBA_SC3_Extras1

I-43

Mid(S, 4, 2) = "ABC" MsgBox S ' Afişează 123AB6789

End Sub

I.7.2.11. InStr([start,]string1,string2[,compare])

Întoarce o valoare de tip Variant (Long) reprezentând poziţia primei apariţii a string2 în string1. • start (opţional). Expresie numerică care stabileşte poziţia de început pentru fiecare căutare. Dacă

este omis, căutarea începe de la poziţia primului caracter. Argumentul este obligatoriu dacă se specifică o comparaţie.

• string1 (obligatoriu). Şirul de caractere în care se va face căutarea. • string2 (obligatoriu). Şirul de caractere care este căutat. • compare (opţional). Prezintă modalitatea în care se poate face compararea a două stringuri.

Poate fi 0, 1, sau 2. − 0 – implicit – comparare binară, senzitivă; − 1 – comparare textuală, ne-senzitivă, adică fără să se ţină cont de caracterele mari sau mici; − 2 – comparare bazată pe informaţiile din baza de date; − dacă parametrul compare lipseşte, atunci setarea Option Compare din modulul de cod determină tipul comparaţiei.

� Dacă nu se găseşte şirul specificat se întoarce valoarea 0. Dacă unul din şiruri este NULL, atunci NULL se întoarce.

Exemplu. Dim Sir, SirCautat, Pozitie

Sir = "Popescu Panait" ' String în care se caută. SirCautat = "P" ' Se caută "P". 'Următoarele 4 instrucţiuni încep cercetarea de la poziţia 4 Pozitie = Instr (4, Sir, SirCautat, 1) ' Comparaţie textuală. Întoarce 9. Pozitie = Instr (4, Sir, "P", 1) ' Comparaţie textuală. Întoarce 9. Pozitie = Instr (4, Sir, "p", 1) ' Comparaţie textuală. Întoarce 9. Pozitie = Instr (4, Sir, "p", 0) ' Comparaţie binară. Întoarce 0. Pozitie = Instr (1, Sir, "W") ' Implicit comparaţia e binară _ (lipseşte ultimul argument).Întoarce 0.

Exemplu. Private Sub cmdInstr_Click ()

Debug.Print InStr ("Alison Balter", "Balter") ' întoarce 8 Debug.Print InStr ("Hello", "1") ' întoarce 3

End Sub

I.7.2.12. String(număr,caracter)

Întoarce un şir de caractere, care conţine de număr de ori caracterul specificat.

� Dacă în loc de caracter este un număr N caracterul multiplicat va fi Chr(N). Dacă N>255 se va folosi Chr(N Mod 256).

� Dacă al doilea argument conţine un şir de mai multe caractere se va multiplica primul. Exemplu.

Dim MyString

MyString = String(5, "*") ' Întoarce "*****" MyString = String(5, 42) ' Întoarce "*****" – codul Ascii al lui * este 42 MyString = String(10, "ABC") ' Întoarce "AAAAAAAAAA".

I.7.2.13. Space(număr)

� Întoarce un şir de caractere care conţine de număr de ori caracterul spaţiu. Exemplu.

Dim MyString MyString = Space(8) ' întoarce un string cu 8 spaţii MyString = "Hello" & Space(10) & "World" ' Inserează 10 spaţii _ între cele două cuvinte.

Page 44: VBA_SC3_Extras1

I-44

I.7.2.14. Format(expresie[,format])

Funcţia Format transformă o expresie într-un şir de caractere care respectă un şablon (format). • Expresie – este expresia pe care doriţi să o formataţi. • Format (opţional) reprezintă tipul de format, şablon, pe care doriţi să îl aplicaţi. El este ori un

nume valid de format (de ex. "Long Time" sau "hh:mm:ss AMPM") ori un format creat (definit) de utilizator.

Exemplu. Private Sub cmdFormat_Click ()

Dim MyTime, MyDate, MyStr MyTime = #5:04:23 PM# MyDate = #1/27/93# ' Se vor folosi şi următoarele funcţii care întorc timpul şi data _ curentă a sistemului de calcul: ' NOW () =întoarce data şi timpul ' TIME () =întoarce timpul ' DATE () =întoarce data MyStr = Format(Time (), "Long Time") MsgBox MyStr ' Afişează timpul curent al sistemului de calcul, în _ formatul definit în Windows pentru "Long Time" MyStr = Format(Date, "Long Date") MsgBox MyStr ' Afişează data curentă a sistemului de calcul, în _ formatul definit în Windows pentru "Long Date" MyStr = Format(MyTime, "h:m:s") ' Întoarce "17:4:23". MsgBox MyStr MyStr = Format(MyTime, "hh:mm:ss AMPM") ' Întoarce _ "05:04:23 PM". MsgBox MyStr MyStr = Format(MyDate, "dddd, mmm d yyyy") ' Întoarce _ "Miercuri, Ian 27 1993". MsgBox MyStr ' Dacă parametrul format lipseşte se va întoarce un string. MyStr = Format(23) ' Întoarce "23". MsgBox MyStr ' Formate definite de utilizator. Se folosesc în continuare următoarele _ caractere pentru format: _ # – Întoarce cifra dacă există. Dacă nu există se întoarce "blanc" _ 0 – Întoarce cifra dacă există. Dacă nu există se întoarce 0 _ , – Întoarce separatorul de grupe de cifre (în sistemul românesc,_ virgula sau american, punctul) definit în Windows (System settings). _ . – Întoarce semnul pentru punctul zecimal definit în Windows _ % – Întoarce în procente MyStr = Format(5459.4, "##, ##0.00") ' Întoarce "5,459.40" - _ System settings în Windows este U.S. MsgBox MyStr MyStr = Format(334.9, "###0.00") ' Întoarce "334.90". MsgBox MyStr MyStr = Format(5, "0.00%") ' Întoarce "500.00%". MsgBox MyStr ' Formate definite de utilizator. Se folosesc în continuare următoarele _ caractere pentru format: ' < – Întoarce stringul cu litere mici ' > – Întoarce stringul cu litere mari MyStr = Format("HELLO", "<") ' Întoarce "hello". MsgBox MyStr MyStr = Format("This is it", ">") ' Întoarce "THIS IS IT". MsgBox MyStr MsgBox Format(50, "Currency") '50.00 LEI – Afişează în sistemul _ de valută definit în Windows (System settings) MsgBox Format(Now(), "Short Date") ' 8/5/95 – Afişează în _ formatul definit pentru "dată scurtă" MsgBox Format(Now(), "DDDD") 'Afişează cuvântul pentru zi MsgBox Format(Now(), "DDD") 'Afişează ziua prescurtat (pe 2, 3 _ caractere) MsgBox Format(Now(), "YYYY") 'Afişează anul din patru cifre

End Sub

Page 45: VBA_SC3_Extras1

I-45

I.7.3. Funcţii pentru tablouri (array) - UBound ş i LBound

UBound (arrayname[,dimension]) LBound (arrayname[,dimension])

Întorc o valoare de tip Long, care va conţine, pentru o anumită dimensiune a unui tablou: � Pentru UBound: valoarea indicelui celui mai mare disponibil (marginea superioară). � Pentru LBound: valoarea indicelui celui mai mic disponibil (marginea inferioară). Sintaxa celor două funcţii cuprind: − arrayname (obligatoriu). Denumirea variabilei care defineşte tabloul. − dimension (opţional). Este de tip Variant (Long). Indică dimensiunea a cărei margine

(superioară sau inferioară) este întoarsă. Se utilizează 1 pentru prima dimensiune, 2 pentru a doua etc. Dacă lipseşte, automat va fi 1.

Funcţia UBound se utilizează împreună cu funcţia LBound pentru a determina mărimea unui tablou, şi anume:

• LBound – pentru a găsi cea mai joasă valoare a dimensiunii unui tablou. • UBound – pentru a găsi cea mai mare valoare a dimensiunii unui tablou.

Exemplu. Pentru tabloul cu dimensiunile: Dim A(1 To 100, 0 To 3, -3 To 4) UBound şi LBound întorc următoarele valori:

Funcţia Parametrii Valoarea întoarsă (A, 1) 100 (A, 2) 3 UBound (A, 3) 4 (A, 1) 1 (A, 2) 0 LBound (A, 3) –3

Marginea cea mai de jos, implicită, pentru orice dimensiune a unui tablou creat prin declaraţie (Dim, Private, Public, ReDim sau Static), este 0 sau 1. Ea depinde de setarea declaraţiei Option Base (de obicei 0).

Excepţie. Baza unui tablou creat cu funcţia Array este 0, ea nefiind afectată de Option Base. Tablourile pentru care dimensiunile sunt setate folosind To în declaraţiile Dim, Private, Public,

ReDim sau Static pot lua orice valoare întreagă ca fiind marginea cea mai de jos (cel mai mic indice).

I.7.4. Funcţii de conversie

I.7.4.1. Str(Număr)

Transformă un număr într-un şir de caractere. • Număr – argumentul funcţiei, de tip Long, va conţine o expresie numerică ce va fi convertită

într-un şir de caractere. • După conversie, la începutul stringului va fi un spaţiu pentru numerele pozitive sau semnul (–)

pentru numerele negative. • Punctul zecimal va fi reprezentat întotdeauna de semnul punct(.), indiferent de cum este setat

acesta în Windows (ca punct sau ca virgulă). • Pentru transformarea numerelor în stringuri, cu folosirea altor reguli de prezentare, se foloseşte

funcţia Format. Exemplu.

Dim MyString MyString = Str(459) ' Întoarce "459". MyString = Str(-459.65) ' Întoarce "-459.65". MyString = Str(459.001) ' Întoarce " 459.001".

I.7.4.2. Val(string)

Întoarce numărul conţinut în string, ca pe o valoare numerică de tipul cel mai apropiat reprezentării valorii respective.

• Funcţia Val, în momentul în care întâlneşte un caracter care nu poate face parte din reprezentarea unui număr, opreşte inspecţia şi face conversia numai până la acest caracter.

• Printre caracterele care nu sunt recunoscute de funcţia Val, sunt şi virgula (,) sau semnul dolar ($).

Page 46: VBA_SC3_Extras1

I-46

• &O şi &H, sunt considerate ca rădăcină pentru numere în reprezentarea octală, respectiv hexazecimală.

• Spaţiile, tab-ul şi LF nu se iau în considerare (se sar). • Punctul zecimal va fi reprezentat întotdeauna de semnul punct (.).

Exemplu. Dim MyValue MyValue = Val("2457") ' Întoarce 2457. MyValue = Val(" 2 45 7") ' Întoarce 2457. MyValue = Val("24 and 57") ' Întoarce 24. MyValue = Val(" 1615 198th Street N. E.") ' Întoarce 1615198

I.7.5. Funcţii pentru mesaje

I.7.5.1. MsgBox(prompt[,buttons][,title])

Afişează un mesaj într-o căsuţă de dialog, aşteaptă utilizatorul să apese un buton şi întoarce o valoare de tip Integer care indică codul butonului apăsat.

Sintaxa funcţiei MsgBox cuprinde următoarele argumente: • Prompt (obligatoriu). Expresie de tip string afişată ca mesaj în caseta de dialog. Lungimea sa

maximă este de aproximativ 1024 caractere, depinzând de mărimea caracterelor folosite. Dacă promptul este compus din mai mult de un rând, se pot separa liniile utilizând un caracter CR=Chr(13), un caracter LF=Chr(10), sau o combinaţie (Chr(13) & Chr(10) ) după fiecare rând.

� În VBA, există definită constanta de tip string: vbCr=Chr(13) & Chr(10) • Buttons (opţional - implicit este 0). Expresie numerică care este suma valorilor reprezentând

patru caracteristici ale căsuţei de mesaj şi anume: − ce butoane se afişează (OK, Cancel, Yes, No, Retry, Ignore); − care este butonul care se va considera implicit; − ce pictogramă se afişează; − faţă de ce este modală caseta de mesaj: aplicaţie sau sistem (nu se poate ieşi din aceasta în aplicaţie/ sistem până nu se închide).

Setările pentru butoanele argument sunt:

Constanta Val Descrierea Ce reprezintă

VbOKOnly 0 Afişează numai butonul OK. VbOKCancel 1 Afişează butoanele OK şi Cancel. VbAbortRetryIgnore 2 Afişează butoanele Abort, Retry şi Ignore. VbYesNoCancel 3 Afişează butoanele Yes, No şi Cancel. VbYesNo 4 Afişează butoanele Yes şi No. VbRetryCancel 5 Afişează butoanele Retry şi Cancel.

Numărul şi tipul butoanelor afişate în caseta de dialog

VbCritical 16 Afişează pictograma Critical Message. VbQuestion 32 Afişează pictograma Warning Query. VbExclamation 48 Afişează pictograma Warning Message VbInformation 64 Afişează pictograma Information Message.

Felul pictogramei utilizate în partea din stânga sus

VbDefaultButton1 0 Primul buton este implicit. VbDefaultButton2 256 Al doilea buton este implicit. VbDefaultButton3 512 Al treilea buton este implicit. VbDefaultButton4 768 Al patrulea buton este implicit.

Care este butonul implicit

VbApplicationModal 0 Aplicaţie modală – utilizatorul trebuie să răspundă casetei de mesaj înainte de a continua să lucreze în aplicaţia curentă.

VbSystemModal 4096 Sistem modal – toate aplicaţiile sunt blocate până când utilizatorul răspunde casetei de mesaj.

Dacă caseta de text este modală la nivelul aplicaţiei curente sau a tuturor taskurilor

− Title (opţional). Expresie de tip string afişată pe bara de titlu a casetei de dialog. Dacă lipseşte, se va plasa pe bara de titlu numele aplicaţiei.

Valoarea întoarsă de funcţie este:

Page 47: VBA_SC3_Extras1

I-47

Constanta Valoare Butonul pe care s-a apăsat

vbOK 1 OK vbCancel 2 Cancel vbAbort 3 Abort vbRetry 4 Retry vbIgnore 5 Ignore vbYes 6 Yes vbNo 7 No

� Aceste constante sunt definite în VBA. În consecinţă, numele acestea pot fi utilizate oriunde în program în locul valorilor respective.

� MsgBox poate fi utilizată şi ca procedură. În acest caz parametrii nu se mai scriu între paranteze. În această formă este folosită numai pentru afişarea unui mesaj. Exemplu.

Public Sub TestMsgBox () Dim Rasp As Integer Dim Nr As Integer Const LimInf = -100 Const LimSup = 100 ' Generează o valoare aleatoare întreagă între LimInf şi LimSup Randomize Nr = Int((LimSup - LimInf + 1) * Rnd + LimInf) ' MsgBox folosit ca funcţie ' Afişează mesaj, şi introduce în Rasp, butonul apăsat de utilizator _ Se observă folosirea lui at ( @ ) ca separator de rânduri!! Rasp = MsgBox("Doriti modificarea semnului numarului " & _ Nr & " extras? @ -Yes=Il face pozitiv; @ -No=Il face negativ; ", _ vbYesNoCancel + vbQuestion + vbDefaultButton3 + vbSystemModal, _ "Exemplu parametrii MsgBox") If Rasp = vbYes Then

Nr = Abs(Nr) ElseIf Rasp = vbNo Then

Nr = Abs(Nr) * -1 Else 'Cancel - Lasă numărul neschimbat End If MsgBox "Numarul prelucrat este: " & Nr, vbInformation End Sub 'Se observă mai sus folosirea lui MsgBox ca pe o procedură

I.7.5.2. InputBox(prompt[,title][,default][,X][,Y])

Afişează un mesaj într-o casetă, aşteaptă ca utilizatorul să introducă un text sau/şi să apese un buton şi întoarce o valoare (string) ce conţine acest text.

Sintaxa funcţiei InputBox cuprinde următoarele argumente: • Prompt (obligatoriu). Expresie de tip string afişată ca mesaj în caseta de dialog. Lungimea sa

maximă este de aproximativ 1024 caractere, depinzând de mărimea caracterelor folosite. Dacă promptul este compus din mai mult de un rând, se pot separa liniile utilizând un caracter CR(carriage return) Chr(13), un caracter LF(line feed) Chr(10), sau o combinaţie (Chr(13) & Chr(10) ) după fiecare rând.

• Title (opţional). Expresie de tip string afişată pe bara de titlu a casetei de dialog. Dacă titlul lipseşte, se va plasa pe bara de titlu numele aplicaţiei.

• Default (opţional). Expresie de tip string afişată în caseta de text ca răspuns implicit dacă utilizatorul nu introduce nimic. Dacă lipseşte, caseta de text va fi afişată goală.

• X (opţional). Expresie numerică care reprezintă, în twips, distanţa pe orizontală de la marginea din stânga a casetei de dialog la marginea din stânga a ecranului. Dacă lipseşte, caseta de dialog este centrată orizontal.

• Y (opţional). Expresie numerică care reprezintă, în twips, distanţa pe verticală de la marginea de sus a casetei de dialog la marginea de sus a ecranului. Dacă lipseşte, caseta de dialog este poziţionată vertical la aproximativ o treime din distanţa până în subsolul ecranului. Exemplu.

Page 48: VBA_SC3_Extras1

I-48

Următorul exemplu utilizează InputBox pentru a citi o dată introdusă de utilizator şi folosirea lui MsgBox şi ca funcţie şi ca procedură (pentru afişarea unor mesaje). Se observă utilizarea semnului @ pentru a delimita diversele părţi ale şirului de caractere.

Sub CustomMessage ()

Dim strMsg As String, strInput As String ' Iniţializează stringul. strMsg = "Număr în afara intervalului. @ Aţi introdus un număr _ care este mai mic decât 1 şi mai mare ca 10. @ Apăsaţi OK pentru a _ introduce numărul din nou." ' @ - rol de delimitator de rânduri ' Se cere utilizatorului să introducă o valoare. strInput = InputBox("Introduceţi un număr între 1 şi 10. ") If strInput <> "" Then ' Testează ca valoarea intodusă să nu fie şir vid

Do While (strInput < 0 Or strInput > 10) If MsgBox(strMsg, vbOKCancel, "Error!") = vbOK Then

strInput = InputBox("Introduceţi număr între 1şi 10") Else

Exit Sub End If

Loop ' Afişează data corectă introdusă de utilizator.

MsgBox "Aţi introdus numărul" & strInput & ". " Else ' nu s-a introdus nimic

Exit Sub End If

End Sub

I.7.6. Funcţii cu tipul: Date/ Time

I.7.6.1. DatePart(interval,date)

Funcţia DatePart întoarce o parte dintr-o dată, care este specificată de argumentul interval. Argumentul interval, de tip string, poate lua următoarele valori:

interval Descriere interval Descriere

yyyy Anul w Ziua din săptămână q Trimestrul ww Săptămâna m Luna h Ora y Ziua din an n Minute d Ziua s Secunde

Exemplu. Private Sub cmdDatePart_Click ()

MsgBox DatePart("YYYY", Now) ' Afişează anul curent MsgBox DatePart("M", Now) ' Afişează numărul lunii curente MsgBox DatePart("Q", Now) ' Afişează nr. trimestrului curent MsgBox DatePart("Y", Now) ' Afişează ziua din anul curent

End Sub

I.7.6.2. DateDiff(interval,date1,date2)

Funcţia DateDiff întoarce intervalul de timp dintre două date, deci date2-date1. Unitatea de timp este specificată de argumentul interval. Exemplu.

Private SubcmdDateDiff_Click () MsgBox DateDiff("d",Now,#12/31/02#) ' Nr. zile până la 12/31/02 MsgBox DateDiff("m",Now,#12/31/02#) ' Nr. luni până la 12/31/02 ' Numărul de ani până la 12/31/02 MsgBox DateDiff("yyyy",Now,#12/31/02#) ' Numarul trimestrelor până la 12/31/02 MsgBox DateDiff("q",Now,#12/31/02#)

End Sub

Page 49: VBA_SC3_Extras1

I-49

I.7.6.3. DateAdd(interval,number,date)

Funcţia DateAdd întoarce rezultatul adăugării sau scăderii unei perioade specifice de timp, precizate prin argumentul interval, la o (dintr-o) dată stabilită.

Private Sub cmdDateAdd_Click () MsgBox DateAdd("d", 3, Now) ' Ziua de azi plus 3 zile MsgBox DateAdd("m", 3, Now) ' Ziua de azi plus 3 luni MsgBox DateAdd("yyyy", 3, Now) ' Ziua de azi plus 3 ani MsgBox DateAdd("q", 3, Now) ' Ziua de azi plus 3 trimestre

End Sub

I.7.6.4. Day(date); Month(date); Year(date)

Întoarce un Variant (Integer), care conţine ziua sau luna sau anul, din data care se găseşte în argumentul funcţiei.

I.7.6.5. Second(date); Minute(date); Hour(date)

Întoarce un Variant (Integer), care conţine secunda sau minutul sau ora, din data care se găseşte în argumentul funcţiei.

I.7.6.6. Now(); Date(); Time()

Now() - întoarce un Variant (Date), care conţine data şi timpul curent (cu care este setat în momentul respectiv sistemul de calcul).

Date() - întoarce un Variant (Date), care conţine data curentă (cu care este setat în momentul respectiv sistemul de calcul).

Time() - întoarce un Variant (Date), care conţine timpul curent (cu care este setat în momentul respectiv sistemul de calcul).

I.7.6.7. DateSerial(year, month, day)

Întoarce un Variant(Date) care va conţine data calendaristică specificată în argumentele: year, month şi day.

Descrierea argumentelor: − Year (obligatoriu); Integer. Număr între 100 şi 9999 inclusiv, sau expresie numerică. − Month (obligatoriu); Integer. Orice expresie numerică. − Day (obligatoriu); Integer. Orice expresie numerică. Pentru a specifica o dată, de exemplu December 31, 1991, valoarea fiecărui parametru trebuie să fie

validă, adică ziua între 1-31 şi luna între 1-12. Exemplul următor va întoarce o dată, exprimată relativ faţă de altă dată. Se observă că operaţiile se

fac specific pentru zile şi luni, ţinându-se cont de numărul de zile şi luni. Astfel ziua (1 - 1) din luna (8 - 2), ar trebui să fie 0/6, dar practic dacă scădem o zi din 1 iunie, avem 31/Mai. Deci, DateSerial(1990 - 10, 8 - 2, 1 - 1) va fi: 31/Mai/1980.

Dacă argumentul pentru an este între 0 şi 99, se vor considera anii din două cifre setaţi în Windows. Pentru ceilalţi ani trebuiesc introduse 4 cifre.

Dacă un argument este dat în afara intervalului acceptat, atunci se va întoarce o dată care este practic mărită cu numărul de zile sau luni care depăşesc valoarea maximă pentru argumentul respectiv.

De exemplu MsgBox (DateSerial(1998, 11, 32) ) va afişa 2/12/1998. Exemplu.

Dim OData As Date OData = DateSerial(1969, 2, 12) 'Întoarce data - February 12, 1969.

I.7.6.8. TimeSerial(hour, minute, second)

Întoarce un Variant(Date) care va conţine timpul pentru o anumită oră, minut şi secundă, specificată în argumentele: hour, minute, second. Exemplu.

Dim Timpul As Date Timpul = TimeSerial(16, 35, 17) 'Reprezentatre timp - 4:35:17 PM

Page 50: VBA_SC3_Extras1

I-50

I.7.7. Funcţii: structuri de control

I.7.7.1. IIf(condiţie, TruePart, FalsePart)

Funcţia IIf are o acţiune asemănătoare cu a instrucţiunii If…Then…Else Funcţia IIf întoarce unul din cele două argumente, TruePart sau FalsePart, în funcţie de rezultatul

evaluării condiţiei ce se găseşte în primul argument. Astfel, dacă: − condiţie = true – funcţia întoarce parametrul TruePart; − condiţie = false – funcţia întoarce parametrul FalsePart.

� Toţi cei trei parametri ai funcţiei sunt obligatorii.

� TruePart sau FalsePart pot la rândul lor să conţină o altă funcţie, deci şi un alt IIF, ceea ce permite realizarea unor structuri complexe de teste. Exemplu.

Function TestIF(TestMe As Integer) as String TestIF = IIf(TestMe > 1000, "Large", "Small")

End Function Dacă va fi folosită în: MsgBox TestIF(1500) ' afişează Large MsgBox TestIF(500) ' afişează Small

I.7.7.2. Choose(index, caz-1[,caz-2,. . . [,caz-n]])

Funcţia Choose întoarce unul din argumentele listei (caz-1 sau caz-2, sau … caz_n) în funcţie de valoarea pe care o are argumentul index, şi anume:

− dacă index = 1 atunci se întoarce caz-1; − dacă index = 2 atunci se întoarce caz-2; − dacă index = n atunci se întoarce caz-n.

� Dacă index < 1, sau index > n, atunci Choose întoarce valoarea Null. Exemplu.

Function GetChoice(Ind As Integer) as String GetChoice = Choose(Ind, "Speedy", "United", "Federal")

End Function 'La apelul funcţiei vom avea: MsgBox GetChoice(2) ' afişează United Dim X As Variant X = GetChoice(5) ' X se va face Null

I.7.7.3. Switch(expr-1,value-1[,expr-2,value-2… [,expr-n,value-n]]..])

Această funcţie are o acţiune asemănătoare cu a instrucţiunii: If…Then…ElseIf…Else Funcţia Switch va evalua în ordine condiţiile expr-1, expr-2, expr-n, pînă când va obţine o valoare

True. În acest moment, cercetarea se opreşte, şi funcţia întoarce valoarea pereche care se găseşte în argumentul value_?. Deci:

− Dacă expr-1 = True atunci se întoarce value-1, şi gata… − Dacă expr-1 = False atunci trece la evaluarea următoare − Dacă expr-2 = True atunci se întoarce value-2, şi gata… − Dacă expr-2 = False atunci trece la evaluarea următoare, etc.

� Dacă nici una din expresiile evaluate nu este True, Switch întoarce Null. Exemplu.

Function MatchUp(CityName As String) as String

MatchUp = Switch(CityName = "London","English",CityName _ = "Rome", "Italian", CityName = "Paris", "French")

End Function

'La apelul funcţiei vom avea: MsgBox MatchUp("Paris") ' afişează French

Page 51: VBA_SC3_Extras1

I-51

I.7.8. Funcţii de inspecţ ie

I.7.8.1. IsNull(expresie)

Întoarce o valoare de tip Boolean care indică dacă expresia transmisă ca parametru de intrare conţine date care nu sunt valide, adică au valoarea Null.

Parametrul este de tip Variant şi conţine o expresie de tip numeric sau string. Funcţia IsNull întoarce: � True – dacă parametrul are valoarea Null; � False – dacă parametrul nu are valoarea Null;

� Aşa cum am mai arătat, dacă un termen al expresiei este Null, atunci expresia va fi tot Null, şi funcţia va întoarce evident True.

� Valoarea Null, îndică faptul că un Variant nu conţine date valide. Mai există încă două valori speciale, Empty şi String vid (gol) care pot fi uşor confundate cu Null, ceea ce constituie o eroare. Deci reamintim că:

• NULL – variabilă variant în care datele nu sunt valide; • EMPTY – variabilă variant care nu a fost îniţializată; • String de lungime 0 (vid, gol) – string care nu are nimic în el, adică este "".

Exemplu. Dim Valoare, Situatie ' variabile variant Situatie = IsNull(Valoare) ' Întoarce False, deoarece este Empty Valoare = "" Situatie = IsNull(Valoare) ' Întoarce False, deoarece este string vid _ (de lungime 0). Valoare = Null Situatie = IsNull(Valoare) ' Întoarce True.

I.7.8.2. IsEmpty(NumeVariabila)

Întoarce o valoare de tip Boolean care indică dacă o variabilă, transmisă ca parametru de intrare, este sau nu EMPTY, adică iniţializată.

Parametrul este de tip variant şi conţine o dată de tip numeric sau string. Funcţia IsEmpty întoarce: � True – dacă variabila NumeVariabila nu este iniţializată, sau a fost introdusă în ea direct Empty; � False – variabila a fost iniţializată (chiar cu Null sau un string vid).

Exemplu. Dim Valoare, Situatie ' variabile variant Situatie = IsEmpty(Valoare) ' Întoarce True. Valoare = Null ' Assign Null. Situatie = IsEmpty(Valoare) ' Întoarce False. Valoare = Empty ' Assign Empty. Situatie = IsEmpty(Valoare) ' Întoarce True.

I.7.8.3. IsMissing(NumeParametru)

IsMissing se foloseşte într-o rutină, pentru a testa dacă un parametru opţional al acesteia a fost sau nu introdus în lista parametrilor actuali de la apelarea acestei rutine.

Parametrul funcţiei IsMissing, NumeParametru, este de tip variant. Aceste (NumeParametru) reprezintă parametrul formal optional care se testează dacă a fost

introdus sau nu în lista parametrilor actuali la apelul funcţiei. Funcţia IsMissing întoarce o valoare de tip Boolean, care va avea valoarea TRUE numai dacă

parametrul opţional testat nu a fost introdus în lista parametrilor actuali, deci el practic lipseşte. Exemplu. Apelarea funcţiei ReturnTwice, definită cu un parametru opţional.

Dim ReturnValue ReturnValue = ReturnTwice() ' Întoarce Null. ReturnValue = ReturnTwice(2) ' Întoarce 4. ' Declararea funcţiei. Function ReturnTwice(Optional A)

If IsMissing (A) Then ' Funcţia a fost apelată fără parametrul A ReturnTwice = Null

Else ' Funcţia a fost apelată cu parametrul A

Page 52: VBA_SC3_Extras1

I-52

ReturnTwice = A * 2 End If

End Function

� Funcţia IsMissing se aplică numai dacă parametrul opţional este de tip variant. Dacă parametrul opţional nu este de tip variant ea va întoarce întotdeauna (fie că parametrul opţional este sau nu este folosit la apelarea funcţiei) valoarea FALSE.

I.7.8.4. VarType(NumeVariabilă)

Întoarce un Integer, care precizează tipul de date ce se găseşte în variabila de tip variant: NumeVariabilă (care este argumentul funcţiei).

Reamintim că variabilele de tip variant se caracterizează prin faptul că în ele se pot introduce valori de diferite tipuri. Funcţia VarType tocmai acest rol are, să ne indice la un moment dat ce tip de date se găsesc într-o variabilă de tip variant. Rezultatul întors de funcţia VarType:

Constanta Val Descriere Constanta Val Descriere

vbEmpty 0 Empty (neiniţializat) vbObject 9 Object

vbNull 1 Null (lipsa datelor valide) vbError 10 Error

vbInteger 2 Integer vbBoolean 11 Boolean – valoare

vbLong 3 Long integer vbVariant 12 Variant (în tablouri)

vbSingle 4 Single-precision vbDataObject 13 Obiect de acces la date

vbDouble 5 Double-precision vbDecimal 14 Decimal – valoare

vbCurrency 6 Currency – valoare vbByte 17 Byte – valoare

vbDate 7 Date – val. de tip Date/Text vbArray 8192 Array – Tablou

vbString 8 String

� Constantele fiind definite în VBA, ele pot fi utilizate oriunde în loc de valorile specificate. Exemplu.

' Variabile declarate variant, deoarece lipseşte tipul de data Dim IntVar, StrVar, DateVar, MyCheck ' Iniţializarea variabilelor IntVar = 459: StrVar = "Hello World": DateVar = #2/12/69# ' !!! Aşa se pot scrie mai multe instrucţiuni pe un rând, separându-le, _ aşa cum se vede, cu două puncte. MyCheck = VarType(IntVar) ' Întoarce 2. MyCheck = VarType(StrVar) ' Întoarce 8. MyCheck = VarType(DateVar) ' Întoarce 7.

I.7.9. Funcţiile agregate SQL

O funcţie agregată SQL este specifică prin faptul că datele ei de intrare sunt valorile unui câmp dintr-o tabelă (cerere) – care este legată de obiectul în care se foloseşte, adică cerere, tabel, formular sau raport –, din toate sau o parte din înregistrări.

Ele calculează expresii al căror domeniu de aplicabilitate este un câmp al tabelei (cererii) care se utilizează în obiectul unde sunt folosite. În cazul rapoartelor sau formularelor, funcţiile agregate SQL se calculează pe tabela (cererea) legată la acesta.

Funcţiile agregate SQL au ca argument numele câmpului pe care sunt definite. Totuşi, în cazul cererilor cu clauză total, în care introducerea funcţiei agregate SQL se face într-o coloană ataşată câmpului de definiţie, ele se folosesc fără argument.

Funcţiile agregate SQL sunt: − Sum – calculează suma valorilor pe un câmp; − Max, Min – întoarce valoarea maximă/ minimă a unui câmp; − Avg – calculează media aritmetică a valorilor unui câmp; − Count – numărul de înregistrări ale câmpului (diferite de NULL). Dacă se doreşte să se ia în calcul şi câmpurile cu valoarea NULL, atunci se va folosi expresia

COUNT(*). − Var, VarP, StDev, StDevP–calcule statistice (varianţa şi deviaţia standard).

Page 53: VBA_SC3_Extras1

I-53

� Valoarea NULL, în funcţiile agregate (SQL sau de domeniu), nu se ia în considerare. În celelalte funcţii sau operaţii, valoarea NULL a unui termen duce la rezultatul NULL al expresiei, indiferent de felul în care e constituită aceasta.

I.7.10. Funcţiile agregate de domeniu

Funcţiile agregate de domeniu întorc date de calcul agregate, la fel ca şi funcţiile agregate SQL. Diferenţa rezultă din faptul că domeniul de definiţie al acestor funcţii este reprezentat de un câmp al unei tabele (cereri) – din baza de date curentă – asupra căruia se aplică, eventual, un criteriu de selecţie a înregistrărilor. Domeniul de definiţie este stabilit de valorile ce se găsesc în parametrii (argumentele) funcţiei.

Funcţiile agregate de domeniu, (au aceiaşi denumire ca a funcţiilor agregate SQL, dar cu litera D în faţă) sunt:

− DSum – calculează suma valorilor pe un câmp; − DMax, Dmin – întoarce valoarea maximă/ minimă a unui câmp; − DAvg – calculează media aritmetică a valorilor unui câmp; − DCount – numărul de înregistrări ale câmpului (diferite de NULL); − DVar, DVarP, DStDev, DStDevP – calcule statistice (varianţa şi deviaţia standard); − DLookUp – întoarce prima valoare întâlnită în domeniul selecţionat. (aceasta nu are echivalent

în funcţiile agregate SQL). Argumentele folosite sunt aceleaşi în toate aceste funcţii şi stabilesc, aşa cum am mai arătat, care

este domeniul de definiţie pe care se calculează valoarea agregată. DFuncţie (NumeCâmp, NumeTabela[, Criteriu])

• NumeCâmp, NumeTabela – sunt stringuri care stabilesc care este câmpul şi tabela (cererea) asupra căreia se fac calculele agregate.

• Criteriu – este un string prin care se introduce un criteriu de selecţie a înregistrărilor din domeniul specificat de primii doi parametri. Dacă nu este prezent acest parametru, se vor lua în calcul datele din câmpul respectiv din toate înregistrările tabelei specificate.

� Dacă nu se selecţionează datorită criteriului nici o înregistrare, funcţia întoarce valoarea NULL.

Exemplu. Dim varX As Variant, iNr As Integer, sSir As String

' cazul 1 – selecţia înregistrărilor din tabela Studenti cu CodStudent _ având valoarea <100 – întoarce dintre acestea valoarea Nume cea mai mare în ordinea de _ sortare. – CodStudent (care e folosit în criteriu) este de tip numeric şi a fost _ comparat cu un LITERAL varX = DMax ("[Nume]", "Studenti", "[CodStudent]<100") ' cazul 2 – selecţia înregistrărilor cu Nume având valoarea 'Doru' _

– întoarce dintre acestea valoarea Anul cea mai mică – Nume (care e folosit în criteriu) este de tip text şi a fost comparat cu un _ LITERAL

varX = DMin ("[Anul]", "Studenti", "[Nume]='Doru' ")

' cazul 3 – selecţia înregistrărilor cu CodStudent având valoarea < cea din _ variabila numerică iNr

– întoarce dintre acestea valoarea Nume cea mai mare în ordinea de _ sortare. – CodStudent (care e folosit în criteriu) este de tip numeric şi a fost _ comparat cu o dată care se găseşte într-o variabilă iNr = 100 varX = DMax ("[Nume]", "Studenti", "[CodStudent]<" & Nr) ' cazul 4 – selecţia înregistrărilor cu Nume având valoarea ce se găseşte _ în variabila string sSir – întoarce dintre acestea valoarea Anul cea mai mică – Nume (care e folosit în criteriu) este de tip text şi a fost comparat cu o dată care se găseşte într-o variabilă sSir = "Doru" varX = DMin ("[Anul]", "Studenti", "[Nume]='" & sSir & "'")

Se observă că în formarea criteriului este foarte important dacă criteriul se va aplica pe un câmp numeric sau de tip text. În cazul când avem de-a face cu un câmp text valoarea cu care se face compararea trebuie la rândul ei să fie string, deci încadrată din nou între ghilimele (2 ghilimele într-un string delimitat

Page 54: VBA_SC3_Extras1

I-54

de ghilimele sunt considerate ca un semn ghilimea) sau un apostrof. Deci "[Nume]='Doru' " este echivalent cu "[Nume]=""Doru"" "

Lucrurile se complică în momentul în care criteriul pe care îl introducem va compara un câmp cu o valoare ce se află într-o variabilă, ca în cazurile 3 şi 4. Important este să ştim că forma de scriere a criteriului este diferită în funcţie de natura câmpului folosit de criteriu, număr sau text.

� Reamintesc că valoarea NULL, în funcţiile agregate (de domeniu sau SQL), nu se ia în considerare. În celelalte funcţii sau operaţii, valoarea NULL a unui termen duce la rezultatul NULL al expresiei, indiferent de felul în care e constituită aceasta.