Sunteți pe pagina 1din 21

Functii de cautare in Excel (nivel avansat)

Publicat de gecs in categoria Formule, Functii tip Lookup - 4 Comentarii - (3 August, 2011 la ora
7:22 am)

Cautam cautam Ne cautam cheile de la casa, de la masina, ochelarii de pe nas, hartiuta aia pe care am scris ceva important alaltaieri si pe care am pus-o undeva, bine, sa nu uitam de ea Cautam o adresa, un numar in memoria telefonului, da cate nu cautam Pana si in Excel avem de cautat si daca datele unde trebuie sa scormonim se intind pe vreo cateva sute (poate chiar mii) de randuri, musai sa stim sa cautam bine (!) Pana sa discutam despre functiile de cautare pe care ni le pune la dispozitie Excel-ul, trebuie sa observam ca sunt patru elemente care caracterizeaza intotdeauna o cautare: ce cautam; unde cautam; cum cautam; ce rezultat asteptam in urma cautarii.

De regula cautam o valoare, iar valoarea cautata poate fi una concreta, sau o valoare pe care n-o stim exact, dar stim ca trebuie sa indeplineasca anumite criterii. Daca in prima situatie lucrurile sunt relativ simple, in cea de-a doua va trebui sa stapanim si alte proceduri in afara functiilor de cautare. Inainte de discutia despre unde cautam va trebui sa lamurim cateva lucruri mai generale. In primul rand vor trebui bine stapanite adresarea si referinta. Pentru ca o discutie mai extinsa asupra acstor aspecte ar lungi prea mult lucrurile, consideram ca adresarea folosind stilurile A1 sau R1C1 precum si referinta relativa, absoluta, sau mixta sunt lucruri comune si deja insusite. De asemenea ceva experienta in utilizarea functiilor ADDRESS() si INDIRECT() ar fi de mare ajutor.

In al doilea rand ar trebui subliniat ca nu putem face abstractie de faptul ca un proces de cautare se poate desfasura pe un volum important de date. Oricare dintre functiile de cautare existente in Excel are ca argument (alaturi de altele) si unde cautam. Deoarece descrierile functiilor de cautare din help-ul programului fac referire atat la range, cat si la array, cat si la vector cred ca e necesara o scurta discutie asupra semnificatiei acestor denumiri. Toate reprezinta tablouri de date. Daca in cazul vectorului lucrurile sunt mai simple pentru ca e vorba de un tablou de date cu o singura dimensiune (o coloana sau un rand), fie privit ca range, fie ca array, in ceea ce priveste diferenta dintre range si array aveasta e ceva mai subtila. Sinonime in aparenta, range-ul este un tablou de date care exista fizic intr-o pagina de Excel, pe cand array-ul e tot un tablou de date care insa exista doar in memorie e volatil daca valorile lui nu sunt inscrise undeva, intr-un range. Cele mai multe functii, inclusiv cele de cautare, au inteligenta necesara de a transforma un range intr-un array, de aceea explicatiile din help fac in general referinta la array, dar pe parcursul explicatiilor e inscrisa si echivalenta cu range-ul. O formulare de genul: array a range of cells nu poate fi altfel interpretata decat in sensul inteligentei despre care vorbeam mai sus pentru ca se pot folosi ca argumente si array-uri de constante care exista doar in corpul functiei respective, ca argumente, fara sa existe fizic in vreo foaie de calcul. Forma sub care se pot scrie aceste array-uri este: {1,2,3;a,b,c} unde acoladele marginesc datele array-ului, virgulele separa elementele aceluiasi rand (coloana), iar punctul si virgula serpara coloanele (randurile). In al treilea rand (parca la trei ramasesem cu insiruirea) pentru definirea setului de date in care se face cautarea (fie el range sau array) o buna intelegere si experienta in lucrul cu functiile care pot fi folosite la definirea range-urilor sunt binevenite. Daca pana acum n-ati facut cunostinta cu domnul OFFSET(),ar fi bine sa stiti ca dumnealui returneaza un range si e foarte folositor si in (sau poate in primul rand in) functiile de cautare. Asa stand lucrurile, inainte de a vorbi despre functiile de cautare propriu-zise, e musai sa-l descoperim pe domnul OFFSET().

Dupa cum spuneam, domnul OFFSET() returneaza un range si are urmatoarele argumente: OFFSET(celula_de_referinta, randuri, coloane, randuri_in_range,coloane_in_range) celula_de_referinta adresa celulei de la care se aplica urmatoarele doua argumente ale functiei pentru determinarea range-ului de returnat; randuri distanta in randuri de la celula_de_referinta pana la inceputul range-ului de returnat; coloane distanta in coloane de la celula_de_referinta pana la inceputul range-ului de returnat;

