Folosirea variabilelor de obiect pentru a reprezenta obiecte

După cum s-a descris pe pagina Lucrul cu variabile, constante și enumerări, unul dintre tipurile de date disponibile pentru variabilele din VBA este tipul Object. O variabilă Object se folosește pentru a reprezenta un obiect din cod: în locul referirii direct la obiect, se poate folosi variabila Object pentru a accesa sau manipula obiectul pe care îl reprezintă.

Iată un avantaj major al acestei abordări: folosind variabilele Object, codul este mai ușor de citit. Este mai simplu să vedem ce obiect are o secțiune a codului, mai ales când se lucrează cu mai multe obiecte din aceeași secțiune de cod. În plus, se pot da nume descriptive acestor variabile ușor de înțeles. Mai mult, variabilele Object sunt adesea o necesitate când trebuie manipulate colecții de obiecte.

De exemplu, presupunem că se creează o procedură care manipulează cele trei registre de lucru deschise în Excel, copiind mai multe celule dintr-un registru în celălalt. Dacă sunt deschise doar cele trei registre de lucru, se face referire la ele prin Workbooks(1), Workbooks(2) și Workbooks(3), deoarece acestea vor ocupa doar (și numai) cele trei sloturi din colecția Workbooks.

Dar dacă procedura modifică ordinea registrelor de lucru, închide unul sau mai multe registre de lucru sau creează unul sau mai multe registre de lucru noi, lucrurile devin rapid confuze. Dacă, totuși, au fost create variabile de obiecte (numite, de exemplu, xlWorkbook1, xlWorkbook2 și xlWorkbook3) care se referă la respectivele registre de lucru, va fi mult mai ușor să fie identificate. Acest lucru se datorează faptului că, indiferent de ce registru de lucru se mută la prima poziție în colecția Workbooks, se poate face referire la obiectul reprezentat de variabila Object xlWorkbook1 și va fi accesat registrul de lucru ales anterior. Cu alte cuvinte, atunci când sunt create variabile de tip Object, li se pot da nume folosind cuvinte care sunt mai ușor de înțeles decât numerele de index. Mai important, odată ce este numit, numele variabilei Object nu se schimbă. Numerele indecșilor se pot schimba.

O variabilă Obiect se declară aproape la fel ca și orice altă variabilă, folosind o instrucțiune Dim, Private sau Public. Dar se specifică tipul As Object. De exemplu, următoarea declarație declară variabila Object objMyObject:

Dim objMyObject As Object

Ca de obicei, la folosirea instrucțiunii Dim, dacă această declarație se folosește în cadrul unei proceduri, aceasta creează o variabilă cu domeniu de aplicare local. Dacă se folosește în secțiunea de declarații din partea de sus a codului, se creează o variabilă cu domeniul de aplicare Private la nivel de modul. În mod similar, cuvintele cheie Private și Public creează variabile de obiect privat, respectiv public, la nivel de modul.

După ce se declară variabila Obiect, i se poate atribui un obiect. (Atribuirea obiectelor funcționează puțin diferit de modul de atribuire a unei valori unei variabile obișnuite în care se folosește semnul egal.) Pentru a atribui un obiect unei variabile Object, se folosește instrucțiunea Set. Sintaxa pentru o instrucțiune Set este:

Set objectvariable = {[New] expression|Nothing}

Iată și descrierea sintaxei:

  • Objectvariable este numele variabilei Object care se atribuie obiectului.
  • New este un cuvânt opțional care se folosește la crearea implicită a unui obiect nou în clasa specificată. Totuși, se recomandă crearea explicită a obiectelor și apoi atribuirea lor la variabilele Object în locul folosirii cuvântului New pentru crearea implicită a lor.
  • expression este o expresie obligatorie care specifică sau întoarce obiectul care va fi atribuit la variabila Object.
  • Nothing este un cuvânt opțional care se atribuie unei variabile Object existente pentru a o goli de conținut și a elibera memoria pe care a ocupat-o.

De exemplu, următoarele comenzi declară variabila Object numită objMyObject și o atribuie la registrul de lucru activ din Excel:

Dim objMyObject As Object
Set objMyObject = ActiveWorkbook

Următoarea instrucțiune folosește cuvântul cheie Nothing pentru a elibera memoria ocupată de variabila Object numită objMyObject:

