Sunteți pe pagina 1din 19

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 ca
VLOOKUP() 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 de-al 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
de COUNTA(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(Monitoar
e!$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 cu Ctrl+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 discutat-o
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 (!)

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