randuri_in_range numarul de randuri ale range-ului de returnat; coloane_in_range numarul de coloane ale range-ului de returnat;

Deocamdata atat despre OFFSET() (nu-i mai spunem domn fiindca deja am facut cunostinta cu el si pare destul de prietenos), dar vom vedea mai departe cat de folositor poate fi si, in consecinta, cat de prieteni cu el trebuie si noi sa fim.

Cum cautam e simplu: intotdeauna de sus in jos si de la stanga la dreapta. Mai exista insa si alte conditii in afara de cele triviale pe care le-am mentionat, conditii specifice fiecarei functii de cautare in parte, care figureaza fie ca argumente explicite ale functiilor, fie ca mod implicit de cautare, fara prezenta unor argumente asociate. Rezultatul returnat de oricare din functiile de cautare depinde in mod direct de valoarea (implicita sau explicita) a acestui argument. De fapt acest argument reprezinta modul in care se face comparatia elementului cautat cu elementele componente ale tabloului de date in care cautam. De exemplu, daca dorim o potrivire exacta (exact match) a valorii cautate cu una dintre valorile aflate in range-ul in care cautam, in anumite situatii va trebui sa declaram aceasta intr-un mod explicit, iar daca in urma cautarii potrivirea exacta nu a fost gasita, functia va returna o eroare. E posibil sa cautam o potrivire aproximativa (approximate match), sau sa indicam o comparatie de tipul < sau > (mai mic sau mai mare) pentru realizarea cautarii, dar folosirea acestor variante presupune intotdeauna o ordonare intr-un sens crescator sau descrescator a valorilor din coloanele (randurile) unde se face comparatia pentru realiarea cautarii. Diferite de la functie la functie, argumentele care indica modul de cautare (cum_cautam), le vom discuta mai aplicat in sectiunile destinate fiecarei functii de cautare in parte.

Pana sa luam fiecare functie de cautare in parte si sa-i descoperim caracteristicile si intrebuintarile, a mai ramas sa discutam la modul general despre ce fel de rezultat asteptam de la functiile de cautare. De cele mai multe ori asteptam ca rezultat o valoare asociata valorii cautate, dar sunt situatii in care ne intereseaza doar daca valoarea cautata exista, sau pozitia (randul sau coloana) in care se afla aceasta. Functiile de cautare vor intoarce intotdeauna un rezultat, fie ca e vorba de o valoare (cea cautata, sau nu, in functie de cat de bine am folosit functia respectiva), fie ca e vorba de o eroare pentru ca in urma cautarii nu s-a gasit valoarea respectiva in conditiile cerute, sau pentru ca argumentele furnizate nu respecta conditiile solicitate. In functie de cum vrem sa arate datele noastre care cuprind si formule care pot returna erori, trebuie sa fim pregatiti pentru tratarea acestor erori,

cunoscand modul de functionare al urmatoarelor functii: IF(), IFERROR(), ISERR(), ISERROR() si ISNA().

Acestea fiind zise si, sper eu, si cat-de-cat intelese, Sa le numaram, coane Fanica (vorba poetului fo) Raspunsul e tot de pus intre ghilimele: Cei patru evanghelisti sunt urmatorii trei: Luca si Matei (!) Culmea e ca initialele chiar se potrivesc: Lookup si Match!!! Acestea sunt cele doua functii de cautare de baza. LOOKUP() are si variantele VLOOKUP() si HLOOKUP(), iar MATCH() se foloseste de obicei in combinatie cu INDEX().Si asa se explica si raportul dintre primul citat si al doilea, fiindca la numaratoare ne ies 5 in loc de 4 (Ghita! Renumeratie dupa buget mica, coane Fanica, sa traiti fo)

LOOKUP() Help-ul acestei functii ne spune ca exista doua forme in care putem folosi LOOKUP: forma vectoriala si forma de tip array. Sintaxa functiei difera si ea de la forma la forma, dupa cum urmeaza: Forma vectoriala: LOOKUP(valoare, vector_de_cautat,vector_de_returnat_rezultat); Forma de tip array LOOKUP(valoare,array).

Argumentele functiei in forma vectoriala inseamna: valoare valoarea de cautat care poate fi sub forma unei valori, o referinta la o valoare de tip numeric, sir de caractere, sau logic, sau o functie care returneaza asemenea tipuri de valori; vector_de_cautat vectorul in care se cauta; vector_de_returnat_rezultat vectorul din care se returneaza rezultatul.

Functia cauta valoarea in vectorul furnizat ca al doilea argument si returneaza valoarea asociata pozitiei din vectorul furnizat ca al treilea argument. Pentru ca functia sa returneze un rezultat corect primul vector trebuie sa aiba valorile ordonate crescator (,-2, -1, 0, 1,

2, , A-Z, FALSE, TRUE), iar cei doi vectori furnizati ca argumente vor trebui sa aiba acelasi numar de elemente.

