Sunt cazuri când trebuie testate două sau mai multe condiții înainte de a face o acțiune:
Dacă afirmația X este adevărată și afirmația Y este adevărată, atunci se face o acțiune; dacă afirmația X este adevărată sau afirmația Y este adevărată, atunci se face o altă acțiune; dacă afirmația X este adevărată și afirmația Y nu este adevărată, atunci se face altceva și asa mai departe.
De exemplu, dacă plouă și este rece, se ia echipamentul de ploaie care ține și cald.
Pentru a testa mai multe condiții, se folosesc operatorii logici VBA pentru a conecta condițiile. Tabelul următor prezintă operatorii logici pe care îi suportă VBA, cu exemple și comentarii scurte.
Dintre acești șase operatori logici, cel mai mult se folosesc operatorii de conjuncție (And), disjuncție (Or) și negare (Not), iar ceilalți trei se folosesc în ocazii speciale (rare).
VBA nu folosește evaluarea în scurt-circuit
De reținut la evaluarea condițiilor multiple: VBA nu folosește evaluarea în scurt-circuit în expresiile logice (spre deosebire de alte limbaje de programare, cum ar fi C și C++).
Evaluarea în scurt-circuit este un termen folosit pentru o tehnică simplă de logică folosită de majoritatea oamenilor atunci când iau decizii în fiecare zi: dacă prima sau mai multe condiții dependente sunt false, nu se mai pierde timp pentru evaluarea altor condiții suplimentare.
De exemplu, presupunem că se dă o masă gratuită dacă se livrează la timp un produs și se primește și o promoție. Dacă produsul nu este livrat la timp, șansele de a primi promoția sunt zero. A doua condiție nu se mai evaluează, deoarece rezultatul necesită îndeplinirea ambelor condiții și prima condiție nu a fost îndeplinită. Deci, se scurtcircuitează (se sare) orice testare suplimentară a stării.
VBA nu gândește astfel. Evaluează și a doua condiție (și alte condiții ulterioare), chiar dacă nu e nevoie. Evaluarea tuturor condițiilor ia mai mult timp (acum nu mai constituie o problemă), dar poate introduce complicații neașteptate în cod (lucru care poate fi o problemă).
De exemplu, codul următor produce o eroare atunci când selecția conține doar un caracter. Eroarea apare deoarece codul se termină la executarea funcției Mid cu un șir de lungime zero (selecția de un caracter minus un caracter) - chiar dacă această condiție nu ar trebui să fie evaluată atunci când prima condiție nu este îndeplinită (deoarece lungimea selecției nu este mai mare de 1):
Dim strLitera As String
strLitera = Selection.Text
If Len(strLitera) > 1 And _
Mid(strLitera, Len(strLitera) - 1, 1) = "T" Then
MsgBox "A doua litera este T.", vbInformation, "A doua litera"
End If
Pentru a evita acest tip de probleme, se folosesc blocuri If imbricate (nested). În următorul exemplu de cod, prima condiție nu este îndeplinită (din nou, pentru selecția unui singur caracter), așa că a doua condiție nu mai este evaluată. Se poate vedea cum un bloc If este imbricat în (conținut de) celălalt bloc If:
Dim strLitera As String
strLitera = Selection.Text
If Len(strLitera) > 1 Then
If Mid(strLitera, Len(strLitera) - 1, 1) = "T" Then
MsgBox "A doua litera este T.", vbInformation, "Penultima litera"
End If
End If
Folosirea NOT pentru a modifica proprietățile booleene
Iată un truc util. Comanda Not este o modalitate la îndemână pentru a comuta între True și False. Folosind Not cu o variabilă sau proprietate booleană, se poate comuta starea variabilei sau a proprietății fără a mai verifica care este starea curentă. De exemplu, în Excel, se poate crea o structură If pentru a comuta proprietatea Boolean pentru variabila Saved (care controlează dacă Excel consideră că documentul activ conține modificări nesalvate) folosind cod, astfel:
If ActiveWorkbook.Saved = True Then
ActiveWorkbook.Saved = False Else
ActiveWorkbook.Saved = True
End If
Dar se poate obține același efect mult mai simplu, folosind Not, ca în codul următor:
ActiveWorkbook.Saved = Not ActiveWorkbook.Saved
Ca în majoritatea limbajelor de programare, blocurile If din VBA sunt printre comenzile cele mai utile și versatile folosite la luarea unei decizii.
În secțiunea următoare, sunt prezentate trei moduri de folosire a instrucțiunii If:
If...Then îi transmite VBA să ia decizii simple. Când condiția este îndeplinită, se execută comanda (sau comenzile). Când condiția nu este îndeplinită, VBA sare peste linia cu comenzi din blocul condiţional.
O comandă If începe cu If și se încheie cu End If. (Comanda prescurtată If...Then poate fi scrisă pe o singură linie, iar în acest caz, comanda End If este omisă.)
SINTAXĂ
Comenzile simple If...Then pot fi scrise pe o singură linie. Comanda If...Then pe o singură linie arată astfel:
If conditie Then 'Codul care va fi executat se scrie aici
Atunci când condiția este îndeplinită, VBA execută comanda sau comenzile care urmează pe aceeași linie. Atunci când condiția nu este îndeplinită, VBA nu execută comanda sau comenzile de pe acea linie.
Dar blocul de instrucțiuni If...Then se poate scrie și pe mai multe linii. O comandă If...Then pe mai multe linii (liniile de cod dintre If și End If sunt numite și bloc) arată astfel:
If conditie Then
'Codul care va fi executat este scris aici
End If
Atunci când condiția este îndeplinită, VBA execută toate comenzile din bloc (comenzile care se află între If și End If). Când condiția nu este îndeplinită, VBA sare peste comenzile din bloc și preia comenzile de după instrucțiunea End If.
Comanda If pe o singură linie nu folosește End If
De reținut că la comanda If...Then pe o singură linie, nu se pune la final End If, iar blocul If cere la final End If. VBA înțelege că o condiție If pe o singură linie se încheie pe aceeași linie.
Dar la blocul If trebuie specificat finalul condiției, pentru ca VBA să înțeleagă care este codul pe care trebuie să îl ignore în cazul în care condiția este evaluată la False. Blocurile If sunt mai ușor de citit.
EXEMPLE
Comenzi If pe o singură linie
Dim bytVarsta As Integer
bytVarsta = InputBox("Introduceti varsta.", "Varsta")
If bytVarsta < 18 Then MsgBox "Nu aveti voie sa cumparati alcool.",, "Fara alcool"
Prima linie declară variabila bytVarsta de tip Integer. A doua linie cere utilizatorului să introducă vârsta într-o casetă de dialog și o stochează în variabilă. A trei linie verifică valoarea din bytVarsta și afișează mesajul Fara alcool dacă valoarea din bytVarsta este mai mică decât 18.
Se pot include mai multe instrucțiuni pe o singură linie, dacă sunt separate de două puncte. O comandă If pe o singură linie poate avea mai multe comenzi. Pe acea linie se specifică acțiunea sau acțiunile care vor fi executate dacă expresia din comanda If...Then este evaluată la True.
De exemplu, pentru a opri macrocomanda după afișarea mesajului Fara alcool, se poate include comanda End după două puncte pe aceeași linie, astfel:
If bytVarsta < 18 Then MsgBox "Nu aveti voie sa cumparati alcool.",, "Minor": End
Modul în care VBA execută codul este:
Se pot adăuga și alte comenzi pe aceeași linie „logică”, separate între ele de două puncte. Dacă se introduce și comanda End, ea ar trebui să fie ultima, deoarece încheie procedura. (Pentru VBA, o linie logică înseamnă că este o linie unică de cod care trebuie executată, indiferent de liniile fizice reale, pe care codul le afișează pe monitor.)
Se poate adăuga și o altă declarație If:
If bytVarsta < 21 Then If bytVarsta > 18 Then MsgBox _
"Poti vota, dar nu ai voie sa bei alcool.",, "Fara alcool": End
Însă, folosind această abordare, la această linie din editorul Visual Basic, există câteva probleme:
Blocurile If
Construcțiile de blocuri If funcționează la fel ca și cele pe o singură linie, însă blocurile conțin mai multe linii - de obicei câte o comandă pentru fiecare linie - și au la final comanda End If. De exemplu, instrucțiunea If cu o linie din secțiunea precedentă ar putea fi scrisă și ca un bloc If astfel:
If bytVarsta < 18 Then
MsgBox "Nu ai voie sa cumperi alcool.",, "Fara alcool"
End
End If
Dacă condiția din prima linie (linia cu comanda If) returnează True, VBA execută instrucțiunile din blocul If. VBA afișează caseta de mesaje și apoi execută instrucțiunea End.
În acest exemplu, blocurile If sunt mai ușor de citit (și, prin urmare, mai ușor de depanat) decât instrucțiunile If de pe o singură linie. Acest lucru este valabil mai ales atunci când sunt imbricate mai multe comenzi If.
Pentru a facilita citirea blocurilor, convenția este să se apese tasta Tab pentru a muta la dreapta liniile din bloc (VBA ignoră indentarea în timpul execuției). Indentarea se poate vedea și în exemplul de cod anterior.
La blocurile scurte If, ca și cel de mai sus, indentarea nu face o diferență mare. Dar, în declarațiile If complexe, indentarea face diferența între un cod clar și unul de neînțeles, ca în secțiunea de mai jos, la „Imbricarea blocurilor If”.
Comenzile If...Then sunt utile pentru a urma o singură cale în funcție de o condiție, dar uneori este nevoie să se aleagă între două căi de urmat. Pentru aceasta, se folosește comanda If...Then...Else.
Folosind o comandă If...Then...Else, se poate face o anumită acțiune atunci când condiția este True și o altă acțiune dacă este False. Este la fel ca în limbajul zilnic, de exemplu Daca ploua, iau umbrela, altfel iau protectia solara.
Comenzile If...Then... Else pot fi folosite și la casetele cu mesaje care au două butoane. Dacă utilizatorul face clic pe butonul OK, codul va face o anumită acțiune. La clic pe butonul Cancel, va face altceva.
Comanda IF...THEN...ELSE se folosește pentru situațiile TRUE/FALSE
Comanda If...Then...Else este folosită la situații în care sunt întâlnite condițiile adevărat/fals. (Ca și la întrerupătorul electric – deschis sau închis.) Pentru situații mai complexe, în care apar trei sau mai multe condiții, se folosește o comandă logică mai complexă, cum ar fi If…Then...ElseIf…Else sau Select Case. Ele vor fi descrise ulterior.
Sintaxa
Sintaxa pentru comanda If...Then...Else este următoarea:
If conditie Then
Comenzi1
Else
Comenzi2
End If
Dacă conditie
este True, VBA execută Comenzi1, primul grup de comenzi. Dacă conditie
este False, VBA mută executarea la linia Else și execută Comenzi2, al doilea grup de comenzi.
Și aici există opțiunea de a construi o comandă pe o singură linie If...Then...Else sau blocuri de comenzi If...Then...Else. Se recomandă crearea de blocuri If...Then...Else pentru că sunt mai ușor de citit și depanat și pentru că o structură If...Then...Else este mai lungă decât structura If...Then și va rezulta o linie mult mai lungă.
Exemplu
Un exemplu simplu pentru comanda If...Then...Else este prezentat mai jos.
1. Sub Criticul_de_Carte_Electronica()
2.
3. Dim intPaginiCarte As Integer
4.
5. intPaginiCarte = InputBox _
("Introduceti numarul de pagini din ultima carte citita.", "Criticul de Carte Electronica")
6. If intPaginiCarte > 1000 Then
7. MsgBox "Cartea are multe pagini.", vbOKOnly _
+ vbExclamation, "Criticul de Carte Electronica"
8. Else
9. MsgBox "Cartea nu are prea multe pagini.", vbOKOnly _
+ vbInformation, "Criticul de Carte Electronica"
10. End If
11.
12. End Sub
Iată ce se petrece în procedura de mai sus:
Ultima variantă a comenzii If este blocul If...Then...ElseIf...Else, care se folosește pentru a decide între trei sau mai multe variante de acțiune. Se poate folosi orice număr de linii ElseIf, în funcție de cât de complexă este condiția care va fi verificată.
Din nou, comanda If...Then...ElseIf...Else poate să fie scrisă pe o singură linie sau în blocuri de comenzi. În majoritatea cazurilor, se folosesc blocurile If...Then...ElseIf...Else, care sunt mai ușor de construit, citit și depanat. Ca și la alte comenzi If, comanda If...Then...ElseIf... Else nu are nevoie de instrucțiunea End If, iar blocul If...Then...ElseIf...Else are nevoie de End If.
Sintaxa
Sintaxa pentru If...Then...ElseIf...Else este următoarea:
If conditie1 Then comenzi1
ElseIf conditie2 Then comenzi2
[ElseIf conditie3 Then comenzi3]
[Else
comenzi4]
End If
Dacă condiția exprimată în conditie1 este True, VBA execută comenzi1, primul bloc de instrucțiuni, apoi reia execuția la linia de după clauza End If. Dacă condiția este falsă, VBA comută la prima clauză Elself și evaluează starea exprimată în conditie2. Dacă returnează adevărat, VBA execută comenzi2 și apoi sare la linia de după linia End If; dacă este Fals, VBA trece la următoarea condiție Elself (dacă există una) și evaluează starea (aici, conditie3).
Dacă toate condițiile din declarațiile Elself se dovedesc false, VBA se ramifică la declarația Else (dacă există) și execută declarațiile de după aceasta (aici, comenzi4). Instrucțiunea End If încheie instrucțiunea condițională, iar execuția continuă cu linia de după End If.
Clauza Else este opțională, deși în multe cazuri este o idee bună să fie inclusă pentru a permite VBA să facă o altă acțiune dacă niciuna dintre condițiile specificate în clauzele If și ElseIf nu se dovedesc a fi adevărate. Programatorul nu poate prezice întotdeauna toate condițiile în care se execută programul, astfel încât comanda Else ajută la o finalizare a listei de If-uri. Așa se poate face față la o situație care nu se află în listă.
Pot fi scrise orice număr de clauze ElseIf într-un bloc If, fiecare cu propria condiție. Dar dacă într-o instrucțiune If sunt prea multe condiții ElseIf (de exemplu, mai mult de 5 sau 10), se recomandă folosirea comenzii Select Case, descrisă mai jos.
EXEMPLE
Mai jos sunt prezentate două exemple de comenzi If...Then...ElseIf...Else:
Comanda simplă If...Then...ElseIf...Else
Comanda simplă If...Then...ElseIf...Else de mai jos, este perfectă pentru o casetă de dialog cu trei butoane.
1. Sub Crearea_unui_Document()
2.
3. Dim lngButon As Long
4. Dim strMesaj As String
5.
6. strMesaj = "Creati un document nou bazat pe " & _
"VP Report project?" & vbCr & vbCr & _
"Clic Yes pentru a folosi sablonul VP Report." & vbCr & _
"Clic No pentru a deschide un document gol." & vbCr & _
"Clic Cancel pentru a renunta la crearea unui document nou."
7.
8. lngButon = MsgBox _
(strMesaj, vbYesNoCancel + vbQuestion, "Creare document nou")
9.
10. If lngButon = vbYes Then
11. Documents.Add Template:= "z:\public\template\vpreport.dotm"
12. Elself lngButon = vbNo Then
13. Documents.Add
14. Else 'lngButon is vbCancel
15. End
16. End If
17.
18. End Sub
Procedura Crearea_unui_Document de mai sus afișează o casetă de dialog Yes/No/Cancel care propune utilizatorului să creeze un document nou bazat pe proiectul VP Report. Utilizatorul poate alege cu butonul Yes să creeze un astfel de document, cu butonul No să creeze un document gol, sau cu butonul Cancel să închidă procedura fără crearea unui document.
Iată și descrierea comenzilor din cod:
Dacă linia 10 returnează True, linia 11 folosește metoda Add a obiectului Documents pentru a adăuga un document nou bazat pe șablonul vpreport.dotm. Dacă nu, este evaluată condiția Elself de pe linia 12, care compară valoarea din lngButon cu vbNo. Dacă utilizatorul a dat clic pe butonul Yes de pe caseta de dialog, VBA caută șablonul numit vpreport.dotm în folderul z:\public\template\ pentru a putea rula comanda de pe linia 11. Dacă șablonul nu există, este afișat un mesaj de eroare. Aici se poate modifica calea și numele fișierului din cod, pentru a accesa un fișier șablon.
Acest exemplu este puțin neobișnuit deoarece comanda Else este limitată la trei opțiuni, pentru că acesta este numărul maxim de răspunsuri posibile pentru o casetă de dialog—Yes, No și Cancel.
Deoarece comanda If verifică răspunsul vbYes și comanda Elself verifică răspunsul vbNo, doar răspunsul vbCancel va fi ales pentru comanda Else.
În alte circumstanțe, comanda Else este folosită pentru orice nu este prins de declarațiile If și Elself de deasupra lui Else, deci mai întâi se verifică dacă instrucțiunile If și Elself acoperă toate situațiile care trebuie evaluate înainte de a ajunge la instrucțiunea Else. Așadar, instrucțiunea Else se află în partea de jos a blocului.
De exemplu, dacă utilizatorul este întrebat care sunt culorile steagului României, trebuie furnizate instrucțiuni If și Elself pentru roșu, galben și albastru. Dacă se omite, de exemplu, alb (una dintre posibilități) și culoarea albă pentru utilizator, codul va trece la instrucțiunea Else, care ar putea afișa un mesaj incorect, cum ar fi „Culoarea aleasă nu este pe steag."
Se poate utiliza o instrucțiune If ... Then ... ElseIf fără condiția Else atunci când nu este necesară o altă opțiune dacă niciuna dintre condițiile din instrucțiunea If nu returnează True. În exemplul precedent, situația a avut trei rezultate clar definite: Utilizatorul poate alege butonul Yes, butonul No sau butonul Cancel din caseta de mesaje. Așadar, s-a putut folosi o condiție If pentru a testa dacă utilizatorul a ales butonul Da, o condiție ElseIf pentru a testa dacă utilizatorul a ales butonul No și o condiție Else pentru a testa dacă nu a fost ales niciunul (ceea ce înseamnă că a fost ales butonul Cancel). (Clic pe butonul Close [X] din bara de titlu a unei căsuțe de mesaje este echivalentul alegerii butonului Cancel din caseta de mesaje.)
Ca exemplu de situație în care nu trebuie acționat în niciun fel dacă nici o condiție nu este adevărată, se ia în considerare instrucțiunea If din procedura Verificare_Parola de mai jos. Această procedură verifică dacă parola introdusă de un utilizator pentru a proteja un articol are lungimea adecvată.
Nu se acționează în niciun fel dacă nicio condiție nu este adevărată
1. Sub Verificare_Parola()
2.
3. Dim strParola As String
4.
5. ParolaGresita:
6.
7. strParola = InputBox _
("Introduceti parola pentru a proteja acest element la modificari:", "Parola")
8.
9. If Len(strParola) = 0 Then
10. End
11. ElseIf Len(strParola) < 6 Then
12. MsgBox "Parola aleasa este prea scurta." & vbCr _
& vbCr & "Alegeti o parola cu lungimea " & _
"intre 6 si 15 caractere.", _ vbOKOnly + vbCritical, "Parola scurta"
13. GoTo ParolaGresita
14. Elself Len(strParola) > 15 Then
15. MsgBox "Parola aleasa este prea lunga." & vbCr & vbCr & "Alegeti o parola cu lungimea " & _
"intre 6 si 15 caractere.", vbOKOnly + vbCritical, "Parola lunga"
16. GoTo ParolaGresita
17. End If
18.
19. End Sub
Această procedură forțează utilizatorul să introducă o parolă lungă de 6-15 caractere. Iată ce se petrece:
În acest caz, nu mai este nevoie de încă o comandă Else pentru că utilizatorul a furnizat o parolă care nu îndeplinește condițiile clauzelor If sau ElseIf, iar execuția trece de blocul If și continuă pe linia de după comanda End If.
Se pot construi bucle cu comenzile If și GoTo, ca în exemplul anterior.
Dar mulți profesori și programatori nu recomandă buclele cu If și GoTo. Este o practică proastă, deoarece buclele If...GoTo pot crea „codul spaghetti” (căi de execuție care se realizează într-un mod aleatoriu și sunt greu de prevăzut). Astfel de căi pot fi nu doar nepotrivite, ci și un coșmar pentru depanare.
Cu toate acestea, versiunile simple ale buclelor If și GoTo pot funcționa perfect. Folosirea sau nu a comenzii GoTo în cod poate fi o preferință personală sau depinde de politica companiei sau convingerile profesorului.
Mai jos este descris modul în care poate fi utilizat GoTo.
SINTAXĂ
Declarația GoTo este simplă și poate fi utilă. Sintaxa este următoarea:
GoTo line
Aici, argumentul line poate fi o etichetă (sau, mai rar, numărul unei linii) din procedura curentă.
Numărul unei linii este numărul care se află la începutul liniei, pentru a o identifica. De exemplu, iată o demonstrație a comenzii GoTo:
Sub Demo_of_GoTo()
1
If MsgBox("Go to line 1?", vbYesNo) = vbYes Then GoTo 1
End If
End Sub
A doua linie conține aici doar numărul liniei, 1, care identifică linia. A treia linie afișează un mesaj care oferă o alegere de a trece înapoi pe linia 1; dacă utilizatorul face clic pe butonul Yes, VBA execută comanda GoTo 1 și revine la linia etichetată cu 1, după care afișează din nou mesajul. (Dacă utilizatorul alege butonul No, VBA iese din blocul If.)
Cu toate acestea, se recomandă folosirea unei etichete în locul unui număr pentru o linie. Eticheta de linie este un nume pentru o anumită linie. O etichetă începe cu o literă și se termină cu două puncte. Între literă și cele două puncte, eticheta poate consta din orice combinație de caractere. De exemplu, mai sus a fost folosită eticheta ParolaGresita:, pentru a face bucla înapoi la o etapă anterioară într-o procedură atunci când au fost îndeplinite anumite condiții. Poate că exemplul chintesențial al unei etichete este Bye: eticheta plasată în mod tradițional la sfârșitul unei proceduri de utilizare cu această declarație GoTo:
GoTo Bye
Când această etichetă este plasată chiar deasupra comenzii EndSub, pur și simplu iese din macrocomandă.
GoTo este de obicei utilizat cu o condiție. Dacă se folosește fără o condiție pentru a reveni în cod la o linie anterioară comenzii GoTo, se poate creea o buclă infinită. Și dacă se folosește declarația GoTo Bye fără o condiție, procedura se oprește - nu va fi executată nicio declarație care se află după această linie. Se sare direct la sfârșitul macrocomenzii.
EXEMPLU
Ca exemplu al comenzii GoTo cu o condiție, se poate folosi comanda GoTo Bye împreună cu o casetă mesaj care să întrebe dacă utilizatorul dorește ca să se execute o anumită procedură:
Response = MsgBox("Doriti crearea unui raport zilnic" & _
"din documentul curent?", _
vbYesNo + vbQuestion, "Creare Raport Zilnic")
If Response = vbNo Then GoTo Bye
Dacă utilizatorul face clic pe butonul No din caseta mesaj, VBA execută comanda GoTo Bye, comutând la eticheta Bye: care se află la sfârșitul subrutinei.
Un alt motiv bun pentru a evita utilizarea numerelor de linie ca țintă este că, ulterior, se pot insera anumite coduri înainte de linia țintă, lucru care ar putea duce la o eroare (deoarece numărul corect al liniei țintă se schimbă din cauza adăugării de linii noi).
Blocuri If imbricate
Blocurile If pot fi imbricate (nested) sau puse unul în altul pentru a gestiona eventualele modificări necesare din cod. Fiecare bloc If imbricat trebuie să fie complet în sine. (Aceasta înseamnă că fiecare bloc imbricat trebuie să înceapă cu un If și să se încheie cu propriul său End If.)
De exemplu, dacă se introduce un bloc If în interiorul altui bloc If (dar fără pune End If-ul care încheie If-ul imbricat), VBA presupune că linia End If pentru If-ul exterior încheie If-ul imbricat.
Pentru a face blocurile mai ușor de citit, se recomandă aranjarea lor pe diferite niveluri. Acest lucru este deosebit de important atunci când sunt mai multe blocuri imbricate. Indentarea oferă indicii vizuale, făcând clară linia If asociată cu linia End If. Cu alte cuvinte, indentarea face ca diferitele blocuri If să iasă în evidență.
Exemplul de mai jos arată cum se face pot imbrica mai multe comenzi If:
1. If conditie1 Then 'incepe primul If
2. If conditie2 Then 'incepe al doilea If
3. If conditie3 Then 'incepe al treilea If
4. instructiuni1
5. ElseIf conditie4 Then 'ElseIf pentru al treilea If
6. instructiuni2
7. Else 'Else pentru al treilea If
8. instructiuni3
9. End If 'End If pentru al treilea If
10. Else 'Else pentru al doilea If
11. If conditie5 Then 'incepe al patrulea If
12. instructiuni4
13. End If 'End If pentru al patrulea If
14. End If 'End If pentru al doilea If
15. Else 'Else pentru primul If
16. instructiuni5
17. End If 'End If pentru primul If
Astfel, se poate urmări cu ușurință fluxul de execuție. De exemplu, dacă condiția1 din linia 1 este False, VBA se ramifică la instrucțiunea Else din linia 15 și continuă execuția de acolo. Dacă condiția1 de pe linia 1 este adevărată, VBA evaluează condiția2 de pe linia 2 și așa mai departe.
Indentarea este doar pentru claritatea vizuală. Înlesnește înțelegerea codului pentru oameni - VBA nu-i acordă atenție. Comenzile anterioare imbricate If sunt, de asemenea, adnotate cu comentarii, astfel încât să se poată vedea care linie Else, ElseIf și End If corespunde liniei If. Însă, după indentare, comentarea nu este necesară.
Prin contrast, se poate vedea și versiunea fără indentări pentru blocurile imbricate. Această versiune este dificil de urmărit pentru oameni - mai ales atunci când sunt adăugate și alte linii de cod:
1. If conditie1 Then
2. If conditie2 Then
3. If conditie3 Then
4. instructiuni1
5. ElseIf conditie4 Then
6. instructiuni2
7. Else
8. instructiuni3
9. End If
10. Else
11. If conditie5 Then
12. instructiuni4
13. End If
14. End If
15. Else '
16. instructiuni5
17. End If
Rareori este nevoie urgentă să fie imbricate mai multe blocuri If. Adesea, trebuie imbricată doar o instrucțiune If ... Then într-o instrucțiune If ... Then ... Else sau în cadrul unei instrucțiuni If...Then...ElseIf... Else. Iată arată un exemplu din Word.
Imbricarea unui bloc If...Then
1. Selection.HomeKey Unit:=wdStory
2. Selection.Find.ClearFormatting
3. Selection.Find.Style = ActiveDocument.Styles("Heading 5")
4. Selection.Find.Text = " "
5. Selection.Find.Execute
6. If Selection.Find.Found Then
7. lngResponse = MsgBox("Transform in stilul nota speciala?", vbOKCancel, "Transformare Special Note")
8. If IngResponse = vbOK Then
9. Selection.Style = "Special Note"
10. End If
11. End If
Codul de mai sus caută în documentul activ text scris cu stilul Heading 5 și când îl găsește, afișează un mesaj care se oferă să modifice stilul în Special Note aplicând stilul Special Note. Iată etapele care au loc:
În cazul în care un document conține mai mult de o instanță a stilului Heading 5, se poate folosi o buclă Do While...Loop pentru a căuta fiecare instanță.
Blocurile Select Case
Blocul Select Case oferă o alternativă la blocurile multiple If...Then sau la comenzile ElseIf. Select Case combină posibilitatea de luare a deciziei a construcțiilor If cu un cod mai simplu.
Comanda Select Case se folosește atunci când decizia care trebuie luată este complicată, deoarece implică mai mult de două sau trei valori diferite care sunt evaluate.
Blocurile Select Case sunt mai ușor de citit decât blocurile If...Then complexe, mai ales pentru că există mai puțin cod. Astfel, blocurile Select Case sunt mai ușor de modificat: atunci când trebuie ajustate una sau mai multe valori, este mai puțin cod de eliminat.
Sintaxă
Sintaxa pentru Select Case este următoarea:
Select Case ExpresieDeTestat
Case Expresie1
Instructiuni1
[Case Expresie2
Instructiuni2]
[Case Else
InstructiuniPentruElse]
End Select
Iată cum funcționează sintaxa:
De exemplu, se poate testa pentru a vedea butoanele care au fost alese dintr-un formular al utilizatorului. ExpresieDeTestat este legată de un anumit buton; dacă este ales primul buton, VBA alege Expresie1 și execută declarațiile din rândurile următoare Case Expresie1; dacă este ales al doilea buton, VBA alege Expresie2 și execută declarațiile din rândurile care urmează în cazul Expresie2; și așa mai departe pentru restul blocurilor Case.
Cazul Else este similar cu clauza Else din blocul If. Case Else este o clauză opțională care (dacă este inclusă) este executată dacă niciuna dintre expresiile de mai sus nu se potrivește.
Exemplu
Ca și exemplu pentru blocul Select Case, se consideră codul de mai jos, care cere utilizatorului să introducă viteza de tastare, apoi afișează un răspuns corespunzător.
1. Sub Verificare_Viteza_De_Tastare()
2.
3. Dim varVitezaTastare As Variant
4. Dim strMsg As String
5.
6. varVitezaTastare = InputBox _
("Cate cuvinte puteti tasta pe minut?", "Viteza de tastare")
7. Select Case varVitezaTastare
8. Case " "
9. End
10. Case Is < 0, 0, 1 To 50
11. strMsg = "va recomandam sa invatati sa tastati mai rapid " & _
"inainte de a aplica la un job."
12. Case 50 To 60
13. strMsg = "Se poate si mai rapid. "
14. Case 60 To 75
15. strMsg = "Viteza de tastare este multumitoare."
16. Case 75 To 99
17. strMsg = "Viteza de tastare e mai mult decat adecvata. "
18. Case 100 To 200
19. strMsg = "Viteza este foarte buna."
20. Case Is > 200
21. strMsg = "Nu cred ca se poate tasta asa de rapid."
22. End Select
23.
24. MsgBox strMsg, vbOKOnly, "Viteza de tastare "
25.
26. End Sub
Iată ce se petrece în procedura Verificare_Viteza_De_Tastare de mai sus:
de tip Variant, iar linia 4 declară variabila strMsg de tip String. Linia 5 este goală.Prima clauză Case, de pe linia 8, compară varVitezaTastare cu șirul gol (" ") pentru a vedea dacă utilizatorul alege butonul Cancel sau butonul OK fără a introduce o valoare în caseta text. Atunci când Case " " este True, VBA execută comanda End de pe linia 9, încheind procedura.
Un bloc Select Case poate fi o modalitate bună de a specifica o anumită acțiune, în funcție de alegerea pe care o face utilizatorul într-un control de tip ListBox sau ComboBox.
De obicei, controalele ListBox sau ComboBox afișează o listă cu multe opțiuni diferite, de exemplu județele dintr-o țară. După ce utilizatorul face clic pentru a selecta un element dintr-un control ListBox sau ComboBox, elementul ales apare în proprietatea Value a controlului. Apoi, macrocomanda poate să verifice această proprietate Value ca pe o expresie de testare în blocul Select case și să acționeze în consecință.
Atunci când contează ordinea elementelor
Încă ceva despre structurile complexe de testare. Se verifică dacă în comenzile Select Case și If...Then...Else (sau alte structuri multiple If) condițiile de testare sunt evaluate în ordinea corespunzătoare. Aceasta înseamnă că fiecare condiție care trebuie evaluată trebuie să excludă toate condițiile care o urmează.
De exemplu, se întreabă utilizatorul ce vârstă are și cazurile de testare sunt configurate astfel:
1. Varsta = InputBox ("Ce varsta ai?")
2.
3. Select Case Varsta
4.
5. Case < 50
6. strMsg = "Esti aproape de pensie."
7.
8. Case < 12
9. strMsg = "Salut, tinere."
Aici, codul este greșit. Linia 8 nu va fi executată niciodată pentru că un număr mai mic decât 50, include și numărul 12, deci va fi executată doar comanda de pe linia 5. (Expresia "mai mic decât 50" include "mai mic decât 12.")
Pentru ca să fie corect, codul trebuie scris invers, astfel:
Case < 12
strMsg = "Salut, tinere."
Case < 50
strMsg = " Esti aproape de pensie."
Această problemă se poate evita prin testarea egalității sau a intervalului, ca mai sus:
Case 50 To 60