Documente Academic
Documente Profesional
Documente Cultură
Iniiere n VBA Utilizarea procedurilor Variabile i constante Structuri de control Funcii interne Conversia de la AutoLISP la VBA
Iniiere n VBA
Pachetul VBA oferit de Microsoft pune la dispoziia programului AutoCAD dou lucruri. Mai nti este vorba de motorul propriu-zis al limbajului VBA, care se ocup de interpretarea oricrui cod surs VBA pe care-l scriei, la executarea aplicaiei dumneavoastr. n al doilea rnd, este vorba de Integrated Development Environment (IDE Mediu integrat de dezvoltare a aplicaiilor) din VBA, care v ofer instrumentele de editare i depanare a codului surs VBA pe care-l scriei. n acest capitol, vei nva noiunile de baz ale limbajului VBA. Capitolul 5 de pe acest CD, descrie interfaa IDE i v arat cum s integrai programele VBA n interfaa cu utilizatorul din programul AutoCAD. Totui, trebuie s tii suficient despre IDE pentru a tasta i executa procedurile de urmat din acest capitol, aa c urmeaz o scurt introducere.
1. n AutoCAD, selectai Tools Macro Visual Basic Editor (Instrumente Macrocomand Visual Basic
Editor) pentru a deschide editorul VBA ntr-o fereastr separat.
2. Pentru a trece din fereastra IDE n fereastra AutoCAD i napoi, executai clic pe butonul AutoCAD View
de la captul stng al barei de instrumente Editor, sau selectai View AutoCAD (Afiare AutoCAD) dintr-un meniu de editor. Mai putei tasta Alt+F11 pentru a reveni din editor n AutoCAD sau pentru a trece din fereastra AutoCAD principal napoi n fereastra editorului VBA.
96
NOT
Putei de asemenea deschide automat editorul, cnd ncrcai un proiect VBA. n acest scop, selectai Tools Macro Load Project (Instrumente Macrocomand ncrcare proiect) i verificai s fie selectat caseta de validare Open (Deschidere) din Visual Basic Editor.
Un modul este un container pentru codul surs VBA. Un modul de clas este componenta VBA utilizat pentru a defini un nou tip de obiect. Un UserForm este o component adaptabil a interfeei cu utilizatorul. Modulele de clas reprezint un subiect avansat i despre UserForm-uri vei nva n capitolul 5 de pe acest CD, dar pentru moment, s crem un modul standard. Acesta va fi un loc n care putei executa mostre de cod surs. Dac avei AutoCAD deschis i acesta are ncrcat un desen vid, prestabilit, vei vedea c acest desen include un proiect VBA prestabilit, numit ACADProject.
1. Pentru a insera un nou modul, selectai Insert Module (Inserare Modul) sau executai clic pe butonul
Insert Module de pe Bara de Instrumente Standard. Astfel creai un nou modul i deschidei acest modul n editor. Editorul poate afia mai multe module simultan, deoarece este o aplicaie Multiple Document Interface (MDI).
2. n timp ce nvai VBA, vei considera probabil util s maximizai modulul cu care lucrai. Executai clic
pe butonul Maximize din fereastra Module1, pentru a o mri.
1. n fereastra Module1, tastai Sub HelloWorld i apsai tasta Enter. VBA insereaz paranteze la sfritul
definiiei de procedur i creeaz automat o linie End Sub pentru a marca sfritul procedurii.
2. Acum tastai MsgBox Hello World ntre liniile Sub i End Sub. Observai c VBA afieaz fereastra de
informare rapid (Quick Info) despre argumentele pentru funcia MsgBox. Pentru moment, le putei ignora.
3. Executai clic oriunde n afara liniei pe care tocmai ai tastat-o, pentru a accepta informaiile i a terge de
pe ecran Quick Info.
4. Dup ce am creat o procedur, s o rulm. Putei rula proceduri n mod interactiv n mediul VBA,
utiliznd fereastra Immediate (uneori numit fereastra Debug Depanare). Aceast fereastr poate fi deja afiat la baza IDE. n caz contrar, o putei deschide selectnd View Immediate Window (Afiare Fereastra Immediate) sau tastnd Ctrl+G.
5. Tastai HelloWorld n fereastra Immediate, comunicndu-i lui VBA s execute procedura HelloWorld
pe care tocmai ai creat-o. Instruciunea MsgBox creeaz un mesaj instantaneu (pop-up) n fereastra
INIIERE N VBA
97
dumneavoastr AutoCAD (i, ntmpltor, transform fereastra AutoCAD n fereastra activ, dup cum se arat n figura 1).
6. Executai clic pe OK n aceast caset de dialog pentru a reveni la IDE VBA. Dac ai urmat instruciunile
din aceast seciune, ecranul dumneavoastr va arta ca n figura 2. FIGURA 1
Rezultatele procedurii HelloWorld
FIGURA 2
Procedura HelloWorld din IDE VBA
Scurtturi
PENTRU A LANSA VISUAL BASIC EDITOR
Selectai Tools Macro Visual Basic Editor (Instrumente Macrocomand Editor Visual Basic).
98
Utilizarea procedurilor
Codul surs VBA este stocat n proceduri, care sunt la rndul lor grupate n module. Procedurile sunt de dou feluri: funcii i subproceduri, de obicei numite simplu funcii i sub-uri. n aceast seciune, vei nva s creai i s apelai ambele tipuri de proceduri i s transferai informaii ntre proceduri.
Sub-uri i funcii
Diferena dintre sub-uri i funcii este aceea c funciile returneaz o valoare apelantului, pe cnd sub-urile nu.
UTILIZAREA PROCEDURILOR
99
NOT
De fapt, este mai corect s spunem c funciile pot returna o valoare, deoarece putei executa o funcie folosind o sintax care-i comunic lui VBA s arunce valoarea care ar putea fi returnat. Totui, n acest capitol ne vom concentra pe nvarea unui numr suficient de informaii despre VBA pentru a face lucruri utile ct mai curnd posibil, fr a studia fiecare aspect al limbajului.
Dei exist un element Insert Procedure (Inserare Procedur) n meniul VBA, acesta este inutil deoarece, dup cum ai vzut mai devreme n cazul unui sub, este mai simplu s tastai doar cuvntul cheie Sub sau Function, numele procedurii i s lsai VBA s fac restul. Dup cum se arat n exemplul urmtor, putei crea cte o procedur de fiecare tip.
1. n fereastra Module1, mutai cursorul sub instruciunea End Sub i tastai Sub ShowSquare() i apoi
Enter. Instruciunea End Sub apare sub noua instruciune; mai apare o linie care separ anteriorul End Sub de linia pe care tocmai ai tastat-o.
2. Plasai cursorul sub instruciunea End Sub i tastai Function ReturnSquare() i apoi Enter. n
fereastra Module1 ar trebui s fie afiate urmtoarele rnduri noi, cu cte o linie orizontal ce separ fiecare intrare: Sub ShowSquare() End Sub Function ReturnSquare() End Function
Utilizarea argumentelor
Procedurile noastre ShowSquare i ReturnSquare ridic amndou la ptrat un numr furnizat de utilizator. n acest scop, trebuie s-i furnizai fiecrei proceduri un argument. Un argument este un marcaj de rezervare pentru o informaie care va fi furnizat la momentul rulrii. S vedem cum funcioneaz argumentele.
1. Continuai s adugai linii de program la aceste dou proceduri, pentru a le face s ne transmit ptratul
valorii. Iat versiunea modificat: Sub ShowSquare(x) Debug.Print x * x End Sub Function ReturnSquare(x) ReturnSquare = x * x End Function n fiecare dintre aceste proceduri, x este un argument. La rulare (adic, atunci cnd executai procedura) trebuie s furnizai o valoare pentru argument.
2. Executai clic sub intrarea HelloWorld din fereastra Immediate i tastai ShowSquare 5 i apoi Enter. 3. Dup aceea, tastai ?ReturnSquare (7) i Enter. Figura 3 arat fereastra Immediate dup executarea
fiecreia dintre aceste proceduri.
FIGURA 3
Executarea procedurilor ShowSquare i ReturnSquare
Remarcai c sintaxa de apelare difer la o funcie fa de un sub. n cazul unui sub, pur i simplu furnizai numele procedurii, urmat de toate argumentele pe care le preia sub-ul, fr paranteze. Pentru a apela o funcie din fereastra Immediate, utilizai operatorul ? urmat de toate argumentele preluate de funcie, incluse ntre paranteze. Putei considera operatorul ? ca avnd semnificaia Care este valoarea lui? Dei ambele proceduri produc acelai rezultat n exemplul nostru, utilizeaz metode diferite pentru a furniza acel rezultat. Sub apeleaz Debug.Print, un mic fragment VBA care preia orice urmeaz pe aceeai linie i-l tiprete n fereastra Immediate. Funcia atribuie rezultatul propriului ei nume. Acest lucru are efectul de a face rezultatul s fie valoarea returnat de funcie. Desigur, o procedur poate apela alte proceduri. n exemplul urmtor, procedura CallBoth execut celelalte dou proceduri: Sub CallBoth(x) Dim y ShowSquare x y = ReturnSquare(x) End Sub Aici, y este o variabil local: un loc unde s stocai o informaie. (n seciunea urmtoare, vei nva mai multe despre variabile.) Pentru a apela o funcie dintr-o alt procedur, atribuii valoarea funciei unei variabile locale.
NOT
Mai putei executa o subprocedur utiliznd cuvntul cheie special Call, caz n care argumentele procedurii trebuie incluse ntre paranteze. Adic, instruciunile ShowSquare 4 i Call ShowSquare(4) sunt echivalente. Majoritatea programatorilor utilizeaz sintaxa veche, deoarece necesit mai puin munc de tastare.
VARIABILE I CONSTANTE
101
caz, valoarea prestabilit a argumentului Amount este 1, iar rezultatul funciei este 6 (verificai singur!). n al treilea exemplu se omite de asemenea argumentul opional, dar se utilizeaz sintaxa argumentului denumit, i anume Name:=Value (Nume:=Valoare) pentru a stabili clar ce informaii sunt furnizate. Cel de-al patrulea i cel de-al cincilea exemplu arat c putei furniza argumente n orice ordine dorii, dac utilizai argumente denumite.
NOT
Nu ncercai s amestecai argumente denumite cu argumente poziionale. Dac furnizai unei proceduri un argument denumit, utilizai argumente denumite pentru toate informaiile pe care le transmitei.
Variabile i constante
Nu ai nvat nc despre o parte important a majoritii declaraiilor de proceduri: tipurile de date. Tehnic vorbind, toate argumentele i valorile returnate au fost pn acum de tipul variant. Putei considera variant ca fiind un tip de date multifuncional, care poate stoca orice fel de date. n aceast seciune, vei vedea c exist de asemenea tipuri de date cu funcie special, precum i alte cteva moduri de a stoca date n afar de simple variabile.
Tipuri de date
VBA recunoate zece tipuri de date specifice. Tabelul 1 prezint aceste tipuri de date i domeniul valorilor care pot fi stocate de fiecare n parte. Putei declara tipul unui argument de procedur, al unei variabile sau al unui rezultat returnat folosind cuvntul-cheie As. De exemplu, ai putea rescrie procedurile ShowSquare, ReturnSquare i CallBoth astfel: Sub ShowSquare(x As Integer) Debug.Print x * x End Sub Function ReturnSquare(x As Integer) As Long ReturnSquare = x * x End Function Sub CallBoth(x As Integer) Dim y As Long ShowSquare x y = ReturnSquare(x) End Sub
Tabelul 1
TIP DE DAT
Boolean Byte Integer Long Currency
Tabelul 1 (continuare)
TIP DE DAT
Single Double Date String Variant
STOCHEAZ
De la 3.402823E38 pn la 1.401298E45 i de la 1.401298E45 pn la 3.402823E38, eventual cu rotunjire De la 1.72269313486232E308 pn la 4.94065645841247E324 i de la 4.94065645841247E324 pn la 1.79769313486232E308, eventual cu rotunjire Orice valoare de dat calendaristic sau de or Date de tip text, cu lungimea cuprins ntre 0 i 2E31 caractere Poate conine date de oricare dintre celelalte tipuri, precum i Null (o valoare special pentru date variant neiniializate i cmpuri de baze de date)
NOT
Muli realizatori i autori de programe care lucreaz cu VBA utilizeaz o convenie de denumire ce specific diverse caractere de prefixare pentru nume de variabile, pentru a le indica tipul. De exemplu, un ntreg ar putea fi denumit intX, iar o variabil de tip ir, strName. Exemplele prezentate mai devreme n acest capitol nu au utilizat o convenie de denumire. Totui, de acum ncepnd, n acest capitol vom utiliza Convenia de denumire VBA a lui Reddick, care este probabil convenia de denumire folosit cel mai frecvent n domeniu.
Putei declara explicit o variabil As Variant i o putei utiliza pentru a stoca orice tip de date pe care VBA este capabil s le prelucreze. Putei de asemenea omite complet clauza As dintr-o declaraie de variabil, caz n care VBA ofer implicit tipul variant. Dei aceast tehnic v scutete de grija legat de tipurile de date, acest lucru nseamn de asemenea c VBA nu va face vreo verificare n timpul rulrii, pentru a vedea dac datele sunt acceptabile. Dac declarai o variabil As Integer i ncercai s stocai n ea un ir de caractere, VBA va da eroare; dac declarai aceeai variabil As Variant, VBA nu va ti c nu doreai s accepte iruri.
VARIABILE I CONSTANTE
103
gstrSharedWithEveryone este o variabil public (numit variabil global n versiunile mai vechi de VBA). Aceast variabil poate fi utilizat de orice procedur, din orice modul al proiectului. mstrSharedRightHere este o variabil la nivel de modul. Aceast variabil poate fi utilizat de orice procedur din modulul n care este definit. varArg1 i varArg2 sunt argumente locale. Acestea pot fi utilizate doar de procedurile n ale cror liste de argumente sunt incluse. intI este o variabil local. Aceasta poate fi utilizat doar de ctre procedura n care este definit. intJ este de asemenea o variabil local. Aceasta poate fi utilizat doar de procedura n care este definit.
Aceast distincie ntre variabile publice, la nivel de modul i locale se numete de obicei domeniu de valabilitate al variabilei. Utiliznd exemplul precedent, gstrSharedWithEveryone are domeniu de valabilitate global, mstrSharedRightHere are domeniu de valabilitate la nivel de modul, iar intI are domeniu de valabilitate local. Exist de asemenea un al doilea factor de luat n calcul la declararea variabilelor, acela legat de durata existenei. Variabilele care au domeniu de valabilitate global sau la nivel de modul au durata existenei la nivel de proiect: acestea sunt create la ncrcarea proiectului, iar dac atribuii o valoare uneia dintre aceste variabile, valoarea este stocat pn la descrcarea proiectului (sau pn la momentul n care le atribuii n mod deliberat o alt valoare). Variabilele locale au durata existenei la nivel de procedur: acestea sunt create cnd executai procedura i sunt eliberate la ncheierea procedurii. Totui, putei utiliza cuvntul-cheie Static (dup cum am artat mai devreme, pentru intJ) pentru a declara o variabil local cu durata existenei la nivel de proiect. Acest lucru nseamn c valoarea variabilei persist pe parcursul tuturor apelurilor la procedur. Dac rulai Helper de mai multe ori (i conine cod surs suplimentar, care nu este artat aici, pentru a atribui o valoare variabilei), vei descoperi c intJ conine ultima valoare pe care o stocai n ea, n loc ca variabila s fie reiniializat de fiecare dat.
NOT
Putei verifica dac exist erori de compilare n orice moment, n VBA, selectnd Debug Compile ACADproject (Depanare Compilare ACADproject).
Specificarea instruciunii Option Explicit este att de important nct exist o cale prin care-i putei cere lui VBA s fac acest lucru pentru dumneavoastr n fiecare modul nou.
1. Selectai Tools Options (Instrumente Opiuni) pentru a deschide caseta de dialog Options la pagina
Editor, artat n figura 4. FIGURA 4
Caseta de dialog Options, deschis la pagina Editor
2. Bifai caseta de validare Require Variable Declaration (Declaraia de variabil este obligatorie) (n mod
prestabilit ea nu este bifat) i nu va trebui s v preocupai niciodat n legtur cu includerea manual a instruciunii Option Explicit. Facei acest lucru imediat dup ce instalai AutoCAD, nainte s scriei vreo linie de program.
Utilizarea constantelor
VBA accept constante nume de valori care nu se vor modifica n cursul rulrii aplicaiei dumneavoastr. Putei utiliza constante pentru a face programul dumneavoastr mai lizibil. De exemplu, chiar dac VBA nu furnizeaz o funcie automat pentru transformarea gradelor n radiani, este destul de uor s scriei o asemenea funcie: Function DegreesToRadians1(dblDegrees As Double) _ As Double DegreesToRadians1 = (dblDegrees / 180) * 3.14159 End Function
NOT
Combinaia ntre liniua de subliniere (_) i tasta Enter () servete drept caracter de continuare a rndului n VBA, astfel c primele dou rnduri din acest exemplu vor fi citite ca o singur linie de ctre interpretorul VBA.
Dei este destul de uor de vzut ce se realizeaz n acest exemplu, putei face codul surs puin mai clar, utiliznd o constant care s reprezinte numrul magic: Function DegreesToRadians2(dblDegrees As Double) _ As Double Const Pi = 3.14159 DegreesToRadians2 = (dblDegrees / 180) * Pi End Function
VARIABILE I CONSTANTE
105
La fel ca variabilele, constantele pot fi declarate cu domeniu de valabilitate local, la nivel de modul sau cu domeniu de valabilitate global. De exemplu, dac ai fi avut nevoie de Pi n mai multe locuri, l-ai fi putut defini drept constant global: Public Const Pi = 3.14159 Function DegreesToRadians3(dblDegrees As Double) _ As Double DegreesToRadians3 = (dblDegrees / 180) * Pi End Function
Utilizarea tablourilor
Putei grupa variabilele VBA n tablouri colecii numerotate de variabile, de acelai tip. Pentru a declara un tablou, pur i simplu i comunicai lui VBA cte elemente va avea: Dim strK(1 To 5) As String Astfel creai un tablou, strK, cu spaiu de stocare pentru cinci iruri, numerotate de la 1 la 5. Putei atribui valori elementelor unui tablou sau le putei citi de undeva: Sub ArrayDemo() Dim strK(1 To 5) As String strK(1) = H strK(2) = e strK(3) = l strK(4) = l strK(5) = o Debug.Print strK(1), strK(2), strK(3), _ strK(4), strK(5) End Sub Tablourile au o utilitate limitat n VBA; n multe situaii, coleciile (discutate n cele ce urmeaz) se dovedesc a fi mai utile. Totui, tablourile sunt eseniale n AutoCAD dintr-un anumit motiv: reprezentarea VBA a unui punct n Model Space (Spaiul Model) din AutoCAD este un tablou de valori n reprezentare cu dubl precizie. Iat cum ar putea arta codul de desenare a unei linii n AutoCAD: Sub DrawLine() Dim ptStart(1 To 3) As Double Dim ptEnd(1 To 3) As Double ptStart(1) = 1 ptStart(2) = 1 ptStart(3) = 1 ptEnd(1) = 2 ptEnd(2) = 2 ptEnd(3) = 2 ThisDrawing.ModelSpace.AddLine ptStart, ptEnd End Sub Fiecare dintre tablouri stocheaz informaiile necesare pentru localizarea unui punct. Primul, al doilea i al treilea element ale tabloului stocheaz coordonatele X, Y i Z ale punctului n Model Space din AutoCAD.
Utilizarea coleciilor
Coleciile VBA ofer o alternativ la tablouri, pentru urmrirea mai multor articole. Spre deosebire de tablouri, care sunt concepute pentru a stoca lucruri ce pot fi identificate dup numr, coleciile sunt concepute pentru accesul aleatoriu. Putei considera o colecie ca fiind locul n care punei orice dorii s regsii mai trziu dup nume. Procedura CollectionDemo ilustreaz sintaxa pe care o utilizai cnd lucrai cu colecii: Sub CollectionDemo() Dim col As Collection Set col = New Collection Adaugati trei elemente la colectie col.Add 5, First col.Add 9, Second col.Add 12, Third Regaseste Debug.Print Debug.Print Debug.Print Regaseste Debug.Print Debug.Print Debug.Print articolele dupa nume col.Item(First) col(Second) col(Third) articolele dupa indice col.Item(1) col(2) col(3)
Sterge un articol din colectie col.Remove 2 Si arata cate elemente au ramas Debug.Print col.Count End Sub Dei declarai o colecie cu acelai cuvnt-cheie Dim pe care-l folosii pentru alte variabile, trebuie de asemenea s iniializai colecia. Aceasta deoarece o colecie este un tip de variabil obiect care are proprieti mai complexe dect un simplu loc de stocare pentru date. Iniializarea variabilei este scopul urmtoarei linii: Set col = New Collection Cuvntul-cheie New i comunic lui VBA s creeze un obiect de tipul Collection, iar cuvntul-cheie Set i comunic lui VBA c vei utiliza variabila col pentru a face referire la acest nou obiect. Add este o metod a obiectului Collection. Aceast metod preia dou argumente, primul fiind articolul de adugat, iar al doilea fiind o valoare de cheie care poate fi folosit mai trziu pentru a face referire la articol. Putei aduga orice la o colecie. n acest caz, adugai cele trei numere: 9, 5 i 12.
STRUCTURI DE CONTROL
107
Un obiect este orice fel de variabil care are un comportament complex. De exemplu, obiectul Document din AutoCAD reprezint un ntreg fiier de desen. O metod este orice tie obiectul s fac. Printre metodele obiectului Document se numr Open i Regen. Putei considera metodele ca fiind verbele unui obiect. O proprietate este orice descrie un obiect. Printre proprietile obiectului Document se numr Name i ActiveLinetype. Putei considera proprietile ca fiind adjective ce descriu un obiect.
Pe lng obiectele puse la dispoziie de AutoCAD, VBA are o serie de obiecte ncorporate, inclusiv obiectul Collection pe care tocmai l-ai vzut. Mai trziu n acest capitol vei nva s utilizai modulele de clas pentru a crea propriile dumneavoastr obiecte.
Urmtoarele dou seciuni ale exemplului arat c putei regsi elemente fie dup cheie, fie dup indicele (poziia) n cadrul coleciei. Cuvntul-cheie Item poate fi specificat sau omis la utilizarea oricrei sintaxe. Aceasta pentru c Item este metoda prestabilit a obiectului colecie. n fine, putei utiliza metoda Remove pentru a terge un articol dintr-o colecie i proprietatea Count pentru a arta numrul curent de articole dintr-o colecie.
Structuri de control
Dei limbajului BASIC original i lipseau multe caracteristici, majoritatea acestor deficiene au fost remediate n versiunile ulterioare, cum ar fi VBA. VBA este acum un limbaj de programare complet echipat, cu un set complet de structuri de control pentru cicluri, ramificare i fluxul de control. Aceast seciune va descrie structurile de control care sunt cele mai utile n aplicaii.
Structura IfThenElse
Pentru a realiza ramificarea, VBA utilizeaz o structur IfThenElse, dup cum se arat n urmtorul exemplu: Function IfDemo(intNum As Integer) As String If intNum = 1 Then IfDemo = One ElseIf intNum = 2 Then IfDemo = Two ElseIf intNum = 3 Then IfDemo = Three Else IfDemo = I dunno End If End Function n aceast structur, fiecare cuvnt cheie If i ElseIf este urmat de cte o condiie boolean ceva ce poate fi evaluat ca fiind True sau False. Cnd VBA ntlnete o condiie ce are valoarea True, execut instruciunile care urmeaz dup acea condiie. Dac includei o clauz Else, acel set de instruciuni este executat dac nici una dintre condiii nu este True. Observai c o instruciune End If este obligatorie pentru a ncheia instruciunea condiional. Figura 5 arat rezultatul executrii lui IfDemo cu diverse date de intrare.
FIGURA 5
Testarea procedurii IfDemo
Cicluri For
Uneori, programul dumneavoastr va trebui s efectueze aceeai operaie de mai multe ori; de exemplu, s adauge o sigl pe toate desenele legate de un proiect. VBA pune la dispoziie mai multe structuri de tip ciclu pentru executarea repetat a codului surs. Ciclul For este poate cel mai simplu dintre acestea, oferind o cale de executare a unui set de instruciuni de un numr predeterminat de ori. Ciclul For funcioneaz incrementnd sau decrementnd un contor: Sub ForDemo() Dim intI As Integer Ciclu For simplu: intI este incrementat cu 1 de fiecare data cand este executat ciclul For intI = 1 To 5 Debug.Print intI
STRUCTURI DE CONTROL
109
Next intI Pentru ciclu cu incrementare: in acest caz, 2 este adunat la intI la fiecare reluare a ciclului For intI = 1 To 5 Step 2 Debug.Print intI Next intI Inversare ciclu For: aici, intI este decrementat de fiecare data prin ciclu For intI = 5 To 1 Step -1 Debug.Print intI Next intI End Sub Ciclurile For sunt utile cnd tii exact de cte ori trebuie executate. Adesea, vei utiliza un ciclu For pentru a prelucra elementele unui tablou. Dac lucrai cu o colecie, putei iei n avantaj utiliznd un ciclu Do, dup cum se arat n seciunea urmtoare.
Cicluri Do
Ciclurile Do asigur o alternativ la ciclurile For atunci cnd nu tii de cte ori trebuie s executai ciclul, dar tii cnd trebuie s v oprii. Cel mai simplu ciclu Do execut o instruciune atta timp ct o condiie este True i se oprete de ndat ce aceasta devine False: Sub DoDemo1(intInput As Integer) Do While intInput > 0 Debug.Print intInput; intInput = intInput - 1 Loop End Sub Figura 6 arat rezultatul acestui ciclu. FIGURA 6
Rezultatul unui ciclu Do simplu
NOT
Semnul punct i virgul de la sfritul instruciunii Debug.Print i comunic lui VBA s pun rezultatele pe aceeai linie de ieire.
Putei de asemenea determina executarea unui ciclu Do atta timp ct o anumit condiie este False, utiliznd Until n loc de While: Sub DoDemo2(intInput As Integer) Do Until intInput = 0 Debug.Print intInput; intInput = intInput - 1 Loop End Sub
Ciclurile Do v permit de asemenea s testai condiia la sfritul ciclului, n loc s o testai la nceputul acestuia, dup cum se arat n urmtoarele dou exemple: Sub DoDemo3(intInput As Integer) Do Debug.Print intInput; intInput = intInput - 1 Loop While intInput > 0 End Sub Sub DoDemo4(intInput As Integer) Do Debug.Print intInput; intInput = intInput - 1 Loop Until intInput = 0 End Sub
NOT
Un ciclu Do cu testare la sfrit va fi executat ntotdeauna cel puin o dat, chiar dac ar fost fi omis n cazul n care testul ar fi fost la nceputul ciclului.
Operatorul GoTo
Pe lng ramificare i cicluri, VBA include un operator pentru transferul fluxului de control n alt parte din program. Acesta este renegatul GoTo, care determin continuarea execuiei ntr-un alt loc (o etichet) din cadrul procedurii: Sub GoToDemo() Debug.Print In the demo GoTo GoHere Debug.Print This wont print GoHere: Debug.Print This will print End Sub n acest exemplu, GoHere este o etichet, o instruciune neexecutabil care servete doar la marcarea unui loc din procedur. Dei utilizarea unei instruciuni GoTo este adesea asociat cu o programare neglijent, alambicat, aceast instruciune este esenial pentru detectarea erorilor n VBA, dup cum vei vedea mai trziu n acest capitol. Altfel, putei evita aproape ntotdeauna includerea unei instruciuni GoTo n programul dumneavoastr.
Utilizarea operatorilor
VBA include suport pentru diveri operatori. Tabelul 2 rezum aceti operatori. Dei VBA include reguli de preceden relativ complexe, ce reglementeaz ordinea de evaluare a operatorilor, putei utiliza ntotdeauna paranteze pentru a impune o anumit ordine a operaiilor.
111
SEMNIFICAIE
Ridicare la putere (2^3 = 8) Negaie, sau scdere nmulire (2*3 = 6) mprire (6/3 = 2) mprire cu rezultat numr ntreg (8\3 = 2) Modul Adunare Concatenarea irurilor (A & B = AB) Egalitate logic (If A = 5) Inegalitate logic (If A <> 5) Mai mic dect Mai mare dect Mai mic sau egal cu Mai mare sau egal cu Comparaie de iruri cu caractere de nlocuire Echivalena obiectelor Negaie logic i logic Sau logic Sau exclusiv logic Implicaie logic Echivalen logic
FIGURA 7
Quick Info din VBA
n acest exemplu, argumentul Prompt este obligatoriu. Celelalte argumente sunt opionale, dup cum indic parantezele drepte ce nconjoar fiecare argument. Argumentul Buttons As trebuie s fie una dintre valorile din enumerarea intern VbMsgBoxStyle, pe care o putei afia utiliznd Object Browser sau ncepnd s introducei argumentul. n fine, valoarea returnat de funcie va fi una dintre valorile permise de enumerarea VbMsgBoxResult. Pe msur ce lucrai cu VBA, Quick Info se va dovedi extrem de util. Dac ajungei s nvai argumentele pentru fiecare funcie i Quick Info ncepe s deranjeze, l putei dezactiva selectnd Tools Options Editor.
NOT
Argumentele Prompt i Title furnizeaz textul i titlul pentru caseta de dialog. Argumentul Buttons controleaz aspectul casetei de dialog; acesta accept o serie de constante pe care le putei vedea consultnd informaiile de asisten IntelliSense pentru funcie. Ultimele dou argumente v permit s specificai un fiier de asisten i un subiect de asisten ce vor fi utilizate dac utilizatorul apas tasta F1 n timp ce este afiat caseta de dialog. Figura 8 arat caseta de dialog produs de urmtoarea instruciune: MsgBox Unable to Save File, _ vbAbortRetryIgnore + vbCritical, File Error FIGURA 8
O mostr de caset de dialog afiat de MsgBox
Valoarea returnat de un apel la funcia MsgBox este o constant ce indic butonul pe care utilizatorul a executat clic. Dei aceste constante sunt numerice, utilizai ntotdeauna constante VBA interne pentru a evalua aceast valoare returnat. Aceasta face programul dumneavoastr mai lizibil i v protejeaz mpotriva viitoarelor schimbri poteniale de valori literale ale diferitelor constante. Procedura MsgBoxDemo ilustreaz aceast tehnic. Sub MsgBoxDemo() Dim intRet As Integer intRet = MsgBox(Unable to Save File, _ vbAbortRetryIgnore + vbCritical, File Error) Select Case intRet Case vbAbort Debug.Print You chose Abort
113
Case vbRetry Debug.Print You chose Retry Case vbIgnore Debug.Print You chose Ignore End Select End Sub Funcia InputBox utilizeaz apte argumente, dei majoritatea sunt opionale: InputBox( Prompt[, Title][, Default][, XPos][, YPos] _ [, HelpFile, Context] i n acest caz, argumentele Prompt i Title controleaz textul i titlul din caseta de dialog. Argumentul Default furnizeaz o valoare returnat, iar urmtoarele dou argumente v permit s specificai locul n care va fi afiat caseta de dialog. Ca exemplu, figura 9 arat caseta de dialog generat de urmtorul apel: InputBox Enter a Number, Numeric Prompt, 27 Valoarea returnat de funcia InputBox este de tipul variant i este tastat de utilizator n elementul de control editabil din caseta de dialog. FIGURA 9
O mostr de InputBox
NOT
La fel ca AutoLISP, VBA solicit ca argumentele funciilor trigonometrice s fie exprimate n radiani.
REZULTATE
Returneaz valoarea ASCII a primului caracter din strX. Returneaz un ir a crui valoare ASCII este n. Returneaz poziia din str1 la care apare str2 ca subir. Se ncepe cutarea acestuia de la poziia Start. Returneaz varianta scris cu litere mici a lui strU. Returneaz numrul de caractere din strX.
Tabelul 3 (continuare)
FUNCIE
LTrim(strX) Mid(strX, Start, Length) Right(strX, n) RTrim(strX) Space(n) Trim(strX) UCase(strL)
REZULTATE
Returneaz valoarea absolut a lui x. Returneaz arctangent de x. Returneaz cosinus de x. Returneaz cel mai mare ntreg care este mai mic sau egal cu x. Returneaz logaritm natural din x. Returneaz 1 dac x este pozitiv i -1 dac x este negativ. Returneaz sinus de x. Returneaz rdcina ptrat din x. Returneaz tangent de x.
115
REZULTATE
Returneaz ora curent. Returneaz data curent. Returneaz data i ora curent. Adun numrul specificat de intervale de timp la data specificat. Returneaz numrul de intervale de timp dintre data1 i data2. Returneaz ziua din sptmn n care cade data specificat.
INTERVAL
An Trimestru Lun Zi din an (de la 1 pn la 366) Zi Zi din sptmn Sptmn Or Minut Secund
Tratarea erorilor
Este important s v asigurai c programul VBA se ocup de orice eroare care poate aprea n cursul rulrii aplicaiei dumneavoastr. Erori nu sunt doar cele cauzate de greeli n program. n VBA este adesea necesar s producei o eroare n cursul obinuit al unei aplicaii. De exemplu, pentru a determina dac un disc se afl ntr-o unitate, este cel mai simplu s ncercai s scriei un fiier pe acea unitate i s interceptai eroarea n cazul n care unitatea este goal. n aceast seciune, vei nva s scriei cod ce se ocup de tratarea erorilor i s folosii obiectele Err i Debug pentru a extrage informaii despre erori.
NOT
Putei mpiedica utilizatorii finali s vad codul surs al proiectului dumneavoastr, indiferent dac a aprut o eroare sau nu, prin protejarea proiectului. Din meniurile VBE, selectai Tools Project Properties (Instrumente Proprietile obiectelor), executai clic pe eticheta Protection i bifai caseta de validare Lock Project for Viewing (mpiedic afiare proiect).
n caseta de dialog ce raporteaz eroarea la rulare, executnd clic pe butonul End vei ncheia executarea programului, pe cnd printr-un clic pe butonul Debug vei opri executarea programului i vei evidenia linia care a produs eroarea. n majoritatea aplicaiilor, acest comportament prestabilit este inacceptabil. n general, vei folosi instruciunea VBA On Error GoTo pentru a trimite toate erorile ctre un anumit loc (la o anumit etichet) din codul surs, urmnd s v ocupai de erori acolo, pentru a mpiedica intrarea n funciune a mecanismului prestabilit de tratare a erorilor din VBA. Funcia ErrorDemo2 arat cum putei face acest lucru n cazul funciei date de noi ca exemplu. Function ErrorDemo2(intX As Integer) As Integer On Error GoTo HandleErr ErrorDemo2 = 10 / intX ExitHere: Exit Function HandleErr: Select Case Err.Number Case 11 Division by zero MsgBox Zero is not a legal input Case Else MsgBox Err.Number & & Err.Description, _ vbCritical, Error in ErrorDemo2 End Select Resume ExitHere End Function
117
1. Instruciunea On Error GoTo i comunic lui VBA c n cazul apariiei oricrei erori ar trebui s ncheie
execuia la eticheta HandleErr.
2. Apoi, funcia continu execuia normal. 3. Dac totul decurge bine, instruciunea Exit Function va fi ultima executat. 4. Dac apare vreo eroare, execuia continu de la HandleErr. 5. Instruciunea Select Case ia o decizie n funcie de numrul erorii. (A se vedea seciunea urmtoare
pentru detalii privind obiectul Err.)
6. Funcia include un mesaj special pentru o anumit eroare, mprirea la 0, pe care realizatorul funciei o
anticipa.
7. Pentru orice alt eroare, funcia i afieaz utilizatorului un mesaj informativ. Funcia nu ofer alte
informaii suplimentare n afar de cele furnizate de VBA n mod prestabilit, dar prin tratarea erorilor, funcia mpiedic oprirea execuiei.
Obiectul Err
n codul dat ca exemplu pentru tratarea erorilor, poate ai observat referirile la Err.Number i Err.Description. Acestea sunt dou proprieti ale obiectului Err, un fragment funcional separat, inclus n VBA. La fel cum AutoCAD are un model de obiecte (prezentat pe larg n capitolul anterior de pe acest CD), i VBA furnizeaz cteva obiecte. Dac se produce o eroare n codul surs, o putei determina citind proprietile obiectului Err, care vor reflecta cea mai recent eroare. (Dac nu s-a produs nici o eroare, Err.Number va fi 0.) Tabelul 7 prezint cele mai importante proprieti ale obiectului Err.
SEMNIFICAIE
Numrul al celei mai recente erori. Textul aferent celei mai recente erori. Sursa celei mai recente erori. De exemplu, dac se produce o eroare cnd lucrai cu elementele de control dintr-un formular, Source va fi MSForms. Numr de eroare dintr-un apel la Windows API.
OBIECTUL DEBUG
Un al obiect VBA care poate fi util n tratarea codului surs este obiectul Debug. Obiectul Debug are o singur metod, Print, care-i permite programului dumneavoastr s trimit un mesaj n fereastra Immediate. Dac nu v putei da seama ce nu este corect atunci cnd programul are un comportament necorespunztor, putei utiliza obiectul Debug pentru a v ajuta s aflai despre ce este vorba. De exemplu, dac exist o variabil, lngCount, care ia o valoare necorespunztoare, putei determina programul dumneavoastr s tipreasc valoarea curent a variabilei n fereastra Immediate, insernd urmtoarea linie de program: Debug.Print lngCount Obiectul Debug are efect doar cnd rulai codul surs n editor. Cnd utilizatorii interacioneaz cu aplicaia dumneavoastr, ei nu vor vedea aceste mesaje.
ECHIVALENT VBA
+ * / = <> < <= > >= Not
119
Tabelul 8 (continuare)
COMAND AUTOLISP
1+ 1abs ads alert and angle angtof angtos arx arxload arxunload ascii atan atof atoi chr close cond cos dictadd dictnext dictremove dictrename dictsearch entmake entupd
Tabelul 8 (continuare)
COMAND AUTOLISP
equal *error* exp expt findfile fix float foreach getangle getcfg, getenv getcorner getdist getint getkword getorient getpoint getreal getstring getvar graphscr handent if itoa last list listp
121
Tabelul 8 (continuare)
COMAND AUTOLISP
log logand logior lsh max min minusp nentsel nitget null numberp open polar read-char read-line regapp rem repeat rtos set setvar sin sqrt ssadd ssdel ssget
Tabelul 8 (continuare)
COMAND AUTOLISP
sslength ssname startapp strcase strcat strlen substr trans ver vports wcmatch while write-char, write-line xload xunload zerop
Extragei acea poriune din numele complet al unei ci de acces la un fiier, care urmeaz dup ultimul slash (diagonal la dreapta), pentru a returna doar numele fiierului. Scriei o procedur ce returneaz media unui set de numere stocate ntr-un tabel. Scriei o procedur ce utilizeaz teorema lui Pitagora, pentru a returna distana dintre dou puncte ntr-un desen 2D (bidimensional) sau 3D (tridimensional).
Vei gsi de asemenea o serie de exemple de proiecte VBA, n directorul AutoCAD Samples/VBA de pe hard-discul calculatorului dumneavoastr, dac ai efectuat o instalare integral a programului AutoCAD.