Functia nu face distinctie intre majuscule si minuscule la comparatia sirurilor de caractere. In cazul in care valoarea cautata nu se afla printre valorile din vectorul de cautat, functia foloseste relatia cea mai mare dintre cele mai mici sau egale cu valoarea cautata valori pentru a face corespondenta intre valoarea cautata si valorile din vectorul de cautat. Daca valoarea cautata e mai mica decat orice valoare din vectorul de cautat functia returneaza eroarea #N/A.

In figura de mai jos gasiti o ilustrare a folosirii functiei LOOKUP() pentru a atasa calificative valorilor notelor obtinute de o grupa de elevi/studenti.

In exemplul de mai sus argumentele al doilea si al treilea sunt de fapt range-uri din aceeasi foaie de calcul (aceste range-uri se pot afla si in alte foi de calcul, dar in aceasta situatie referinta ar trebui prefixata de denumirea foii de calcul si separatorul !). De asemenea este de remarcat folosirea referintelor absolute in cazul range-urilor furnizate ca argumente si a referintei relative in cazul valorii de cautat pentru ca la copiere formula sa actualizeze doar referinta (relativa) a valorii de cautat, referintele absolute pastrandu-se nemodificate.

Aceeasi formula se poate scrie folosind array-uri de constante pentru al doilea si al treilea argument: =LOOKUP(B2,{0,5,7,9, absent},{nesatisfacator,satisfacator,bine,foarte bine,X})

Argumentele functiei in forma de tip array insemana: valoare valoarea de cautat care poate fi sub forma unei valori, o referinta la o valoare de tip numeric, sir de caractere, sau logic, sau o functie care returneaza asemenea tipuri de valori; array tabloul de valori in care se face cautarea si din care se face si returnarea valorii asociate;

Al doilea argument, cel de tip array, va trebui sa fie un tablou de valori de minimum 2 randuri (sau doua coloane) pentru a returna o valoare asociata valorii de cautat. In cazul in care se furnizeaza ca al doilea argument un array cu o singura linie (coloana), valoarea returnata va fi insasi valoarea de cautat. Modul de cautare este acelasi ca la forma vectoriala, iar pentru stabilirea modului de parcurgere al array-ului (pe linie sau pe coloana) se compara cele doua dimensiuni ale tabloului si se alege cea mai mare. In imaginea de mai jos e reluat exemplul anterior, dar cu folosirea formei de tip array a functiei LOOKUP():

Iata si forma cu array de constante pentru acceasi situatie: =LOOKUP(B2,{0,5,7,9, absent;nesatisfacator,satisfacator,bine,foarte bine,X}) In exemplul de mai jos functia LOOKUP() e folosita pentru returnarea denumirii zilei saptamanii pentru un sir de date dintr-un tabel:

Comparand cele doua forme al functiei LOOKUP(), putem spune ca prima forma ofera posibilitatea ca al treilea argument sa nu fie strict legat de al doilea fapt evident atunci cand folosim ca argumente range-uri (al doilea si al teilea argument pot fi range-uri aflate in foi de lucru diferite, in pozitii diferite pe foaia de lucru etc.).

VLOOKUP() si HLOOKUP() Cele doua functii sunt forme ale functiei LOOKUP() si singura diferenta dintre ele este aceea caVLOOKUP() executa o cautare pe verticala (cautand valoarea de cautat in prima coloana a unui range), in timp ce HLOOKUP() cauta pe orizontala (cautand valoarea de cautat in primul rand al unui range). Ma voi referi doar la VLOOKUP(), analogia cu HLOOKUP() fiind foarte usor de facut avand in vedere singura diferenta dintre cele doua, mentionata mai sus.

Forma generala a functiei este urmatoarea: VLOOKUP(valoare, tablou_array, index_coloana, [modul_de_comparatie]) valoare valoarea de cautat care poate fi sub forma unei valori, o referinta la o valoare de tip numeric, sir de caractere, sau logic, sau o functie care returneaza asemenea tipuri de valori; daca valoarea furnizata e mai mica decat orice valoare din prima coloana a celui deal doilea argument, functia returneaza eroarea #N/A; tablou_array range pe a carui prima coloana se face cautarea; se poate folosi o referinta la un range sau un nume asociat range-ului respectiv; datele din range pot fi numerice, siruri de caractere sau de tip logic ne se face distinctia intre minuscule si majuscule; index_coloana numarul coloanei tabloului (furnizat ca al doilea argument) de pe care se va returna valoarea in cazul gasirii valorii cautate pe prima coloana (1 este indexul primei coloane al tabloului furnizat ca al doilea argument); valoarea acestui argument trebuie sa fie numerica de tip intreg (poate fi si o referinta, sau o alta functie care returneaza o valoare numerica) dar daca e mai mica decat 1 se va returna eroarea #VALUE!, iar daca valoarea acestui argument depaseste numarul de coloane al celui de-al doilea argument va fi returnata eroarea #REF!; modul_de_comparatie argument optional de tip logic, prin care se specifica modul in care se face comparatia pentru a stabili daca valoarea cautata a fost gasita: FALSE pentru o potrivire exacta, TRUE (sau omis) pentru o potrivire aproximativa, caz in care se utilizeaza metoda de potrivire de la LOOKUP(cea mai mare dintre cele mai mici valori decat valoarea cautata sau egala cu valoarea cautata) si tot ca la LOOKUP, array-ul trebuie sa fie ordonat ascendent dupa prima coloana.