Set objMyObject = Nothing

Comparativ cu declararea altor tipuri de variabile, la declararea unei variabile Object se poate declara variabila Object ca fiind de tip Object și se poate folosi comanda Set penstru ca să se specifice ce tip de obiect este. De exemplu, dacă o variabilă Object va reprezenta întotdeauna un obiect Workbook, poate fi declarată ca fiind de tip Workbook. Următoarea declarație declară variabila Object xlWorkbook1 ca de tip de date Workbook:

Dim xlWorkbook1 As Workbook

Astfel, asocierea unui tip cu o variabilă Object are câteva avantaje. În primul rând, după ce se introduce strongly typed (așa cum se numește) variabila Object, Editorul Visual Basic poate oferi asistență completă pentru variabila Object, ca și la obiectul direct. De exemplu, după crearea variabilei Object xlWorkbook1 a tipului de obiect Workbook, editorul Visual Basic afișează lista derulantă Auto List Members când se tastează numele variabilei Object urmată de un punct.

În al doilea rând, când se introduce (strongly type) o variabilă Obiect, se obțin mai greu lucruri greșite în cod. Dacă se încearcă atribuirea unui tip greșit de obiect la o variabilă Object introdusă cu strongly type, VBA afișează o eroare. De exemplu, la crearea unei variabile Object numită Worksheet în Excel, ca în prima dintre instrucțiunile următoare, dar i se atribuie un obiect Workbook, ca în cea de-a doua instrucțiune, VBA afișează un mesaj de eroare " Type Mismatch " atunci când se execută acest cod – așa cum trebuie:

Dim wksSheet1 As Worksheet
Set wksSheet1 = ActiveWorkbook 

Este preferabil faptul că la această etapă de testare este afișată eroarea, în loc să apară mai târziu (de exemplu, când se manipulează obiectul wksSheet1 și nu se comportă conform așteptărilor).

Argumentul principal pentru renunțarea la strongly type pentru o variabilă Object este că uneori (înainte de a scrie codul) este posibil să nu se cunoască exact ce fel de obiect va fi referit în timpul executării sau dacă tipul de obiect pe care îl va stoca poate varia de la un executarea codului la altul. (Dacă este cazul, codul va trebui să fie suficient de flexibil pentru a găzdui obiecte de diferite tipuri pentru aceeași variabilă Object.) Însă se recomandă declararea strongly type la toate variabilele Object.

În cazul în care nu se știe sigur ce tip de obiect se va utiliza pentru o variabilă Obiect, se începe prin declararea variabilei Object ca fiind a tipului de date Obiect. Apoi se rulează codul de câteva ori, având deschisă fereastra Locals (View > Locals Window) și se notează tipul de date pe care VBA îl atribuie variabilei Obiect. De exemplu, dacă se apasă în mod repetat tasta F8 pentru a trece prin următoarele instrucțiuni într-o sesiune a Visual Basic Editor găzduită de Excel, citirea în fereastra Locals identifică mai întâi variabila Object wks doar ca Obiect.

Acest lucru nu este prea util. Dar dacă se apasă încă o dată tasta F8 pentru a executa comanda Set se pot vedea o mulțime de informații (apăsând pictograma + de lângă wks). Acum se poate vedea Object/Sheet1 atunci când se execută a doua instrucțiune de atribuire a primei foi din registrul de lucru activ. De asemenea, se pot vedea toți membrii, valorile actuale și tipul acestora.

Fereastra Locals se poate folosi pentru a identifica tipul de obiect conținut în variabila Object
Dim wks As Object
Set wks = ActiveWorkbook.Sheets(1) 

Sunt și dezavantaje la introducerea variabilelor Weakly Typed

După cum s-a descris anterior, se poate evita specificarea tipurilor de date folosind tipul Variant. De exemplu, declarația Dim varMyVariant creează o variabilă Variant, deoarece instrucțiunea nu specifică un tip de date. Variabilele Variant pot conține obiecte, precum și alte tipuri de date – dar, pentru Variant, VBA va efectua o activitate mai intensă de fiecare dată când întâlnește variabila (deoarece VBA trebuie să determine ce tip de date să folosească) și neagă beneficiile pentru introducerea variabilelor. De asemenea, Weak typing face ca codul să fie mai greu de citit.