Din exemplele urmatoare ne vom lamuri si mai bine cum functioneaza VLOOKUP(). In primul exemplu functia VLOOKUP() e folosita pentru completarea automata a greutatii unui reper dintr-un extras de armaturi folosit in proiectarea de rezistenta in constructii. Mai intai se realizeaza intr-o foaie de lucru urmatorul tabel:

Denumim tabelul creat armaturi (se selecteaza celulele si se tasteaza armaturi in Name Box confirmat cu Enter). Tabelul in care dorim sa folosim informatia din tabelul armaturi ar arata cam asa:

In exemplul de mai sus functia VLOOKUP() e folosita pentru returnarea greutatii unitare a barei in functie de diametrul acesteia (in E4 si apoi copiata in jos, pe coloana). Functia folosita in celula F4 si apoi copiata in jos, pe coloana, calculeaza greutatea totala aferenta pozitiei respective din lista, dar verifica si existenta datelor in celulele care sunt implicate in calcul, iar in cazul in care fie grutatea unitara, fie numarul de bucati nu au fost completate, returneaza un sir vid (). Se pot imagina nenumarate exemple de folosire a functiilor VLOOKUP() sau HLOOKUP() in situatiile in care cunoastem o informatie si dorim returnarea informatiilor asociate acesteia dintr-o lista prestabilita si intretinuta in timp. Legat de folosirea functiilor VLOOKUP() si HLOOKUP() merita amintit faptul ca ambele impun restrictia cautarii unei valori pe prima coloana (primul rand) al range-ului furnizat ca al doilea argument. O alta observatie valabila pentru toate functiile de cautare, este aceea ca o data gasita valoarea cautata in tabloul de date folosit pentru cautare functia va furniza valoarea asociata, fara a exista posibilitatea de a specifica o eventuala continuare a cautarii pentru a gasi eventualele alte aparitii in tabloul de date a valorii cautate. Pentru rezolvarea unei asemenea probleme va trebui sa imaginam o formula mai complexa, eventual de o factura speciala, care sa poata extinde cautarea si dupa prima aparitie a valorii de cautat. Un exemplu in acest sens va fi discutat in finalul acestui articol.

MATCH() Similara functiilor descrise mai sus, functia MATCH() nu mai returneaza o valoare asociata valorii cautate ci pozitia valorii cautate in segmentul de date furnizat ca al doilea argument. Forma generala a functiei este urmatoarea: MATCH(valoare, tablou_array, [modul_de_comparatie]) valoare valoarea de cautat care poate fi sub forma unei valori, o referinta la o valoare de tip numeric, sir de caractere, sau logic, sau o functie care returneaza asemenea tipuri de valori; tablou_array range-ul in care se face cautarea; se poate folosi o referinta la un range sau un nume asociat range-ului respectiv; datele din range pot fi numerice, siruri de caractere sau de tip logic; modul_de_comparatie argument optional de tip numeric (-1, 0 sau 1), prin care se specifica modul in care se face comparatia pentru a stabili daca valoarea cautata a fost gasita (nu se face distinctia intre minuscule si majuscule): 0 pentru o potrivire exacta, 1 (sau omis) pentru o potrivire aproximativa, caz in care se utilizeaza metoda de potrivire de la LOOKUP (cea mai mare dintre cele mai mici valori decat valoarea cautata sau egala cu valoarea cautata) si tot ca la LOOKUP, array-ul trebuie sa fie in ordine ascendenta, -1 pentru situatia in care dorim o potrivire aproximativa inversa ca cea folosita in cazul functiei LOOKUP() cea mai mica sau egala cu valoarea de cautat dintre valorile mai mari decat aceasta, cu conditia ca array-ul furnizat ca al doilea argument sa fie ordonat descrescator. Pozitia returnata este intotdeauna relativa la elementul de inceput al array-ului furnizat ca al doilea argument. De exemplu, daca array-ul furnizat ca al doilea argument este C3:C100, iar valoarea cautata s a potrivit cu valoarea din celula C5, functia va returna valoarea 3. In cazul folosirii functiei cu primul argument sir de caractere si al treilea argument 0 se pot folosi wild card-uri (* pentru un grup de caractere si ? pentru un singur caracter). Daca se doreste gasirea chiar a caracterelor * sau ?, acestea trebuie prefixate de o tilda ~. Daca functia nu a gasit nicio potrivire a valorii cautate in conditiile specificate de parametrul al treilea, se returneaza eroarea #N/A. In general utilizarea acestei functii este similara utlizarii functiilor descrise anterior, cu mentiunea ca in afara de avantajele folosirii wild card-urilor si a metodei inverse de potrivire fata de familia LOOKUP, mai exista si flexibilitatea ordinii de cautare (pe rand sau pe coloana), iar in combinatie cu INDEX() dispare si restrictia legata de cautare a valorii asociate in prima sau ultima coloana (rand) a array-ului in care se cauta. Pana la prezentarea unui exemplu legat de folosirea functiei MATCH() cred ca ar fi bine sa aruncam mai intai o privire si asupra functiei

INDEX() Nu este tocmai o functie de cautare, ci mai degraba o functie care returneaza o referinta la un range, functia INDEX() se prezinta si ea tot sub doua forme: forma referinta si forma array. Ma voi opri aici doar asupra formei array, a carei sintaxa generala este: INDEX(array, numar_rand, numar_coloana) array range-ul in care se face cautarea; se poate folosi o referinta la un range sau un nume asociat range-ului respectiv; datele din range pot fi numerice, siruri de caractere sau de tip logic poate fi si un array de constante; daca array-ul este format doar dintr-un rand sau doar dintr-o coloana, argumentul corespunzator e optional (argumentul al treilea nu este necesar, se aplica cel de-al doilea argument); daca array-ul are mai mult de un rand si mai mult de o coloana, e necesara specificare ambelor argumente referitoare la rand si coloana (2 si 3), iar in cazul in care unul din acestea lipseste, functia va returna un array constand in valorile intregului rand sau coloane specificate; numar_rand indica numarul randului din care se va returna valoarea solicitata prin al treilea argument daca acest argument lipseste, este obligatorie prezenta celui de-al treilea; numar_coloana indica numarul coloanei din care se va returna valoarea solicitata din randul indicat prin al doilea argument daca acest argument lipseste, este obligatorie prezenta celui de-al doilea; Daca sunt furnizate ambele argumente referitoare la rand si coloana si acestea sunt >0, functia va returna elementul din array aflat la intersectia randului si coloanei specificate. Daca unul dintre argumentele referitoare la rand si coloana are valoarea 0, functia va returna coloana, respectiv randul mentionat sub forma unui array (formula trebuie confirmata cu Ctrl+Shift+Enter). Ambele argumente referitoare la rand si coloana trebuie sa indice o pozitie existenta in array, altfel functia va returna eroarea #REF! Din cele scrise mai sus despre MATCH() si INDEX() putem acum deduce cu usurinta cum pot fi folosite acestea in tandem: =INDEX(array1,MATCH(valoare, array2, [modul_de_comparatie]), MATCH(valoare, array2, [modul_de_comparatie])) Este de rmarcat ca functia MATCH() poate fi aplicata asupra unor alte array-uri decat cel folosit ca argument al functiei INDEX() cu grija de a exista corespondenta necesara intre valorile furnizate de MATCH() pentru randul si coloana cautate cu INDEX(). In exemplul urmator vom vedea exact aceasta situatie si il vom vedea si pe OFFSET() in actiune, intr-un mod colateral, dar care merita evidentiat. Pornim de la un exemplu redus de baza de date inscrisa in foaia de calcul denumita Monitoare:

In tabelul de mai sus pe coloana A avem denumirile unor modele de monitoare, iar pe cooanele B:F cateva caracteristici. Oricine a lucrat cu un asemenea tip de tabel stie din experienta ca atat numarul de randuri cat si chiar numarul de coloane pot varia in timp (mai adaugam un model, sesizam ca ni se cer informatii si despre alte caracteristici, asa ca mai adaugam coloanele necesare si completam informatiile pentru toate modelele, stergem intreaga inregistrare pentru ca modelul nu se mai comercializeaza etc.). O asemena baza de date bine intretinuta ne va permite sa extragem informatiile inregistrate aici cu mare usurinta daca stim cum sa stapanim dimensiunile si structura ei (numarul de randuri si numarul de coloane pe care avem date) solutia: declararea de nume si asocierea acestora cu range-uri dinamice. In tabelul de mai sus pe coloana A vom avea inscrise denumirile de modele indiferent

daca avem date despre un model sau altul, coloana A este definitorie pentru numarul de randuri al bazei noastre de date, nu numai pentru ca denumirea modelului e importanta, dar aceste denumiri vor fi unice. In exemplul de folosire a informatiilor din baza de date vom folosi lista de modele pentru a extrage informatia necesara din baza de date si de aceea pentru realizarea acestei liste (vom vedea cum, la momentul potrivit) vom defini numele modele. Desi acest articol nu se refera in mod special la modul de definire a numelor in Excel, o scurta introducere si in acest subiect cred ca e binevenita. Putem defini un nume in doua feluri: 1. selectand o celula sau un grup de celule si tastand numele respectiv (fara ghilimele) in campul Name Box (in stanga barei de formule) si confirmand denumirea cu Enter (ca in exemplul anterior cu extrasul de armaturi); 2. folosind Name Manager (Formulas -> Name manager in Excel 2007, Insert -> Name -> Define in Excel 2003, sau mai simplu Ctrl+F3 in oricare dintre versiuni). A doua optiune ne permite definirea unui nume si folosirea unei formule pentru definirea range-ului asociat numelui respectiv. In fereastra de dialog care apare, tastam numele pe care dorim sa-l definim, iar la Refers To: in loc sa introducem o referinta la un range, folosim OFFSET() Definitia pentru numele modele va folosi urmatoarea formula pe care terbuie s-o scriem in caseta Refers To: =OFFSET(Monitoare!$A$2,0,0,COUNTA(Monitoare!$A$2:$A$1000)) Formula de mai sus returneaza un range care incepe in celula Monitoare!$A$2, si are un numar deCOUNTA(Monitoare!$A$2:$A$1000) randuri. Functia COUNTA() folosita pentru stabilirea numarului de randuri returneaza numarul de celule care nu sunt goale dintr-un range (in cazul asta range-ul Monitoare!$A$2:$A$1000, apreciind ca nu vom avea mai mult de 999 de modele inregistrate, dar range-ul folosit poate merge pana la numarul maxim de randuri (65536 pentru Excel 2003, sau intreaga coloana 220 pentru Excel 2007 in Excel 2007 se accepta si referinta $A:$A pentru intreaga coloana). Procedand in acest fel ne asiguram ca daca mai adaugam un model in baza de date, range-ul asociat acestui nume se va actualiza automat ca dimensiune, de aceea si denumirea de range dinamic. La fel vom proceda pentru definirea numelui caracteristici pentru denumirile coloanelor folosite la inregistrarea caracteristicilor fiecarui model inscris in baza de date. Formula folosita va fi: =OFFSET(Monitoare!$B$1,0,0,1,COUNTA(Monitoare!$B$1:$Z$1)) presupunand ca nu vom folosi coloanele mai spre dreapta de coloana Z, dar putem folosi un range mai mare ca argument al functiei COUNTA(), daca vom considera ca e cazul. Avem pana acum doua nume definite: modele pentru coloana A si caracteristici pentru randul 1. Ne mai ramane sa definim un nume si pentru datele propriu-zise. Vom defini data (nu date pentru ca s-ar confunda cu functia cu acelasi nume si Excel-ul nu ne va permite folosirea acestei denumiri) folosind urmatoarea formula: =OFFSET(Monitoare!$B$2,0,0,COUNTA(Monitoare!$A$2:$A$1000),COUNTA(Monito

are!$B$1:$Z$1)) Remarcati folosirea acelorasi formule COUNTA() pentru definirea numarului de randuri si coloane ca si cele folosite la definirea numelor anterioare. Dupa definirea acestor nume putem edita baza noastra de date in aproape toate modurile cu putinta (mai putin recomandabil ar fi sa stergem toate randurile si/sau toate coloanele, dar in rest): adaugand randuri, adaugand coloane (scriind si ceva date in ele, mai ales pe coloana A si randul 1, evident) sau stergand randuri sau coloane. Bineinteles ca editarea bazei de date va trebui sa fie facuta in conjunctie cu editarea proceurilor prin care extragem informatia din baza de date. Una dintre posibilele proceduri e exemplificata mai jos:

Pe coloana A, incepand cu A2 si terminand unde consideram de cuviinta tot pe coloana A s-a folosit procedura alegerii din lista a modelului folosind Data Validation (Data -> Data Validation). Mai intai se selacteaza celulele unde dorim sa aplicam data validation, se selecteaza din menu Data Validation (Data -> Data Validation) si in dialogul care apare se selecteaza la Allow: tipul List, iar la Source: se scrie =modele (fara ghilimele, evident), se confirma cu OK si am instituit in felul acesta pentru celulele selectate data validation de tip list folosind ca sursa range-ul atasat numelui modele. Numele definite prin procedurile explicate mai sus sunt nume accesibile la nivelul intregului fisier pot fi referite in orice formula din orice foaie de lucru aceasta caracteristica ne-a permis sa folosim numele modele si in formula folosita pentru definirea data validation, chiar daca range-ul asociat acestui nume se afla in alta foaie de lucru decat cea in care sunt celulele unde dorim sa aplicam data validation. Asa arata lista de modele pe care am definit-o folosind procedurile descrise mai sus si din care putem selecta (in cele n randuri pentru care am aplicat acest tip de data validation) modelul ale carui caracteristici dorim sa le vizualizam in coloanele B:F:

Dupa selectia din lista caracteristicile modelului selectat apar in coloanele B:F unde pe fiecare rand pe care am instituit data validation exista formule ca cele specificate in imaginea de mai jos:

In formulele folosite functia IF() n-are decat rolul de a testa daca exista o selectie din lista in celula de pe coloana A a randului curent. Functia LEN() din conditia functiei IF() returneaza numarul de caractere al textului existent in celula referita si e preferabila utilizarea ei pentru testarea existentei sau nu a unei valori afisate intr-o anumita celula atunci cand nu stim sigur daca celula respectiva contine o formula sau nu. In situatia in care celula testata contine o formula care returneaza un sir vid (), atat functia ISBLANK() cat si COUNTA() raporteaza celula ca nefiind goala, chiar daca in aparenta aceasta nu contine (nu afiseaza, de fapt) nimic (nu aceasta e si situatia celulelor din baza de date, unde toate datele sunt introduse manual, fara folosirea de formule). Folosind functia LEN(), testam doar existenta sau nu a unui text (numar, valoare logica etc.) afisat in celula. Dupa cum se vede, in cazul in care in celula din coloana A a randului curent exista o valoare selectata, celulele din coloanele B:F afiseaza caracteristicile modelului selectat folosind tandemul INDEX-MATCH. Deoarece definirea corpului de date (data) a fost facuta in conjunctie cu definirea coloanei modele si a randului caracteristici, functiile MATCH() folosite pentru returnarea numarului randului si numarului coloanei de la intersectia carora functia INDEX() returneaza valoarea cautata, opereaza asupra numelor modele si caracteristici, iar functia INDEX() are ca prim argument numele data. In principiu cam astea ar fi principalele functii de cautare pe care ni le pune la dispozitie

Excel-ul. Exista insa o multime de alte posibilitati ca prin combinarea altor functii sa cream formule care folosesc tot la cautare. Ducand mai departe exemplul de mai sus, in cele ce urmeaza vom exemplifica folosirea (si a) unor alte functii pentru a crea o lista de modele corespunzatoare unei anumite valori pentru caracteristica Diagonala. Vom folosi pentru alegerea valorii diagonalei acceasi procedura de selectare din lista (data validation). Pentru aceasta, intr-o alta foaie de calcul vom introduce pe o coloana (nu conteaza care) incepand cu randul 1 (sau altul) valorile de la 12 la 30 reprezentand posibilele valori pentru caracteristica Diagonala. Selectam range-ul astfel completat si in Name Box tastam diag (fara ghilimele) si confirmam cu Enter. Nu avem nevoie pentru aceasta exemplificare de un nume cu un range dinamic atasat. Avem nevoie in schimb de un nume cu un range dinamic atasat pentru valorile diagonalelor din baza de date, din motivele legate de intretinerea acesteia, enuntate anterior. Folosim aceeasi procedura descrisa pentru crearea numelui modele, dar evident ca vom inlocui in formula coloana A cu coloana B, iar numele folosit va fi diagonala. Spatiul pregatit pentru realizarea procedurii de creare a listei de monitoare existente in baza de date si avand o anume diagonala va arata cam asa:

In celula B35 va aparea lista creata cu data validation din care vom selecta diagonala dorita, iar in range-ul D35:D45 va aparea lista modelelor de monitoare inregistrate in baza noastra de date care corespund acestei cerinte. Imaginile urmatoare ilustreaza comportamentul acestei proceduri pentru diverse valori ale diagonalei selectate.

Formula folosita pentru selectarea tipurilor de modele care indeplinesc cerinta specificata este cea inscrisa in chenar, la baza imaginii , copiata in jos in range-ul D35:D45 si arata cam asa: {=IF(LEN($B$35)=0,",IF(SUMPRODUCT( (diagonala=$B$35))=0,",IF(ROW($A35)-34> SUMPRODUCT( (diagonala=$B$35)),",INDEX(modele,SMALL(IF(((diagonala=$B$35))=0,

COUNTA(modele)+ROW(diagonala),ROW(diagonala)-1),ROW($A35)-34)))))} Formula folosita e de un tip special, denumit formula CSE, sau array formula si se confirma cu Ctrl+Shift+Enter, nu doar cu Enter (de unde si denumirea de formula CSE). Astfel de formule sunt folosite pentru prelucrarea in memorie a array-urilor folosite ca argumente in functiile componente ale formulei. Acoladele care incadreaza formula nu se tasteaza, ele apar automat la confirmarea formulei cuCtrl+Shift+Enter si dispar, tot automat, atunci cand editam formula, pentru reintroducerea ei ca formula CSE dupa editare fiind necesara confirmarea tot cu Ctrl+Shift+Enter. Nu voi insista aici asupra formulelor CSE, ci voi incerca doar o analiza succinta a modului ei de functionare. Ca si in exemplul anterior primul IF() are rolul de a verifica existenta unei valori in celula in care folosim data validation (B35). Functia folosita drept conditie in cazul celui de-al doilea IF() este una pe care n-am discutato pana acum, si nici n-o sa intru in detalii asupra ei in acest moment, fiind suficient sa mentionez ca: SUMPRODUCT((diagonala=$B$35)) Reutrneaza numarul de inregistrari din baza de date care indeplinesc cerinta de valoare a diagonalei specificata in celula B35. Al treilea IF() testeaza daca numarul randului pe care se afla inscrisa formula 34 (observati ca in cazul randului 35, 35-34=1, pe randul 36 aceasta valoare va deveni 2 s.a.m.d.) este mai mare decat numarul de inregistrari care indeplinesc conditia, raportat de SUMPRODUCT((diagonala=$B$35)). In cazul in care valoarea ROW($A35)-34 depaseste valoarea SUMPRODUCT((diagonala=$B$35)) intreaga formula va returna un sir vid (). Partea cea mai interesanta a formulei este insa ultima: INDEX(modele,SMALL(IF(((diagonala=$B$35))=0,COUNTA(modele)+ ROW(diagonala),ROW(diagonala)-1),ROW($A35)-34)) In cazul in care conditia explicata mai sus este falsa, se vor returna din range-ul asociat numelui modele acele valori care corespund cu valoarea calculata de: SMALL(IF(((diagonala=$B$35))=0,COUNTA(modele)+ ROW(diagonala),ROW(diagonala)-1),ROW($A35)-34) Functia SMALL() returneaza cea mai mica k valoare dintr-un range, unde k=1 e valoarea cea mai mica, iar k<=numarul_de_elemente_in_range ar fi valoarea cea mai mare. Analizand portiunea de formula evidentiata mai sus putem observa ca valoarea lui k este calculata de formula ROW($A35)-34 care pentru randul 35 returneaza valoarea 1, iar prin copiere, pe celelalte randuri va returna valorile 2, 3, 4, Mai ramane sa ne lamurim cum este creat range-ul (de fapt array-ul) din care se returneaza SMALL(,k). Pentru ca folosim aceasta constructie cu SMALL() pentru a returna numarul randului din modele, SMALL va trebui sa returneze acest numar. Portiunea IF(( (diagonala=$B$35))=0,COUNTA(modele)+ROW(diagonala),ROW(diagonala)1) este cea care determina folosirea acestei formula ca formula CSE pentru ca in corpul acestei functii IF() se creaza array-ul care este transmis ca parametru functiei SMALL().

Acest array este un array de numere de randuri care indeplinesc conditia de valoare a diagonalei. Functia folosita pe post de conditie a functiei IF in discutie, adica: (( (diagonala=$B$35))=0 testeaza daca valoarea expresiei (diagonala=$B$35) este egala cu 0 si daca da, functia IF returneza expresia COUNTA(modele)+ROW(diagonala) care este un numar mai mare decat numarul de randuri existente in baza de date +1, iar daca expresia este diferita de 0, functia IF returneaza expresia ROW(diagonala)-1) care este de fapt numarul randului inregistrarii din baza de date care satisface conditia legata de valoarea diagonalei. Pentru ca toata aceasta expresie este aplicata asupra unui intreg range (cel atasat numelui diagonala) si ca intreaga formula e introdusa ca formula CSE, aceasta portiune de formula va returna un array in care vor exista numerele randurilor din modele care satisfac conditia impusa si numere de randuri care depasesc numarul maxim de randuri din baza de date, dar care nu vor intra in discutie pentru ca functia SMALL() va returna doar numarul randurilor al caror index in acest array este mai mic sau egal cu cel numarul de inregistrari care satisfac conditia impusa. In formula analizata mai sus am folosit functii care n-au facut obiectul acestui articol ca descriere detaliata si explicare a modului lor de functionare si utilizare, dar depsre versatilitatea lui SUMPRODUCT() sau magia formulelor CSE vom mai discuta, poate, cu alta ocazie. Pana atunci, sa cautati bine (!) Autor: Sorin Georgescu (moderator forum DrExcel; expert VBA)

S-ar putea să vă placă și