Sunteți pe pagina 1din 96

Ingineria Programrii i

Limbaje de Asamblare
Note de curs

Marian Drdal
Cristian Ioni

1. Aspecte generale referitoare la framework-uri i


mediul .NET
1.1 Framework-uri pentru dezvoltarea de aplicaii
software
Un framework software este o platform software universal i
reutilizabil folosit la dezvoltarea aplicaiilor, produselor i soluiilor
software. Scopul unui framework este de a mbuntii eficiena procesului
de dezvoltare de noi aplicaii software. Framework-ul poate imbuntii
productivitatea procesului de dezvoltare de software i a: calitii, fiabilitii
i robusteii noului software. Productivitatea dezvoltatorului este
mbuntit prin faptul c acesta se concentreaz pe cerinele specifice ale
aplicaiei pe care o construiete n loc s consume timpul pentru a programa
infrastructura aplicaiei.
Conceptul de framework este mai extins dect cel de bibliotec. In
cazul utilizrii unei biblioteci, obiectele i metodele implementate sunt
instaniate i apelate n aplicaia dezvoltatorului. Pentru acest lucru trebuie s
se cunoasc care obiecte i metode trebuie utilizate i apelate astfel nct
aplicaia s-i ating scopul. Pe de alt parte, la utilizarea unui framework
dezvoltatorul definete obiecte i implementeaz metode care
particularizeaz aplicaia sa i acestea sunt instaniate i apelate prin
intermediul framework-ului. In acest caz, framework-ul definete un flux de
control pentru aplicaie. Un mod obinuit de a particulariza un framework
const n a suprascrie entitile implementate de ctre acesta. Pentru
alinierea la framework, programatorul poate s defineasc clase derivate din
clasele lui, s implementeze interfee definite de framework i s defineasc
metode virtuale i clase abstracte din framework.
In funcie de destinaie, framework-urile se pot clasifica n:
framework-uri destinate dezvoltrii aplicaiilor software cu caracter general,
n diferite tehnologii, respectiv framework-uri pentru dezvoltarea de aplicaii
2

software specializate. In general, indiferent de tipul de framework folosit,


dezvoltarea aplicaiilor software necesit utilizarea unui mediu de dezvoltare
care s fie capabil s coopereze cu framework-ul dorit.
Reprezentativ pentru categoria framework-urilor cu caracter general
este framework-ul construit de Microsoft, care poart numele de .NET
Framework. Astfel, dac se dorete construirea unei aplicaii de tip Windows
Forms, programatorul i poate defini propria interfa prin intermediul unei
clase (Class_Forma) care va fi derivat din clasa Form a framework-ului
.NET, dup cum urmeaz:
class Class_Forma : Form
{
}

Prin motenire se preiau proprieti de baz pentru fereastr, astfel nct


aceasta va avea iconi, butoane pentru: minimizare, maximizare i
nchidere, dup cum se poate observa n figura 1.4, precum i funcionaliti
implicite aferente butoanelor generate.

Figura 1.4 Forma generat implicit

Pentru a putea executa aplicaia a fost definit i clasa Principala n care s-a
definit metoda static Main, necesar pentru startarea execuiei aplicaiei.
Practic codul din Main ruleaz o instan a clasei Class_Forma definit
anterior.
class Principala
{
static void Main()
{
Application.Run(new Class_Forma());

}
}

Pe lng framework-urile cu caracter general, exist i framework-uri


care dau posibilitatea programatorului de a dezvolta aplicaii software
specializate. Astfel, produsele software specializate pe anumite domenii de
prelucrare sunt construite pe baza acestor framework-uri. Se vor prezenta
dou astfel de framework-uri pentru a putea dezvolta aplicaii bazate pe
Office i GIS. Dezvoltatorii au la dispoziie mai multe variante de elaborare a
modulelor si anume: s construiasc aplicaii personalizate ntr-un mediu de
dezvoltare care s foloseasc framework-ul, s programeze diferite module
personalizate pe care s le integreze n aplicaiile de baz (de exemplu MS
Word sau Excel) folosind limbajul VBA (Visual Basic for Application) sau
s foloseasc medii de dezvoltare pentru a construi extensii care s fie
integrate ulterior n aplicaiile de baz i s conlucreze i cu celelalte
elemente software ale produsului.
Exist totodat i framework-uri care nu stau la baza unor produse
software specializate ci au fost fcute pentru a dezvolta diferite tipuri de
aplicaii. De exemplu, DirectX are pe lng versiunea run-time i versiunea
pentru dezvoltare DirectX SDK. In general, framework-urile pentru
dezvoltare de aplicaii au n denumire SDK, acronimul de la Software
Development Kit.
Framework-urile permit proiectanilor i dezvoltatorilor de soft s
reutilizeze codul, s abstractizeze i s proiecteze noi funcionaliti, n
general sunt construite pentru utilizarea lor pe scar larg n dezvoltarea de
aplicaii specializate.

1.2 Mediul .NET caracterizare general


Microsoft a lansat prima versiune a lui .NET Framework n anul
2000. Principalele proprieti ale mediului de programare .NET sunt:
- Mediu independent pentru execuia programelor, n sensul c toate
limbajele se bazeaz pe acelai nucleu (de exemplu, nu exist nici o
4

diferen n rularea unei aplicaii indiferent dac aceasta a fost scris


n VB.NET sau C#);
Mediu orientat obiect n form pur, n sensul c implementeaz
complet proprietile programrii orientate obiect i arhitectura
framework-ului este orientat obiect;
Integrare complet ntre aplicaii, asigurat prin faptul c .NET
Framework poate fi utilizat independent n raport de limbajele de
programare;
Interoperabilitate cu alte componente software existente, ceea ce
permite aplicaiilor .NET s reutilizeze DLL-uri existente,
componente COM, ActiveX etc;
Model simplificat de livrare a aplicaiilor, astfel nct nu mai este
necesar nregistrarea componentelor sau a aplicaiilor n regitrii din
Windows ci dup compilarea componentelor acestea se copiaz n
directorul dorit i apoi se refer pentru a fi utilizate n alte aplicaii;
Model general de securitate, coninut n .NET Framework pentru a
seta caracteristici de securitate aplicaiilor fr a rescrie aplicaiile. In
timpul execuiei unei aplicaii framework-ul verific setrile astfel
nct sa nu permit accesul neautorizat, procesarea unor operaii
interzise etc.

Din punct de vedere istoric, .NET Framework a cunoscut o evoluie


continu, de la lansarea lui, fiecare versiune a adugat noi caracteristici sau
capabiliti, principalele fiind ilustrate n figura 1.2. Din punct de vedere
arhitectural, .NET Framework conine urmtoarele componente:
- Common Language Run-time (CLR), care furnizeaz un nivel de
abstractizare peste sistemul de operare. Partea cea mai important a
CLR se afl n fiierul mscore.dll i furnizeaz urmtoarele
caracteristici:
o Identificarea assembly-urilor necesare;
o ncrcarea lor;

o Identificarea tipurilor corespunztoare folosind metadatele


assembly-ului;
o Translatarea codului MSIL (Microsoft Intermediate
Language).

Figura 1.2 Evoluia .NET Framework[1]

Biblioteca de clase de baz care se constituie din cod preconstruit


pentru sarcini des utilizate n programarea de nivel sczut.
Principalul rol al acestei componente este de a furniza servicii de
infrastructur dezvoltatorilor. Aceste servicii se constituie ca un strat
peste interfaa de programare WIN API. Directorul bibliotecii de
clase conine o mulime de assembly-uri;
Framework-uri i tehnologii de dezvoltare, ce reprezint soluii
reutilizabile i care se pot personaliza pentru o larg varietate de
sarcini de programare.

2. Utilizarea interfeelor i a evenimentelor n


dezvoltarea de aplicaii
2.1 Interfee
O interfa se definete similar unei clase avnd urmtoarele
particulariti:
- n loc de folosirea cuvntului cheie class se folosete interface;
- nu poate conine atribute;
- proprietile i metodele au doar semnturile nu i implementarea.
Interfeele se folosesc pentru a implementa aceleai operaii dar ntr-un alt
context de lucru. Altfel spus, o clas care implementeaz o interfa trebuie
s implementeze metodele i proprietile interfeei pentru a se alinia la un
mod de utilizare. In acest sens, un exemplu sugestiv se refer la faptul c, n
vederea implementrii unei colecii se dorete ca elementele ei s fie iterate
folosind instruciunea specific foreach.
Se propune o implementare minimal a structurii de dat list simplu
nlnuit ca fiind o colecie de noduri, nodurile fiind implementate tot
printr-o clas de sine stttoare inclus n clasa lista.
public class Lista
{ // clasa nod
public class nod
{
object inf;
public nod next;
public nod(object k, nod urm) { inf = k; next = urm; }
public object informatia
{
get { return inf; }
set { inf = value; }
}
}
nod cap;
protected uint nrn;
public Lista() { cap=null; nrn=0; }

public void Adaugare(object k)


{
nod tmp = new nod(k, cap);
nrn++;
cap=tmp;
}
}

Pentru colecia definit prin intermediul clasei Lista, instruciunea


foreach

nu funcioneaz. Acest lucru devine posibil fcnd urmtoarele

completri:

clasa Lista va moteni interfaa IEnumerable;

ca o consecin a punctului anterior este necesar s se defineasc


metoda GetEnumerator(), n clasa Lista, dup cum urmeaz:

public IEnumerator GetEnumerator()


{ return nrn==0 ? null : new ListEnum(cap); }

In cazul n care lista e vid, metoda returneaz null, altfel metoda ntoarce
un obiect care implementeaz interfaa IEnumerator pentru o list. Obiectul
este de clas ListEnum i refer elementele listei prin intermediul capului
listei (cap);

astfel se definete clasa ListEnum care implementeaz interfaa


IEnumerator:

class ListEnum : IEnumerator


{
Lista.nod aux, init;
bool vb;
public ListEnum(Lista.nod ccp) { aux = init = ccp; vb = true; }
public object Current { get { return aux.informatia; } }
public bool MoveNext()
{
if(aux==init && vb ) { vb=false; return true;}
if (aux.next!=null)
{
aux=aux.next;
return true;
}
else return false;
}
public void Reset() { aux=init; vb=true; }
}

Din codul surs se observ urmtoarele:


-

constructorul iniializeaz membrii de tip nod cu capul listei i variabila


boolean vb cu true;

metoda Reset() repune referina auxiliar aux pe nceputul listei i vb


pe true;

proprietatea Current este de tip read-only i furnizeaz informaia util


a nodului curent (cel referit prin aux);

metoda MoveNext() are ca scop referirea urmtorului nod valid al listei,


caz n care returneaz true; dac nu mai exist noduri n list returneaz
false.

Instruciunea foreach ncepe prin a apela metoda Reset(), dup


care apeleaz metoda MoveNext() cu scopul de a referi primul element al
coleciei, adic primul nod valid al listei; scopul variabilei vb este de a face
distincie ntre primul apel al metodei MoveNext() i celelalte, care vor
avansa referina aux atta timp ct mai exist un nod valid n list. Utilizarea
instruciunii foreach mpreun cu colecia Lista se poate face acum sub
forma:
Lista l = new Lista();
l.Adaugare(100); l.Adaugare(200); l.Adaugare(150);
try
{
foreach (int k in l) { Console.WriteLine(k); }
}
catch
{
Console.WriteLine("Lista vida!!!");
}

S-a inclus instruciunea foreach ntr-un bloc try cu scopul de a lansa o


excepie n cazul n care lista este vid.
O alt modalitate de a utiliza interfeele o constituie partajarea
accesului la elementele unei clase complexe n concordan cu o logic a
utilizrii elementelor clasei. Astfel, spre exemplificare, se va implementa
clasa cont bancar care conine date personale cum ar fi: nume, prenume, cod
numeric personal, domiciliu etc ct i date financiare, ca de exemplu: iban,
9

sold etc. Evident, pentru cele dou categorii de date stocate n clasa cont se
vor defini i implementa operaii specifice: determinarea vrstei persoanei,
operaia de depunere respectiv retragere n / din cont etc. Interfeele vor fi
astfel definite i apoi implementate n clasa cont astfel nct numai prin
intermediul acestora se vor utiliza obiectele. Pentru rezolvarea problemei se
va defini clasa operaie bancar ce va conine data la care se efectueaz
operaia, tipul operaiei (depunere / extragere) i suma:
class operatie_bancara
{
DateTime dop;
public int suma;
public char tip;
public operatie_bancara(DateTime fdop, int fs, char ft)
{
dop = new DateTime(fdop.Year, fdop.Month, fdop.Day);
suma = fs; tip = ft;
}
}

Interfeele construite sunt:


- pentru date personale:
interface IDate_Pers
{
string Nume // proprietatea pentru numele persoanei
{
get;
set;
}
// seteaza data nasterii
void set_dn(int fy, int fm, int fz);
// determina varsta
int get_varsta();
}

pentru date financiare:


interface IDate_Fin
{
string Iban // proprietatea pentru cont
{
get;
set;
}
void Depune(DateTime dt, int s); //depunere
void Extrage(DateTime dt, int s);//extragere
int get_sold(); // determina sold
}

10

Clasa Cont motenete i implementeaz cele dou interfee i are forma:


class Cont : IDate_Pers, IDate_Fin
{
int si;
string np, iban;
DateTime dn = new DateTime();
List<operatie_bancara> lopb = new List<operatie_bancara>();
public Cont(int fsi) { si = fsi; }
//implementarea interfetei Date_Pers
string IDate_Pers.Nume
{
get { return np; }
set { np = value; }
}
void IDate_Pers.set_dn(int fy, int fm, int fz)
{
dn = DateTime.Parse(fy.ToString()+"-"+
fm.ToString()+"-"+fz.ToString());
}
int IDate_Pers.get_varsta()
{
return DateTime.Now.Year - dn.Year;
}
//implementarea interfetei Date_Fin
string IDate_Fin.Iban
{
get { return iban; }
set { iban = value; }
}
void IDate_Fin.Depune(DateTime dt, int s)
{
lopb.Add(new operatie_bancara(dt, s, 'd'));
}
void IDate_Fin.Extrage(DateTime dt, int s)
{
lopb.Add(new operatie_bancara(dt, s, 'e'));
}
int IDate_Fin.get_sold()
{
int sd = 0, se = 0;
foreach (operatie_bancara opi in lopb)
if(opi.tip == 'd') sd += opi.suma; else se += opi.suma;

11

return si+sd-se;
}
}

Se observ c la implementarea elementelor de interfa, n clasa Cont, s-a


folosit o definire explicit a interfeei prin precedarea numelui metodei sau
proprietii de numele interfeei acest lucru permite ca elementele din
interfa s poat fi folosite doar prin intermediul unei interfee i nu direct
prin intermediul obiectului. Tot legat de acest lucru se observ ca
modificatorul public nu mai este indicat la implementarea metodelor /
proprietilor deoarece, prin definirea explicit a interfeei, caracterul public
este asociat automat datorit faptului c elementele unei interfee au
ntotdeauna caracter public.

2.2 Lucrul cu evenimente


Pentru a nelege mecanismul evenimentelor se urmrete ca el s se
implementeze folosind interfee ce definesc un pattern ce trebuie
implementat de clasele care urmeaz s comunice n acest fel. Din punct de
vedere al logicii de implementare se pot stabili dou categorii de clase: cele
care genereaz obiecte observabile ct i cele care genereaz obiecte ce
observ (observatori). Pentru o legtur cu lumea real v putei imagina
relaia ntre prini i copilul lor n sesul c prinii i observ copilul, deci
joac rolul de observatori, n timp ce copilul este entitatea observabil.
Obiectul observabil notific observatorii cnd acesta i schimb starea. De
exemplu, cnd copilul nu mai are bani, acesta i ntiineaz prinii care,
apoi realizeaz o aciune (de exemplu, mama i d bani copilului iar tata l
atenioneaz c a cheltuit prea mult). Un alt element util de observat n
implementare const n faptul c oobiectele observabile se cupleaz la
observatori i atunci conlucreaz iar cnd se realizeaz operaia de decuplare
atunci ele nu mai conlucreaz.

12

O clas care genereaz obiecte ce observ (observatori) trebuie s


implementeze o interfa care conine semntura metodei (Notificare) care
implementeaz funcionalitatea ce se execut atunci cnd observatorul este
notificat. Evident, fiecare clas care genereaz observatori va implementa n
mod propriu notificarea.
interface IObservator
{
void Notificare();
}

Clasa care genereaz obiecte observabile trebuie s implementeze o interfa


specific IObservabil care definte semnturile a dou metode: una care
cupleaz observatori i alta care-i decupleaz:
interface IObservabil
{
void Cupleaza(IObservator o);
void Decupleaza(IObservator o);
}

Pentru a defini mecanismul de organizare a coleciei de observatori (lobs),


cuplarea i decuplarea s-a construit clasa Observabil_Impl care
implementeaz interfaa IObservabil.
class Observabil_Impl : IObservabil
{
protected List<IObservator> lobs = new List<IObservator>();
public void Cupleaza(IObservator o)
{
lobs.Add(o);
}
public void Decupleaza(IObservator o)
{
lobs.Remove(o);
}
}

Codul descris pn n acest moment este de maxim generalitate i poate fi


folosit de orice clase care genereaz obiecte care conlucreaz n sensul c
unele obiecte notific alte obiecte care reacioneaz la notificrile primite.

13

Pentru exemplificarea ct mai simpl a mecanismului s-a construit clasa


observabil numit Element care conine un atribut de tip ntreg (el) iar la
schimbarea valorii lui obiectul va notifica alte obiecte (observatorii).
class Element : Observabil_Impl
{
int el;
public int Valoare_el
{
get { return el; }
set
{
if (el != value)
{
el = value;
foreach (IObservator o in lobs) o.Notificare();
}
}
}
}

Se poate observa c la schimbarea strii elementului, el notific toi


observatorii iar prin apelul metodei Notificare a fiecrui observator,
observatorul va declana aciunea ca rspuns al notificrii.
Se propune clasa Cons_obs care va genera un observator ce va afia la
consol mesajul Element modificat!! atunci cnd obiectul observabil i
schimb starea:
class Cons_obs : IObservator
{
public void Notificare()
{
Console.WriteLine("Element modificat!!");
}
}

Pentru a exemplifica funcionalitatea se construiete obiectul oel de tip


Element, se construiete obiectul cu rol de observator (cobs1), se cupleaz
observatorul la obiectul observabil i se schimb starea elementului fapt care
genereaz apelul metodei Notificare din observator care determin afiarea
mesajului corespunztor, dup care se vizualizeaz noua valoare a
elementului.
Element oel = new Element();

14

Cons_obs cobs1 = new Cons_obs();


oel.Cupleaza(cobs1);
oel.Valoare_el = 10;
Console.WriteLine("elment = {0}", oel.Valoare_el);

V propunem s testai ntreaga funcionalitate i anume s realizai


decuplarea observatorului dup care s schimbai starea elementului i vei
observa c mesajul de notificare nu se va mai afia pentru c obiectele nu
mai conlucreaz dup decuplare.
Pentru a complica exemplul se mai adaug un alt observator de data aceasta
o clas derivat din clasa form (Form) care va implementa interfaa
IObservator. Metoda de notificare va afia mesajul Modificat pe cte o linie
nou ntr-ul control (mes) de tip Label de pe form. Pe de alt parte, din
cadrul formei se d posibilitatea modificrii valorii elementului prin
intermediul controlului (tval) de tip TextBox la apsarea pe butonul Set_val
fapt care va determina notificarea ambilor observatori ceea ce va duce la
apariia unui mesaj la consol ct i n form. Pentru a putea modifica
elementul din form, la constructorul formei se trimite ca parametru o
referin la obiectul de tip Element care se reine ntr-un atribut al formei i
prin care se va permite modificarea strii elementului.
public partial class Form1 : Form, IObservator
{
Element rel = null;
public Form1(object fel)
{
InitializeComponent();
rel = (Element)fel;
}
public void Notificare()
{
mes.Text += "Modificat"+ Environment.NewLine;
}
private void button1_Click(object sender, EventArgs e)
{
rel.Valoare_el = Convert.ToInt32(tval.Text);
}
}

Testarea funionalitii s-a realizat prin definirea metodei Main n forma:


static void Main(string[] args)

15

{
Element oel = new Element();
Cons_obs cobs1 = new Cons_obs();
Form1 forma = new Form1(oel);
oel.Cupleaza(cobs1);
oel.Cupleaza(forma);
oel.Valoare_el = 10;
forma.ShowDialog();
Console.WriteLine("elment = {0}", oel.Valoare_el);
}

ceea ce determina apariia interfeei aplicaiei ca n figura 2.1. Primul mesaj


a fost afiat ca urmare a schimbrii strii obiectului prin atribuirea realizat
n Main iar cel de-al doilea ca urmare a modificrii strii elementului din
form.

Figura 2.1 Interfaa aplicaiei

O clas poate avea pe lng atribute, proprieti, metode i


evenimente. Prin eveniment se nelege un tip de membru al unei clase care
este activat cnd evenimentul se declaneaz, n timpul execuiei unei
aplicaii. La momentul declanrii evenimentului metoda asociat va fi
apelat.
16

Spre exemplu, dac considerm un obiect de tip Timer, atunci el are


definit evenimentul Tick care se declaneaz periodic, dup ce se scurge o
perioad de timp. Declanarea evenimentului impune apelul unei metode
care implic efectuarea unei procesri ce ine de specificul aplicaiei, deci nu
se poate defini metoda n clasa Timer ns ea poate fi cuplat la eveniment,
din exteriorul clasei Timer. Concret, se va construi o aplicaie care s
asocieze efectul de blinking unui text (textul devine vizibil respectiv
invizibil la un iterval de 300 milisecunde). Pentru acest lucru se va declara
un obiect de tip Timer (t) n clasa Form1: Timer t; Pe evenimentul Load, de
iniializare a formei, se va construi obiectul Timer, se va stabili durata
intervalului de timp, n milisecunde i se va asocia evenimentului Tick
metoda (actiune) care se va apela cnd se va declana evenimentul:
private void Form1_Load(object sender, EventArgs e)
{
t = new Timer();
t.Interval = 300;
t.Tick += new EventHandler(actiune);
}

Se observ c asocierea metodei de utilizator actiune, evenimentului Tick, sa realizat cu operatorul += adic prin adugarea unui nou obiect de tip
EventHandler.
Metoda actiune are un prototip prestabilit n sensul c aceste metode care se
apeleaz la declanarea evenimentelor primesc: obiectul care a interceptat
evenimentul (sender) i un obiect (e) care conine argumentele ce nsoesc
evenimentul. Aceast metod se va defini n aplicaie i va schimba starea de
vizibilitate a textului care este un control de tip Label avnd numele et:
void actiune(object sender, EventArgs e)
{
et.Visible = ! et.Visible;
}

Pornirea timer-ului se va face prin aplelul metodei Start n timp ce, oprirea
lui, se face prin apelul metodei Stop. Ambele metode se apeleaz prin
obiectul t, de tip Timer i operaiile se vor declana prin apsarea a dou
butoane special construite n acest sens.
17

Detaare metodei evenimentului se face prin construcia:


t.Tick -= new EventHandler(actiune);

dup care, la apsarea pe butonul care starteaz timer-ul nu se va mai apela


funcia actiune; deci, efectul de blinking pentru acel text nu se va mai
produce.
La nceputul acestui subcapitol s-a precizat faptul c modalitatea de a
construi obiecte observabile i observatori reprezint, de fapt, modul n care
se implementeaz evenimentele. Folosind evenimente n aplicaii .NET noi
utilizm un mecanism mai evoluat i mai simplu de folosit dar care ascunde
n esen mecanismul descris iniial. Pentru o mai bun nelegere a
problemei se propune ca exemplul din debutul acestui subcapitol sa-i
pstreze funcionalitatea doar c se va utiliza conceptul de eveniment pentru
ca obiectele s conlucreze.
Clasa Element va fi modificat astfel nct ea va conine un delegat care este
similar unui pointer la funcie adic se precizeaz o semntur de funcie
fr a-i preciza implementarea i un eveniment care este similar unei
proprieti asociate unui delegat.
class Element
{
public delegate void DElement();
public event DElement Schimba_el;
int el;
public int Valoare_el
{
get { return el; }
set
{
if (el != value)
{
el = value;
if(Schimba_el!=null) Schimba_el();
}
}
}
}

18

Se observ c la schimbarea strii elementului se apeleaz funcia


Schimba_el care este de tipul precizat prin delegat i care la acest moment
nu are o implementare concret. Testul Schimba_el!=null ne asigur c
delegatul refer o implementare concret altfel s-ar genera eroare la apel.
Observatorii elementului trebuie conform acestui mecanism s
implementeze metoda Schimba_el. Pentru similitudine se pstreaz aceeai
observatori iar metoda Schimba_el va pstra coninutul metodei Notificare
din exemplul iniial.
class Cons_obs
{
public void Schimba_el()
{
Console.WriteLine("Element modificat!!");
}
}
public partial class Form1 : Form
{
Element obel = null;
public Form1(object fel)
{
InitializeComponent();
obel = (Element)fel;
}
public void Schimba_el()
{
mes.Text += "Modificat!!"+Environment.NewLine;
}
private void button1_Click(object sender, EventArgs e)
{
obel.Valoare_el = int.Parse(tb.Text);
}
}

Se observ c practic observatorii au rmas la fel doar ca s-a modificat


numele metodei Notificare care acum a devenit Schimba_el. Dac am fi
denumit evenimentul Notificare observatorii ar fi rmas ca n exemplu
iniial.
O alt modificare important ce tine de lucrul cu evenimente o
constituie cuplarea i decuplarea care acum se realizeaz folosind operatorii
19

+= respectiv -= pe eveniment. Acest lucru este vizibil n metoda Main, care


acum are forma:
static void Main(string[] args)
{
Element el = new Element();
Cons_obs cobs1 = new Cons_obs();
Form1 frm = new Form1(el);
el.Schimba_el += new Element.DElement(cobs1.Schimba_el);
el.Schimba_el += new Element.DElement(frm.Schimba_el);
el.Valoare_el = 10;
frm.ShowDialog();
Console.WriteLine("elment = {0}", el.Valoare_el);
}

Construirea unei clase care s conin un membru de tip eveniment


trebuie proiectat astfel nct acel eveniment s aib condiii bine precizate
pentru a se declana. Cu alte cuvinte, cel ce proiecteaz clasa trebuie s
defineasc evenimentele la care obiectele respective vor raspunde (de
exemplu, clasa Button definete evenimentul Click care se va declana la
momentul cnd se apas pe butonul mouse-ului i cursorul acestuia se afl
pe suprafaa butonului sau clasa Timer definete evenimentul Tick care se
declaneaz periodic la un anumit interval de timp). Pentru exemplificare, se
dorete a se construi o clas care s implementeze animaia prin vizualizarea
succesiv a unor imagini (tehnica filmului). Se urmrete definirea unui
eveniment care s notifice momentul terminrii afirii secvenei de imagini.
Un alt aspect deosebit de important n implementarea lucrului cu
evenimente se refer la mecanismul prin care este posibil asocierea unei
metode care se va apela la momentul declanrii evenimentului. Ideea de
baza const n faptul c cel care proiecteaz clasa definete evenimentul ns
aciunea concret care se va efectua la momentul declansrii evenimentului
se definete de ctre cel ce utilizeaz clasa. Pentru a implementa mecanismul
n clasa care definete evenimentul trebuie declarat un delegat, de exemplu:
20

public delegate void MM_EventHandler(object sender, EventArgs e);

S-a declarat de aceast dat un delegat care se aliniaz la prototipul


delegailor ce se asociaz evenimentelor n ceea ce privete programarea
aplicaiilor Windows. Prototipul este standard n sensul c parametrii au
semnificaiile: obiectul care trimite evenimentul (sender) i obiectul (e) care
ncapsuleaz alte elemente ce sunt trimise odat cu evenimentul. Dup
declararea delegatului se declar evenimentul (Notificare_Animatie) pe baza
lui, astfel:
public event MM_EventHandler Notificare_Animatie;

Clasa care implementeaz animaia (MM_anim), prin tehnica


filmului este:
namespace animatie
{
public delegate void MM_EventHandler(object sender, EventArgs e);
public class MM_anim
{
public event MM_EventHandler Notificare_Animatie;
//folosit pentru a stoca imaginile
ArrayList vimag = new ArrayList();
//reprezinta colectia de imagini
int k; //variabila pentru referirea unei imagini din colectie
PictureBox cadru; // controlul pentru afisarea imaginilor
// timer pentru controlul periodicitatii afisarii imaginilor
Timer t;
// constructor care primeste controlul de afisare si
// intervalul de timp la care vor fi afisate imaginile
public MM_anim(PictureBox fcadru, int intv)
{
cadru = fcadru;
t = new Timer();
t.Interval = intv;
t.Tick += new EventHandler(actiune);
}
//adaugarea unei imagini la colectie;
//s numele fisierului ce contine imaginea
public void Add_imag(string s)
{
vimag.Add(new Bitmap(s));
}
// metoda care declanseaza animatia
public void Play()

21

{
k = 0; // refera prima imagine din colectie
t.Start(); // porneste timer-ul
}
// metoda cuplata la evenimentul Tick al Timer-ului
// ea realizeaza afisarea tuturor imaginilor din colecie
private void actiune(object sender, EventArgs e)
{
cadru.Image = (Bitmap)vimag[k++];
if (k == vimag.Count)
{
// in cazul in care s-a afisat si ultima imagine din colectie
t.Stop(); // se opreste timer-ul
// se invoca evenimentul Notificare_Animatie
if (Notificare_Animatie != null)
Notificare_Animatie(this, new EventArgs());
}
}
}
}

Se observ c, dup ce se afieaz i ultimul cadru, se oprete timer-ul i se


apeleaz metoda Notificare_Animatie care primete obiectul (this) i un
obiect de tip EventArgs pentru a realiza concordana cu prototipul
delegatului; n exemplul prezentat nu se realizeaz i trimiterea de informaii
suplimentare odat cu evenimentul.
Testarea funcionalitii clasei s-a realizat prin construirea unei aplicaii
Windows Forms care utilizeaz un control de tip PictureBox numit canvas i
un buton pentru a derula animaie (Play). In cadrul clasei form s-a declarat
un obiect de tip MM_anim: MM_anim anim; Metoda Form1_Load ce relizeaz
iniializarea formei are urmtoarea definiie:
private void Form1_Load(object sender, EventArgs e)
{
// construirea obiectului anim
anim = new MM_anim(canvas, 300);
int i;
// calea directorului in care se regasesc imaginile
string cale = "d:\\media\\pamintul\\";
// adaugarea imaginilor in colectie fisierele au numele
// c1.jpg, c2.jpg, ... c15.jpg
for (i = 0; i < 15; i++)
anim.Add_imag(cale + "c" + (i + 1).ToString() + ".jpg");
// asocierea metodei actiune evenimentului Notificare_Animatie

22

anim.Notificare_Animatie +=new MM_EventHandler(actiune);


}

Apsarea butonului Play determin declanarea animaiei:


private void button1_Click(object sender, EventArgs e)
{
anim.Play();
}

Metoda actiune care se va apela la declanarea evenimentului de terminare a


derulrii animaiei are ca obiectiv afiarea mesajului:
Animatia s-a terminat!!:
public void actiune(object sender, EventArgs e)
{
MessageBox.Show("Animatia s-a terminat!!", "Notificare",
MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}

Interfaa aplicaiei precum i notificarea terminrii animaiei se ilustreaz n


figura 2.2.

Figura 2.2 Afiarea mesajului de notificare a terminrii animaiei

Dac se dorete a se trimite odat cu mesajul i alte informaii atunci


este neceasar a se deriva o clas din clasa EventArgs care s conin propriile
elemente. In exemplul prezentat ar putea fi util s se transmit odat cu
evenimentul de notificare i informaia suplimentar cu privire la numrul
cadrului. Astfel, n domeniul de nume animatie se va defini clasa
MM_EvArgs dup cum urmeaz:
public class MM_EvArgs : EventArgs
{
int cs; // numarul cadrului

23

// constructorul care primeste numarul cadrului


public MM_EvArgs(int z)
{
cs = z;
}
// proprietatea pentru obtinerea numarului de cadre
public int cadru_stop
{
get { return cs; }
}
}

Modificrile care decurg din folosirea unei clase proprii pentru argumentele
evenimentului sunt:

n clasa MM_anim se modific metoda actiune astfel nct apelul


metodei
Notificare_Animatie
va
avea
forma:
Notificare_Animatie(this, new MM_EvArgs(k));

n clasa Form1 unde se testeaz funcionalitatea clasei MM_anim, se


modific metoda actiune care se apeleaz pe evenimentul
Notificare_Animatie astfel nct mesajul va conine i numrul de
cadre afiate:

public void actiune(object sender, MM_EvArgs e)


{
MessageBox.Show("Animatia s-a terminat ultimul cadru: "
+ e.cadru_stop.ToString()+"!!",
"Notificare", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk);
}

24

3. Prezentarea i utilizarea framework-ului


ArcObjects .NET SDK pentru dezvoltarea
aplicaiilor GIS
3.1 Introducere
ArcObjects reprezint un framework dezvoltat pe tehnologia
componentelor de tip COM (Component Object Model) pe baza cruia este
construit produsul software cunoscut sub denumirea de ArcGIS, dezvoltat
de ESRI (Environmental Systems Research Institute). Cele trei versiuni de
ArcGIS (ArcView, ArcEditor i ArcInfo) partajeaz aceleai aplicaii de
baz: ArcCatalog i ArcMap. Modelul de date al geobazei de date precum i
ArcObjects constituie fundamentele celor dou aplicaii desktop.
Modelul de date georelaional implic stocarea datelor n formate
independente care se bazeaz pe divizarea atributelor n dou entiti i
stocarea lor separat. Astfel, o dat spaial este alctuit din atributul
spaial, care se stocheaz separat de atributele nonspaiale, legtura fiind
fcut prin intermediul unui cmp de identificare (ID), ce are rolul de
combina, n mod coerent, cele dou tipuri de atribute. Legtura dintre entiti
se poate face bidirecional adic fie de la cele spaiale ctre cele nonspaiale
sau invers, ca n figura 3.1.
Stocarea datelor spaiale prin modelul geobaz de date presupune
stocarea att a atributelor spaiale ct i a celor nonspaiale, mpreun, ntr-o
tabel de atribute. Cmpul care conine atributul spaial este de tip vector
(geometric).
Caracteristicile spaiale sunt implementate i procesate prin
intermediul claselor de obiecte cu toate c ele rezid n tabelele unei baze de
date relaionale. Astfel, acestea conin proprieti i metode care opereaz
asupra lor. Pentru a lucra cu framework-ul ArcObjects, n modul
programare, este necesar nelegerea tipurilor de clase care se afl n relaii
de diferite tipuri, n cadrul bibliotecii de clase.
25

Atribute nonspaiale

Structuri de date spaiale

Date nespaiale pentru Regiunea 1

Regiunea 1

Date nespaiale pentru Regiunea 2

Regiunea 2

Date nespaiale pentru Regiunea 3


Regiunea 3

Regiunea 4

Date nespaiale pentru Regiunea 4


Date nespaiale pentru Regiunea 5
Regiunea 5

(a)

Structuri de date spaiale

Atribute nonspaiale
Date nespaiale pentru Regiunea 1

Regiunea 1

Date nespaiale pentru Regiunea 2

Regiunea 2

Date nespaiale pentru Regiunea 3


Regiunea 3

Regiunea 4

Date nespaiale pentru Regiunea 4


Date nespaiale pentru Regiunea 5
Regiunea 5

(b)
Figura 3.1 Tipuri de legturi: nainte (a) i napoi (b)

Un sistem informatic geografic lucreaz cu date spaiale. Aceste date


se folosesc pentru a reprezenta diferite elemente din realitatea geografic,
prin tipuri de vectori (caracteristici spaiale) i prin locaia lor pe suprafaa
pmntului.
26

Principalele date spaiale de tip vectorial sunt:


- Punctul este caracterizat prin locaia sa, nu ocup spaiu i nu are
asociat o arie sau un volum. Intr-o baz de date punctul se
stocheaz printr-o msur direct a lui sau printr-o msur
indirect (transformare). Data de tip raster este un exemplu de
folosire a msurii directe a unui punct i include harta de pixeli
(imaginea bitmap). De exemplu, o imagine preluat din satelit
realizeaz o coresponden direct ntre un pixel de imagine i
suprafaa acoperit de el pe suprafaa terestr.
- Linia se caracterizeaz prin existena a cel puin dou puncte (cel
de nceput i cel de sfrit) urmnd ca punctele intermediare s fie
generate prin ecuaia dreptei. Un obiect spaial este descris, de
obicei, printr-o colecie de segmente ca de exemplu cursul unui
ru sau al unui drum, ce formeaz o polilinie. Din punct de
vedere spaial, liniei i se asociaz doar informaie de lungime nu
i informaie de grosime sau laime.
- Poligonul se caracterizeaz printr-o locaie i un contur. Locaia
este dat de un punct fix pentru a ancora poligonul n spaiu (de
obicei este punctul din centrul regiunii). In spaiul bidimensional,
conturul se vizualizeaz ca o linie iar n spaiul tridimensional ca
o suprafa. Data de tip regiune stocat ntr-o baz de date este o
aproximare geometric a unui obiect spaial (de exemplu,
judeele unei ri, lacurile etc). Acestui tip de vector i se poate
calcula aria i perimetrul. Este singura dat spaial care acoper
suprafee n spaiul geografic studiat.
Pe lng datele spaiale de tip vector, sistemele informatice
geografice mai opereaz i cu date de tip raster. Acestea se descriu printr-un
grid de culoare (hri de bii), acoper o zon bine definit de pe suprafaa
terestr i se folosesc pentru a induce mai mult realism spaiului geografic
studiat. Sub form de raster se reprezint imaginile satelitare, modelul de
altitudine al terenului (DEM), ortofotoplanul, hrile scanate etc.
27

Datele spaiale, fie c sunt vectori fie c sunt de tip raster, trebuie s
fie localizate pe suprafaa pmntului. Localizarea lor se face prin
coordonate geografice (longitudine, latitudine) sau coordonate de tip
proiecie (de exemplu, sistemul de coordonate UTM Universal Transverse
Mercator).
Prin longitudine se nelege unghiul format ntre primul meridian i
poziia pe glob, n timp ce prin latitudine se nelege unghiul format ntre
ecuator i poziia pe glob (figura 3.2).
Un sistem de coordonate de tip proiecie este un sistem de
coordonate n plan, bazat pe o proiecie a hrii. Hrile sunt reprezentate n
plan dar ele reprezint suprafee curbe. Transformarea spaiului
tridimensional ntr-un spaiu bidimensional se numete proiecie (figura 3.3).
De exemplu, sistemul de coordonate UTM se bazeaz pe proiecia Mercator.

Figura 3.2 Latitudine Longitudine [2]

Figura 3.3 Proiecia

28

3.2 Clase, obiecte, relaii i interfee


ArcObjects se compune din clase i obiecte. Clasele descriu n mod
general mulimea de obiecte care au aceleai atribute. Obiectele sunt instane
de clase i se refer la elemente concrete din realitate. Rndurile unei tabele
se identific cu obiectele unei clase de obiecte iar coloanele ei reprezint
atributele clasei.
Exist trei tipuri de clase n framework-ul ArcObjects [1]:
- Coclase care sunt utilizate pentru a genera noi obiecte, de
exemplu, clasa RgbColor este folosit pentru a defini i manipula
culori conform modelului de culoare RGB;
- Clase abstracte care nu pot fi folosite la generarea de noi obiecte
ns au rolul de a construi ierarhii de clase care pornesc de la o
entitate avnd un caracter general. Ele conin atribute i metode
care sunt motenite de toate clasele derivate direct sau indirect
din ea. De exemplu, clasele care implementeaz diferite modele
de culoare sunt derivate dintr-o clasa abstract numit Color;
- Clase, care nu se folosesc direct pentru a genera noi obiecte ci
acestea sunt construite prin intermediul altor obiecte; de exemplu,
pentru a accesa caracteristicile selectate la un moment dat pe
hart se poate construi un obiect de tip MapSelection pornind de
la obiectul hart.
In cadrul unei biblioteci de clase se stabilesc diferite tipuri de relaii
ntre clase. Inelegerea acestor relaii ajut programatorii s neleag
filosofia de dezvoltare a framework-ului i s programeze eficient aplicaiile.
Tipurile principalele de relaii [4] sunt:
- De asociere, care se pune n eviden ntre dou clase. O asociere
poate fi multipl, notat (1..*) sau avnd cel mult o asociere
(1..0). De exemplu, o astfel de relaie exist ntre clasa Color i
ColorRamp n sensul c o ramp de culori este format din mai
multe culori i este ilustrat n figura 3.4;
29

Figura 3.4 Asocierea

De motenire, se definete ntre o superclas i o subclas.


Astfel, o subclas este o specializare a unei superclase i i
motenete atributele i proprietile. De exemplu, clasa Symbol
este o superclas pentru MarkerSymbol, LineSymbol i
FillSymbol i se figureaz dup cum se poate observa n figura
3.5;

Figura 3.5 Motenirea

De compunere, care se descrie prin faptul c un obiect are n


compunere unul sau mai multe obiecte de alt tip. Este oarecum
similar cu asocierea doar c entitile sunt structural diferite. De
exemplu, un document de tip hart este format din mai multe
hri ceea ce se ilustreaz ca n figura 3.6, unde MxDocument este
clasa document iar Map reprezint clasa hart;

Figura 3.6 Compunere

De agregare, care presupune c o clas este definit prin


agregarea elementelor altor clase, care sunt de tipuri diferite i
30

aprioric cunoscute. Spre exemplu, un obiect Cursor se poate crea


pornind de la un obiect de tip Table, adic o tabel i de la un
obiect de tip QueryFilter care impementeaz partea de filtrare a
datelor din tabel pentru a constitui cursorul. In figura 3.7 se
ilustreaz acest tip de relaie;

Figura 3.7 Agregare

De instaniere, care presupune c un obiect se poate crea doar


prin intermediul altui obiect. De exemplu, n figura 3.7, se poate
observa c obiectul Cursor se poate construi prin intermediul
obiectelor Table i QueryFilter.

Biblioteca de clase ArcObjects, a fost construit n mod deosebit prin


definirea i implementarea interfeelor, lucru caracteristic tehnologiei COM.
Prin interfa se nelege o grupare logic de proprieti i metode definit
pentru una sau mai multe clase. Interfaa se bazeaz pe un anumit nivel de
generalitate sau pe necesiti specifice de utilizare. Prin convenie,
denumirile interfeelor ncep cu litera I, de exemplu: IMap, IApplication,
IDocument etc. Interfeele, pe de o parte, sunt implementate de ctre una sau
mai multe clase iar pe de alt parte, o clas poate implementa una sau mai
multe interfee. Astfel, clasa Map implementeaz mai multe interfee printre
care IMap i ITableCollection. Pornind de la coclase, se pot defini referine
(pointeri) la interfee care se ncarc prin construirea unui obiect al unei
coclase sau prin atribuirea unui obiect / interfee unei alte interfee. Este
evident faptul c acest lucru e posibil dac respectiva clas implementeaz
ambele interfee. Avnd o referin valid la o interfa, atunci doar
metodele i proprietile acelei interfee pot fi utilizate. Pentru a exemplifica
elementele descrise, se identific faptul c interfaa IMap are o proprietate
care returneaz numrul de caracteristici spaiale selectate pe hart
31

(SelectionCount), n timp ce interfaa ITableCollection are proprietatea


TableCount care returneaz numrul de tabele de atribute nonspaiale
existente n cadrul documentului hart. Presupunem c variabila doc
reprezint o referint la interfaa IMxDocument, a obiectului MxDocument
care implementeaz documentul hart:
IMxDocument doc = ArcMap.Document;

iar aceast interfa are o proprietate care furnizeaz harta curent sub forma
unei referine la IMap. In acest caz, se foreaz conversia explicit ctre un
obiect de tip hart (Map):
Map harta = (Map)doc.FocusMap;

Pentru a accesa proprietile din interfeele IMap i ITableCollection ale


clasei Map, atunci se definesc referine la acele interfee i ele se ncarc din
obiectul harta (de tip Map):
IMap pimap = (IMap)harta;
ITableCollection pitc = (ITableCollection)harta;

Odat ce au fost ncrcate referinele ctre interfeele dorite, se pot accesa i


proprietile pentru a fi afiate:
// afiarea numrului de caracteristici selectate
MessageBox.Show(pimap.SelectionCount.ToString());
// afiarea numrului de tabele
MessageBox.Show(pitc.TableCount.ToString());

Interfeele au, de asemenea, rolul de a extinde funcionalitatea frameworkului. Astfel, se permite programatorilor s defineasc, n ArcObjects, noi
interfee care pot fi adugate la cele existente.
O interfa conine proprieti i metode pe care utilizatorul le poate
accesa prin intermediul ei. Proprietile definesc caracteristicile (atributele)
unei interfee n timp ce metodele definesc comportamente specifice ale
interfeei. In ArcObject sunt descrise grafic interfeele, astfel nct,
programatorul s-i poat da seama care sunt proprieti i care sunt metode.
Astfel, proprietile sunt descrise prin linie n timp ce metodele se descriu
prin sgei (
). La rndul lor, proprietile pot fi de mai multe feluri:
- read only, adic pot fi doar consultate valorile lor i se figureaz:
32

write only, adic pot fi doar modificate valorile lor i se


figureaz:
dac se atribuie prin valoare i
prin
referin;
- read-write, adic pot fi att consultate ct i modificate i se
figureaz:
o
n cazul n care se atribuie o valoare proprietii;
o
n cazul n care se atribuie o referin proprietii.
De exemplu, interfaa IFeatureCursor (figura 3.8) motenete interfaa
IUnknown i conine:

Figura 3.8 Interfaa IFeatureCursor

colecia de cmpuri (Fields); precum i

funcii care realizeaz tergerea unei caracteristici (DeleteFeature),


cutarea unui cmp (FindField), eliberarea buffer-elor (Flush),
inserarea unei caracteristici (InsertFeature), accesarea urmtoarei
caracteristici
(NextFeature)
i
actualizarea
caracteristicii
(UpdateFeature).

3.3 Programarea aplicaiilor GIS folosind ArcObjects


Pentru a utiliza ArcObjects n mediul .NET au fost generate
assembly-uri i biblioteci de obiecte COM pentru a gestiona interaciunea
.NET-COM. Folosind ArcOjects, se pot dezvolta aplicaii n mai multe
modaliti:
Se pot dezvolta aplicaii GIS de sine stttoare folosind
componenta ArcEngine i un mediu de dezvoltare a aplicaiilor
software precum Visual Studio.NET;
33

Se pot dezvolta extensii care ulterior se ataeaz la aplicaii ale


pachetului ArcGIS i care constituie elemente de interaciune
pentru diferite procesri personalizate n GIS;
Se pot dezvolta aplicaii Web.
Exemplificarea utilizrii framework-ului s-a realizat folosind pachetul
software ArcGIS 10 i mediul de programare Visual Studio.NET 2010, n
varianta de construire a extensiilor pentru a personaliza procesrile n GIS.
4.3.1 Modul de construire a extensiilor n ArcGIS
ArcGIS 10 introduce pentru dezvoltarea extensiilor ArcGIS Desktop
noul model add-in Desktop care furnizeaz un cadru de construire a unei
colecii de elemente personalizate, incluse ntr-un singur fiier. Utilizarea
add-ins pentru personalizarea aplicaiilor GIS ofer avantajul c acestea pot
fi uor partajate ntre utilizatorii conectai la o reea, nu necesit soft de
instalare sau parcurgerea de proceduri pentru nregistrarea COM-urilor.
Add-ins pot fi scrise n tehnologiile .NET sau Java alturi de XML
(Extensible Markup Language). XML se utilizeaz pentru a descrie
elementele de interfa, n timp ce prin .NET sau Java se implementeaz
funcionalitatea extensiilor.
Tipurile de add-ins permise pentru personalizarea aplicaiilor ArcGIS
Desktop sunt:
Butoane i instrumente reprezint controale simple care pot
apare pe bare de instrumente iar n cazul butoanelor i pe
meniuri;
Combobox furnizeaz liste derulante pentru alegerea opiunilor
dar i posibilitatea de a defini zone de editare;
Meniuri i meniuri contextuale care pot apare att pe bare de
instrumente ct i sub form de meniuri pop-up adugate
contextului aplicaiei;
Multi-opiuni reprezint o colecie dinamic de opiuni ale unui
meniu care va fi creat la momentul execuiei;
34

Bar de instrumente fereastr care poate gzdui diferite tipuri


de controale: butoane, instrumente, grupuri de instrumente i
combobox-uri;
Grup de instrumente reprezint un grup compact de instrumente
care apare n bara de instrumente sub forma unui mic buton de tip
drop-down pentru a expanda celelalte elemente din grup n
vederea utilizrii lor;
Ferestre care apar n aplicaii ArcGIS Desktop. Ele pot fi
populate cu diverse tipuri de controale, inclusiv controale ESRI;
Extensii ale aplicaiei sunt utilizate pentru coordonarea
aciunilor ntre celelalte componente (butoane, instrumente i
ferestre) care exist n cadrul add-in. Aceste extensii se utilizeaz
pentru stocarea strilor asociate add-in i se pot folosi pentru a
intercepta i rspunde la diversele evenimente expuse de
aplicaia gazd;
Extensii pentru editare permit personalizarea operaiei de
editare direct n contextul de lucru al acestei operaii. Extensiile
de editare sunt ncrcate cnd se ncepe sesiunea de editare.
Construirea unui add-in pentru ArcMap n Visual Studio .NET 2010
se realizeaz n urmtoarele etape:
A. Realizarea unui document hart (fiier mxd) care s conin o
compoziie tematic. Pornind de la existena bazei de date de tip
personal geodatabase, bd_ro.mdb, care conine judeele din
Romnia, ca date spaiale de tip poligon, n aplicaia ArcMap se
ncarc stratul tematic judete, din baza de date i se va stoca
aceast compoziie tematica n fiierul h_ro.mxd, dup cum se
observ n figura 3.9. Construirea acestui document are ca scop
crearea cadrului contextual pentru a utiliza i testa
funcionalitatea extensiei.

35

Figura 3.9 Document hart n ArcMap

Figura 3.10 Tip de proiect

B. Se deschide Visual Studio.NET 2010, se alege proiect nou de tip


Visual C#, se deschide grupul ArcGIS, se alege ablonul Desktop
Add-Ins, se selecteaz varianta 3.5 de .NET Framework i se mai
selecteaz aplicaia pentru care se va construi extensia ArcMap
Add-in, ca n figura 3.10.

36

Figura 3.11 Descrierea general a add-in-ului

C. Etapa de completare a tipului de add-in ct i a metadatelor lui se


desfoar prin intermediul a dou ferestre. In prima fereastr,
figura 3.11 se introduc date cu privire la numele, compania,
descrierea i autorul add-in-ului.

Figura 3.12 Alegerea tipului i modificarea de atribute pentru add-in

37

In cea de-a doua fereastr a procesului de construire a extensiei se va alege


n primul rnd tipul de add-in, n cazul exemplului s-a ales Button dup care
se completeaz diferite informaii despre acesta, dup cum se poate observa
n figura 3.12.
Principalul atribut care se impune a se modifica este Category
deoarece comanda definit prin acest add-in va fi regsit n ArcMap la acea
categorie. De asemenea, se impune a se modifica textul ce va apare pe
buton, tooltip-ul, imagine iconiei etc. In final se apas butonul Finish i se
termin procesul de creare a noului proiect.
Dup parcurgerea acestor etape se pot observa dou fiiere,
principale, generate:
Fiierul Config.esriaddinx conine descrierea add-in-ului sub
forma unui document XML:
<ESRI.Configuration xmlns="http://schemas.esri.com/Desktop/AddIns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>Test_add</Name>
<AddInID>{154cb4c3-092a-4bfd-a203-4688972b7cbe}</AddInID>
<Description>Test Extensie</Description>
<Version>1.0</Version>
<Image>Images\Test_add.png</Image>
<Author>mar</Author>
<Company>ASE</Company>
<Date>3/24/2011</Date>
<Targets>
<Target name="Desktop" version="10.0" />
</Targets>
<AddIn language="CLR" library="Test_add.dll" namespace="Test_add">
<ArcMap>
<Commands>
<Button id="ASE_Test_add_Button1" class="Button1"
message="Add-in command generated by Visual Studio project wizard."
caption="Test" tip="Exemplu de test!" category="Test extensie"
image="Images\Button1.png" />
</Commands>
</ArcMap>
</AddIn>
</ESRI.Configuration>

Se regsesc n acest document informaiile care au fost introduse prin


formele prezentate la procesul de construire a proiectului, rezultatul fizic al
acestui proiect adic o bibliotec cu legare dinamic, n exemplul prezentat,
38

avnd numele Test_add.dll. Tot n cadrul proiectului a fost generat folderul


Images n care se observ fiierul Button1.png care conine iconia implicit
a butonului. Imaginea poate fi editat cu un editor de imagini bitmap astfel
nct programatorul s-i personalizeze elementul de interaciune.
Fiierul Button1.cs conine comportamentul acestui add-in sub
form de cod surs scris n limbajul C#:
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace Test_add
{
public class Button1 : ESRI.ArcGIS.Desktop.AddIns.Button
{
public Button1()
{
}
protected override void OnClick()
{
//
// TODO: Sample code showing how to access button host
//
ArcMap.Application.CurrentTool = null;
}
protected override void OnUpdate()
{
Enabled = ArcMap.Application != null;
}
}
}

Clasa care implementeaz comportamentul butonului are numele implicit


(Button1) iar metoda suprascris OnClick() trebuie dezvoltat astfel nct la
evenimentul Click pe buton s se efectueze aciunea dorit. Pentru
exemplificare, se va afia mesajul Ai apasat!! ntr-o caset de mesaje.
Afiarea mesajului se va face prin apelul metodei statice Show din clasa
MessageBox dup cum urmeaz: MessageBox.Show("Ai apasat!!"); n cadrul
metodei
OnClick.
Clasa
MessageBox
aparine
domeniului
System.Windows.Forms care se va include: using System.Windows.Forms; i
totodat se va aduga la Solution Explorer/References componenta .NET:
System.Windows.Forms.
39

Dup aceste modificri, se va rula proiectul i se observ c se


lanseaz, n paralel, aplicaia ArcMap. Pentru a testa extensia se procedeaz
astfel:
n ArcMap se selecteaz meniul Customize/Toolbars/Customize
i apare dialogul din figura 3.13. Utilizatorul extensiei poate s-i
construiasc propriul toolbar care s fie folosit ca gazd pentru
propriile lui comenzi. Pentru acest lucru, se apas butonul New...
i se construiete o nou bar de instrumente (n exemplu, avnd
numele Test figura 3.13).

Figura 3.13 Personalizarea interfeei cu utilizatorul

Prin apsarea butonului OK se va construi noua bar de instrumente care va


fi adugat la cele deja existente n ArcMap ns ea nu va conine nici un
control figura 3.14.
Adugarea controlului (butonului) la bara de instrumente care
tocmai a fost creat; Se alege tab-ul Commands n cadrul ferestrei
de dialog Customize i va apare forma ilustrat n figura 3.15. Se
observ c fereastra conine dou controale de tip list, una
conine categoriile iar cealalt comenzile care aparin respectivei
categorii. Astfel, se caut categoria care are numele identic cu
ceea ce s-a introdus la construirea proiectului, pentru atributul
categorie (vezi figura 3.12). Dup selectarea categoriei, se poate
observa c n lista de comenzi apare comanda construit prin
40

aplicaia .NET. Se selecteaz comanda i prin drag and drop se


adaug n bara de instrumente anterior construit. Astfel, bara de
instrumente se populeaz cu comenzile pe care le dezvoltm noi
sau cu alte comenzi deja existente n ArcMap. In figura 3.16 se
ilustreaz bara de instrumente populat cu comanda Test. Dup
procesul de populare cu comenzi a barei de instrumente, se
nchide fereastra de dialog Customize apsnd pe butonul Close.

Figura 3.14 Adugarea unei noi bare de instrumente

Figura 3.15 Categorii / comenzi

41

Salvarea documentului hart din ArcMap pentru ca acesta s


stocheze i extensia personalizat. Ori de cte ori se va deschide
documentul h_ro.mxd va apare i extensia nou construit. Acest
proces de construire a extensiei se va face o singura dat, la
prima rulare a aplicaiei. In rest, se va deschide documentul i se
va testa funcionalitatea comenzii.

Figura 3.16 Extensia personalizat n ArcMap

Testarea funcionalitii comenzii se face dnd click pe butonul


din bara nou construit. Rezultatul este ilustrat n figura 3.17 i se
concretizeaz prin afiarea mesajului Ai apasat!! n caseta de
mesaje.

Figura 3.17 Rezultatul testrii comenzii

42

4.3.2 Simbologii n GIS


Una din principalele aplicaii ale GIS se refer la faptul c, pe hri,
se pot afia diverse informaii statistice, astfel, utilizatorul avnd i o
perspectiv geografic asupra fenomenului reprezentat. Afiarea rezultatelor
fenomenelor economice / sociale pe hri implic construirea de cartograme.
Prin cartogram se nelege reprezentarea grafic pe o hart a unor indicatori
statistici prin: tonuri de culoare, patternuri de afiare, dimensiuni variabile a
simbolurilor afiate etc.
Privind din perspectiva modelului relaional, se consider o baza de
date de tip personal geodatabase bd_ro.mdb, n care exist tabela judete care
conine judeele sub form de date spaiale de tip poligon i tabela populaie
care conine populaia judeelor dup cum urmeaz:
populaia n orae mari (avnd un numr de locuitori mai mare de
150000) cpop;
populaia n orae (avnd un numr de locuitori cuprins ntre
10000 i 150000) tpop;
populaia n mediul rural (avnd un numr de locuitori mai mic
de 10000) rpop.
Cele dou tabele conin un cmp comun pe baza cruia se realizeaz
jonciunea ntre cele dou tabele, este vorba de simbolul judeului aa cum
apare pe numerele de nmatriculare a autovehiculelor, cmp de tip ir de
caractere de lungime dou caractere. Numele lui este sy n tabela populaie i
sj n tabela judee.
Un prim exemplu de realizare a unei cartograme const n a colora
judeele de pe hart ntr-un gradient de culoare n funcie de populaia lor
total. Astfel, prin apsarea butonului de pe bara de instrumente construit n
acest scop, harta se va colora n funcie de totalul populaiei i va apare i
legenda corespunztoare simbologiei create.
Codul surs conine mai multe pri n funcie de etapele pe care le
soluioneaz:

43

Identificarea stratului tematic care se va colora n cazul


exemplului este vorba de layer-ul judee.
// declarare de variabile pentru a stoca numarul de layer-e (nl),
// i variabila contor i nrg numrul de grupe (intervale) n care
// se vor diviza judeele n funcei de populaie
int nl, i, nrg=3;
IMxDocument doc = ArcMap.Document; // obinerea documentului hart
IMap harta = doc.FocusMap; // obinerea hrii
// declarare de interfee pentru layer fiecare conine proprieti
// i metode necesare n diferite contexte de lucru
ILayer lyr = null;
IFeatureLayer ifl = null;
IFeatureClass ifc = null;
// determinarea numrului de layere ce exist n cadrul hrii
nl = harta.LayerCount;
// iterarea layer-elor pentru a identifica layerul judete
// pe care dorim sa-l colorm
for (i = 0; i < nl; i++)
{
lyr = harta.get_Layer(i);
if (lyr.Name == "judete")
{
// accesarea interfeei IFeatureLayer pentru layer-ul dorit
ifl = (IFeatureLayer)lyr;
// prin interfaa IFeatureLayer se acceseaz proprietatea FeatureClass
// care conine proprieti i metode cu privire la clasa de
// caracteristici spaiale
ifc = (IFeatureClass)ifl.FeatureClass;
}
}

Construirea spaiului de lucru de tip baz de date Access care se


va mapa pe fiierul bd_ro.mdb:
Type tip =
Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory");
IWorkspaceFactory wsf =
(IWorkspaceFactory)Activator.CreateInstance(tip);
IWorkspace ws = wsf.OpenFromFile(@"d:\test_bdsa\bd_ro.mdb", 0);

Realizarea jonciunii ntre tabela de atribute spaiale judete i


tabela de atribute nonspaiale populatie. Pentru a realiza acest
lucru trebuie ca tabela de atribute nonspaiale s fie inclus n
documentul hart. Dup cum se poate observa n figura 3.17,
aplicaia ArcMap conine dou ferestre principale i anume
fereastra din stnga ce afieaz cuprinsul hrii (Table Of
44

Contents TOC) i fereastra n care se afieaz compoziia


tematic (harta) propriu-zis. In fereastra TOC se vizualizeaz
layer-ele adic straturile tematice, bara de instrumente a ferestrei
conine mai multe butoane care ofer i o alt perspectiv
coninutului ferestrei TOC. Astfel, dac se apas pe butonul List
by Source se listeaz toate entitile incluse la documentul hart
prin sursa lor de provenien. In cazul n care se adaug i tabela
de atribute nonspaiale populatie, alturi de caracteristica spaial
judee, atunci fereastra TOC va avea coninutul afiat n figura
3.18.

Figura 3.18 Afiarea entitilor unui document prin sursa lor

Adugarea tabelei de atribute nonspaiale se poate face static,


respectiv prin programare:

//se construiete un set de date cu numele tabelei (populaie)


// n cadrul spaiului de lucru
// construit anterior (baza de date Access bd_ro.mdb)
IDatasetName dsn = new TableNameClass();
dsn.Name = "populatie";
dsn.WorkspaceName = (IWorkspaceName)(((IDataset)ws).FullName);
// se deschide tabela populatie i se ncarc variabila
// tpop de tip ITable
IName name = (IName)dsn;
ITable tpop = (ITable)name.Open();
if (tpop == null) { MessageBox.Show("Nu exista tabela"); return; }
// se adaug tabela la colectia de tabele a hartii
// colectia de tabele fiind (ITableCollection)
// care se refer doar la tabelele de atribute nonspaiale
((ITableCollection)harta).AddTable(tpop);

45

Tabela populaie conine populaia n orae mari, n orae i n mediul rural


pentru fiecare jude. Pentru a obine populaia total se va face suma acestor
cmpuri i se va stoca ntr-un alt atribut al tabelei populaie. Cartograma se
va realiza prin colorarea hrii n funcie de populaia total a judeului.

Adugarea cmpului Total_populaie la tabela populatie:

//construirea cmpului Total_populatie de tip ntreg


IField totp = new FieldClass();
IFieldEdit totped = (IFieldEdit)totp;
totped.Name_2 = "Total_populatie";
totped.Type_2 = esriFieldType.esriFieldTypeInteger;
//adugarea cmpului nou construit la tabela populatie
tpop.AddField(totped);

Umplerea cmpului Total_populaie cu suma valorilor celor trei


cmpuri (cpop+tpop+rpop), adic populaia n orae mari, orae i
mediul rural

// construirea unui cursor mapat pe tabela populatie - tpop


ICursor ctpop = tpop.Update(null, false);
IRow rind;
// traversarea cursorului rnd cu rnd
rind = ctpop.NextRow();
while (rind != null)
{
// calcului valorii noului cmp
int k = (Int32)rind.get_Value(1) + (Int32)rind.get_Value(2) +
(Int32)rind.get_Value(3);
// setarea valorii cmpului dorit
rind.set_Value(4, k);
// confirmarea modificrii rndului
ctpop.UpdateRow(rind);
// trecerea la rndul urmtor
rind = ctpop.NextRow();
}

Efectuarea jonciunii propriu-zise dintre tabela care conine


caracteristica spaial (judete) i tabela cu date nonspaiale
(populatie) pe cmpul simbol jude:

// construirea unui obiect pentru realizarea jonciunii n memorie


IMemoryRelationshipClassFactory mrc = new
MemoryRelationshipClassFactoryClass();
// realizarea jonciunii ntre tabelele judete identificat
// prin ifc i populaie
// identificat prin tpop, relaia este de tip unu la unu

46

IRelationshipClass rc = mrc.Open("test", ifc, "sj",


(IObjectClass)tpop, "sy", "jud", "populatie",
esriRelCardinality.esriRelCardinalityOneToOne);
// afiarea relaiei n cadrul aplicaiei ArcMap
((IDisplayRelationshipClass)ifl).DisplayRelationshipClass(rc,
esriJoinType.esriLeftOuterJoin);

Construirea intervalelor pentru divizarea judeelor n funcie de


populaia lor. In ArcGIS sunt implementate mai multe tehnici de
a realiza clasificarea unor elemente n funcie de valoarea unui
indicator (atribut). Pentru a realiza acest lucru trebuie s se
identifice intervale disjuncte de valori iar elementele care au
valoarea indicatorului respectiv ntr-un anumit interval formeaz
o grup. Spre exemplu, cea mai simpl metod de calcul a
intervalelor de valori se refer la divizarea n intervale egale a
domeniului de valori aferent cmpului pe baza cruia se face
clasificarea. Metoda folosit n exemplu pentru determinarea
intervalelor o reprezint divizarea natural (NaturalBreaks) care
are la baz principiul formrii de grupe astfel nct dispersia n
interiorul grupei s fie minim iar dispersia ntre grupe s fie
maxim.
// construirea unei histograme pe baza atributului dup care
// se va face clasificarea
ITableHistogram ith = new BasicTableHistogramClass();
// cmpul
ith.Field = "Total_populatie";
// tabela care contine cimpul
ith.Table = tpop;
// declararea a doua obiecte in care se vor stoca valorile
// atributului (vval) si frecvenele de apariie a lor (vfrecv)
object vval, vfrecv;
// ncrcarea propriu-zis a obiectelor
((IBasicHistogram)ith).GetHistogram(out vval, out vfrecv);
// construirea unei interfee de clasificare pe baza
// metodei NaturalBreaks
IClassify div_grupe = new NaturalBreaksClass();
// atribuirea datelor pe baza crora se vor genera intervalele
div_grupe.SetHistogramData(vval, vfrecv);
// ncrcarea numrului de grupe (intervale) care se vor genera
div_grupe.Classify(ref nrg);
// declararea unui vector care va conine limitele intervalelor
double[] vecgr;

47

// generarea limitelor
vecgr = (double [])div_grupe.ClassBreaks;

Astfel, dac se dorete clasificarea judeelor, din punct de vedere a


populaiei, n trei grupe, atunci vectorul vecgr va conine patru valori, iar
intervalele se formeaz astfel:
o Primul interval: [ vecgr[0], vecgr[1] );
o Al doilea interval: [ vecgr[1], vecgr[2] ); i
o Al treilea interval: [ vecgr[2], vecgr[3] ];
Pe hart, acest lucru se vizualizeaz prin colorarea diferit a judeelor n
funcie de intervalul de valori la care va aparine valoarea cmpului
Total_populatie (figura 3.20). Cu alte cuvinte, intervalelor li se vor asocia
culori, de obicei se utilizeaz culori graduale, adic un gradient de culoare.

Figura 3.19 Rampe de culoare din galeria de stiluri definit de ESRI

Generarea culorilor cu care se vor colora judeele de pe hart. In


terminologia ESRI, culorile se definesc fie individual, n acest
caz exist clase specializate pe diferite modele de culoare, de
exemplu RgbColor aferent modelului RGB, fie colecii de culori
modelate prin clase de tip ramp de culori (ColorRamp).
Coleciile de culori pot fi generate de ctre programator sau pot fi
utilizate i colecii predefinite care se afl n galeria de stiluri
definit de ESRI, dup cum se poate observa n figura 3.19.
48

Pentru a accesa galeria, se selecteaz n ArcMap Customize/Style


Manager i va apare dialogul din figura 3.19.
Pentru a accesa culorile din rampa de culori avnd numele Yellow to Dark
Red se va proceda astfel:
// definirea unei interfee de tip ramp de culoare
IColorRamp rcul = null;
// se alege din galeria ESRI un element (rampa de culoare)
// avnd categoria Default Ramps
IEnumStyleGalleryItem vst = doc.StyleGallery.get_Items("Color Ramps",
"ESRI.style", "Default Ramps");
// se itereaz elementele pn cnd se identific rampa de culoare cu
// numele Yellow to Dark Red
IStyleGalleryItem elem = vst.Next();
while (elem != null)
{
if (elem.Name == "Yellow to Dark Red")
{
rcul = (IColorRamp)elem.Item;
break;
}
elem = vst.Next();
}
// calibrarea rampei de culori la nrg culori;
// din rampa de culori Yellow to Dark Red
// se vor folosi doar nrg culori n exemplu, nrg = 3
rcul.Size = nrg;
bool varb;
// construirea rampei de culori
rcul.CreateRamp(out varb);

Colorarea hrii folosind culorile din rampa de culori i


clasificarea n cele trei intervale de valori generate anterior:
// definirea unui obiect pentru simbologie bazat pe intervale
// de valori
IClassBreaksRenderer cbr = new ClassBreaksRenderer();
// specificarea cmpului pe baza cruia se va face redarea
cbr.Field = "Total_populatie";
// stabilirea numrului de grupe
cbr.BreakCount = nrg;
// setarea valorii minime care reprezint limita inferioar a
// primului interval de valori
cbr.MinimumBreak = vecgr[0];
// declararea unei interfee care exprim modul de umplere
// al poligoanelor - umplere uniform cu culoare
ISimpleFillSymbol fs;
for (i = 0; i < cbr.BreakCount; i++)

49

{
fs = new SimpleFillSymbol();
// stabilirea culorii de umplere
fs.Color = rcul.get_Color(i);
// asocierea simbolului de umplere
cbr.set_Symbol(i, (ISymbol)fs);
// setarea valorii limitei superioare a intervalului
cbr.set_Break(i, vecgr[i+1]);
// etichetarea n legenda hrii ce va apare in TOC
cbr.set_Label(i, vecgr[i].ToString()+ "-" +
vecgr[i+1].ToString() );
}
IGeoFeatureLayer gfl = (IGeoFeatureLayer)lyr;
// asocierea simbologiei (cbr) layer-ului lyr, ce corespunde judeelor
gfl.Renderer = (IFeatureRenderer)cbr;
// redesenarea coninutului vizualizrii curente
doc.ActiveView.Refresh();
// actualizarea coninutului ferestrei TOC (afiarea legendei)
doc.UpdateContents();

Figura 3.20 Colorarea hrii n gradient de culoare pe baza populaiei judeului

Un alt tip de simbologie, se refer la afiarea graficelor pe datele


spaiale pentru a surprinde proporiile unor variabile n cadrul datelor
statistice reprezentate. Pentru exemplificare, s-a ales s se reprezinte pe
hart, prin grafice de tip pie proporia populaiei din: orae mari, orae i din
mediul rural n total populaie, pentru toate judeele rii, dup cum se poate
observa n figura 3.21. Datele cu privire la populaia judeelor n orae mari,
50

orae i mediul rural sunt stocate n tabela populatie n cadrul bazei de date
bd_ro.mdb dup cum s-a prezentat n exemplul anterior. Pentru a nu duplica
codul din exemplul anterior, se vor prezenta acele aspecte care difer sau
trebuie adugate. Astfel, s-au fcut, n plus, declaraiile:
string[] vs = { "Populatia in orase mari", "Populatia in orase",
"Populatia in rural" };
string[] numec = { "cpop", "tpop", "rpop" };

unde:
-

vs reprezint vectorul de etichete ce se va folosi la descrierea


elementelor din legenda hrii; iar
- numec reprezint vectorul ce conine numele cmpurilor pe
baza crora se va constitui graficul de tip pie.
Secvena de cod conine etapele deja prezentate n exemplul anterior:
identificarea stratului tematic judete pe care se va afia simbologia de tip
piechart (setarea variabilei lyr), construirea spaiului de lucru mapat pe baza
de date bd_ro.mdb, adugarea tabelei populatie la documentul hart,
realizarea jonciunii ntre tabela judete i tabela populatie. Pentru a afia
efectiv simbologia de tip piechart pe stratul tematic judete, din hart, dup
ce s-au parcurs etaplele enumerate anterior, se procedeaz astfel:
// construirea unei rampe de nrg (= 3) culori pe baza rampei de culori
// Red to Green, din galeria ESRI
IColorRamp rcul = null;
// doc are aceeai semnificaie ca i n exemplul anterior
// documentul hart
IEnumStyleGalleryItem vst = doc.StyleGallery.get_Items("Color Ramps",
"ESRI.style", "Default Ramps");
IStyleGalleryItem elem = vst.Next();
while (elem != null)
{
if (elem.Name == "Red to Green")
{
rcul = (IColorRamp)elem.Item;
break;
}
elem = vst.Next();
}
rcul.Size = nrg;
bool vb;
rcul.CreateRamp(out vb);

51

// definirea unei interfee pentru descrierea tipului de umplere


ISimpleFillSymbol fs;
// construire interfa pentru simbologia de tip piechart
IPieChartSymbol pcs = new PieChartSymbolClass();
// construire interfa pentru redarea simbologiei de tip chart
IChartRenderer cr = new ChartRenderer();
// setarea sensului de construire a feliilor graficului
// (sensul acelor de ceas)
pcs.Clockwise = true;
// mrimea simbolului (a piechart-ului)
((IMarkerSymbol)pcs).Size = 30;
// se sabilesc parametrii pentru cele nrg (=3) variabile care vor
// compune piechart-ul
for (i = 0; i < nrg; i++)
{
// construirea unui nou simbol de umplere
fs = new SimpleFillSymbol();
// asocierea culorii de umplere preluat din rampa de culoare
// anterior construit
fs.Color = rcul.get_Color(i);
// adugarea simbolului la colecia de simboluri
((ISymbolArray)pcs).AddSymbol((ISymbol)fs);
// adugarea cmpului care se va reda prin piechart
((IRendererFields)cr).AddField(numec[i]);
// asocierea etichetei cmpului pentru afiare la legend
((IRendererFields)cr).set_FieldAlias(i, vs[i]);
}
// asocierea simbologiei de tip piechart construit la simbologia
// de tip chart
cr.ChartSymbol = (IChartSymbol)pcs;
// stabilirea simbolului pentru background-ul hrii
IRgbColor cul = new RgbColor();
fs = new SimpleFillSymbol();
// setare culoare de umplere
cul.Red = 250; cul.Green = 250; cul.Blue = 250;
// asocierea culorii la simbolul nou creat
fs.Color = cul;
// asocierea simbolului construit ca background
cr.BaseSymbol = (ISymbol)fs;
// construirea legendei se va afia n fereastra TOC
cr.CreateLegend();
// etichetarea n legend a simbologiei
cr.Label = "Distributia populatiei pe medii";
// evitarea suprapunerii graficelor
cr.UseOverposter = true;
// asocierea simbologiei (cr) layer-ului lyr, ce corespunde judeelor
IGeoFeatureLayer gfl = (IGeoFeatureLayer)lyr;
gfl.Renderer = (IFeatureRenderer)cr;
// redesenarea coninutului vizualizrii curente
doc.ActiveView.Refresh();

52

// actualizarea coninutului ferestrei TOC


doc.UpdateContents();

Figura 3.21 Simbologie de tip PieChart

3.3.3 Elemente de geoprocesare


Pe lng realizarea de simbologii pe hri, prin GIS, se realizeaz i
procesri de date spaiale. Operaiile referitoare la geoprocesare sunt
implementate n cadrul produsului software ArcGIS i pot fi utilizate n
diferite forme. In cadrul acestui capitol accentul se va pune pe partea de
efectuare a geoprocesrii prin programare ns pentru a realiza acest lucru
este necesar a cunoate semnificaia operaiilor de geoprocesare precum i
varianta vizual (user friendly) de declanare a lor.
Pentru exemplificare, se consider compoziia tematic (figura 3.22)
compus din straturile:
- ruri, de tip polilinie ce conine rurile romniei.
- judete, de tip poligon ce conine judeele romniei;
i se dorete identificarea rurilor care strbat anumite judee.
Rezolvarea acestei probleme const n efectuarea a dou operaii:
- selecia judeelor pentru care dorim s identificm ce ruri exist
n ele;
53

efectuarea operaiei de decupare (clip) a stratului tematic ruri n


funcie de judeele selectate.
Rezultatul operaiei va fi un nou strat tematic ce va conine doar rurile care
se afl n judeele selectate.
Efectuarea vizual a acestei operaii presupune folosirea unei
componente din ArcMap care se numete ArcToolbox i se invoc:
Geoprocessing/ArcToolbox, dup cum se poate observa n figura 3.22.

Figura 3.22 Componenta ArcToolbox

Componenta ArcToolbox conine instrumente care permit executarea de


operaii elementare n ArcGIS. Aceste operaii sunt grupate n funcie de
tipul datelor spaiale pe care ele opereaz, de categoria de prelucrri
efectuate etc. Pentru a face selecia unei caracteristici spaiale folosind un
atribut nonspaial, prin componenta Toolbox, se acceseaz grupul de operaii
Data Management Tools / Layers and Table Views iar din cadrul grupului se
execut instrumentul Select Layer by Attribute (figura 3.23). Interfaa
instrumentului i precum i modul de completare a parametrilor pentru a
selecta judeul care are simbolul judeului (sj=ag), adic judeul Arges, se
prezint n figura 3.23. Rezultatul operaiei de selecie este vizualizat n
figura 3.24. O alternativ mai simpl pentru selecie const n a selecta
54

instrumentul de selecie din bara de instrumente a aplicaiei, ce are simbolul:


, dup care se d click pe judetul care se dorete a se selecta. In cazul n
care judeul este Arge, rezultatul ar fi identic cu ceea ce s-a prezentat n
figura 3.24. Decuparea rurilor care exist n judeul Arge se face prin
execuia instrumentului: Analysis Tools / Extract / Clip. Ca parametrii,
acest operaie primete: caracteristica spaial care se va decupa (rauri),
caracteristica spaial pe baza creia se face decuparea (judete),
cacarteristica spaial care va stoca rezultatul (rauri_rez) care este
parametrul de ieire al operaiei. Un parametru opional al operaiei n
constituie tolerana decuprii exprimat n uniti de lungime. Dup
efectuarea operaiei se va construi un nou strat tematic (rauri_rez) care se va
aduga hrii i care va conine toate rurile care se afl n judeul Arge, ca
n figura 3.25.

Figura 3.23 Interfaa operaiei de selecie a caracteristicii spaiale prin atribute


nonspaiale

Operaiile din ArcToolbox se pot declana i n modul programare,


prin construirea de extensii dup cum s-a prezentat n paragraful 3.3.1.
Categoriile de instrumente de geoprocesare sunt definite sub form de
module care se adauga n proiectul Visual Studio.NET. Referina poart
55

acelai nume cu categoria i se regsesc ca i componente .NET. Astfel, dac


se dorete efectuarea operaiei de decupare, se adaug referina .NET cu
numele ESRI.ArcGIS.AnalysisTools i se adaug domeniul de nume:
using ESRI.ArcGIS.AnalysisTools;

Figura 3.24 Selecia judeului Arge pe hart

In acest context, toate intrumentele se regsesc ca fiind clase i lor li se


atribuie parametrii de intrare, de ieire i eventual ali parametrii necesari
execuiei operaiei, n mod similar lucrului cu comenzi:
// se construiete un obiect Clip
Clip ob_clip = new Clip();
// se seteaz caracteristica ce se va decupa
ob_clip.in_features = "rauri";
// se seteaz caracteristica pe baza creia se va face decuparea
ob_clip.clip_features = "judete";
// se seteaz caracteristica ce va stoca rezultatul operaiei
ob_clip.out_feature_class = @"D:\test_bdsa\bd_ro.mdb\rauri_rez";

Dup construirea obiectului Clip i dup ce au fost ncrcai parametrii,


pentru a efectua propriu-zis operaia se procedeaz astfel:
// se construiete un obiect de tip Geoprocessor
Geoprocessor gp = new Geoprocessor();
// proprietatea OverwriteOutput = true determin ca rezultatul s fie
// suprascris la o nou execuie a comenzii
gp.OverwriteOutput = true;
// executarea propriu-zis a comenzii identificat prin

56

// obiectul ob_clip
gp.Execute(ob_clip, null);

Figura 3.25 Rezultatul operaiei de decupare

Pentru a obine rurile care se afl n judeul Arge, mai nti se selecteaz
judeul folosind instrumentul de selecie din bara de instrumente a aplicaiei
ArcMap dup care se apas butonul din extensia construit de utilizator iar
rezultatul va apare dup cum se poate observa n figura 3.25.

57

4. Dezvoltarea aplicaiilor software bazate pe MS


Office
4.1 Introducere
Aplicaiile bazate pe Office sunt deosebit de utile, n practic,
deoarece folosesc facilitile existente n aplicaiile pachetului software
Microsoft Office. Pentru a dezvolta astfel de aplicaii sau extensii, pe
platforma .NET a fost construit un framework cunoscut sub denumirea de
Visual Studio Tools for Office (VSTO). Acesta ofer suport de programare
.NET pentru Word, Excel, Outlook, PowerPoint, Project, Visio i InfoPath
n Visual Studio. De asemenea, VSTO permite ca documente Word i Excel
s foloseasc caracteristici de programare din .NET cum ar fi suport pentru
legarea datelor, controale care se pot folosi n forme windows etc.

Figura 4.1 Ierarhia modelului EOM

Scrierea codului pentru aplicaiile bazate pe Office implic utilizarea


modelului cunoscut sub denumirea de OOM Office Object Model. Acest
model conine un set de clase i obiecte necesare pentru pentru controlul
aplicaiilor Office. Modelele sunt particularizate n funcie de aplicaiile pe
58

care le controleaz, de exemplu: EOM Excel Object Model, WOM Word


Object Model etc. In general, aceste modele conin o ierarhie de clase i sunt
organizate astfel nct n rdcina ierarhiei se afl clasa Application care
modeleaz comportamentul unei aplicaii particulare din pachetul software
MS Office. Pe lng clasa Application care este prezent n toate ierarhiile,
exist i clase particulare n ierarhie ce depind de aplicaia propriu-zis i
corespund entitilor pe care le manipulm efectiv n aplicaiile Office. De
exemplu, pentru aplicaia Excel, principalele clase ct i relaiile dintre ele
sunt ilustrate n figura 4.1.

Figura 4.2 Ierarhia modelului WOM

Se observ c, la baza ierarhiilor se afl clasa Application care


modeleaz comportamentul aplicaiei Office i prin intermediul acestei clase
se construiete o instan a aplicaiei. Instana aplicaiei poate conine o
colecie de documente modelat prin intermediul coleciei Documents n
WOM sau Workbooks n EOM. Un element al coleciei, adic un obiect de
tip Document sau Workbook, poate conine o colecie de paragrafe
(Paragraphs) sau o colecie de foi de calcul Worksheets.
Pentru aplicaia Word, ierarhia este prezentat n figura 4.2.
59

Pentru dezvoltarea de aplicaii bazate pe PowerPoint, modelul este


PPOM i are ierarhia prezentat n figura 4.3.

Figura 4.3 Ierarhia modelului PPOM

Din figur se observ c aplicaia este compus dintr-o colecie de prezentri


(Presentations) care are elemente de tip prezentare (Presentation), o
prezentare la rndul ei se compune dintr-o colecie de slide-uri (Slides) de
elemente Slide n care se gsesc diferite tipuri de obiecte, cu corespondent
vizual, coninute ntr-o colecie de elemente Shapes.
Ierarhiile de clase specifice tipurilor de aplicaii Office conin clase
care descriu entitile cu care opereaz aplicaiile pachetului Office.
Folosind elemente ale modelului de programare OOM se pot
dezvolta aplicaii n diferite modaliti:
- Aplicaii de utilizator ce interacioneaz cu aplicaii Office; adic
programatorul i dezvolt propria sa aplicaie care n background va
controla i interaciona cu aplicaii i documente Office. De exemplu,
se construiete o aplicaie independent, n mod consol sau
Windows Forms, care are ca scop introducerea unor date ntr-un
document Word pentru a fi ulterior stocat sau imprimat pe hrtie.
Executarea unei astfel de aplicaii va determina lansarea n execuie a
aplicaiei Office pentru a efectua diferite procesri, specifice. In acest

60

mod, aplicaia de utilizator se va executa ntr-un proces distinct fa


de aplicaia Office.
- Construirea de module funcionale existente sub form de biblioteci
cu legare dinamic (DLL Dynamic Link Library) care se includ n
aplicaiile Office pentru a personaliza prelucrrile aplicate
documentelor. De exemplu, construirea unui modul add-in care s
aib ca element de interfa un buton pentru efectuarea unei
prelucrri nestandard asupra datelor existente ntr-o foaie de calcul;
- Ataarea de cod documentelor Office, implic construirea unei
aplicaii pe baza unui ablon de aplicaie Office, definit n mediul
Visual Studio ca tip distinct de proiect (de exemplu, pe baza unui
ablon de aplicaie Excel). Codul ataat permite efectuarea de
prelucrri personalizate i impune construirea de noi interfee pentru
declanarea procesrilor. Secvenele de cod se pot ataa fie
documentelor Office fie abloanelor de documente.
Ultimele dou modaliti prezentate de a dezvolta aplicaii bazate pe Office
au caracteristic faptul c secvenele de cod personalizate ruleaz cu aplicaia
Office n acelai proces; conceptul poart numele de cod gazduit. Pentru a
rula codul n procesul aplicaiei Office, aplicaia respectiv trebuie s
recunoasc codul, sa-l ncarce n procesul su i apoi sa-l execute.
Componentele Office add-in sunt nregistrate n registri astfel nct ele pot fi
gsite i startate de ctre aplicaiile Office. Codul asociat documentelor nu
necesit a fi nregistrat, n schimb el este asociat cu documentul prin
adugarea de proprieti specifice care se stocheaz n fiierul documentului.
Cnd documentul Office este ncrcat atunci se consult proprietile i se
ncarc i codul asociat documentului.
Inainte de VSTO, dezvoltatorii de aplicaii bazate pe Office puteau
folosi limbajul VBA pentru a scrie secvene de cod prin care s-i definesc
propriile prelucrri. Aceste secvene erau scrise direct n interfaa aplicaiei
Office. Toate secvenele de cod VBA se stocau odat cu documentul pentru
care acestea erau scrise. In VSTO, aceast modalitate de a asocia cod unui
61

document se numete soluie la nivel de document. Astfel, n VSTO, se


poate construi o component add-in care s fie livrat mpreun cu
documentul pentru care proceseaz date. Aceast component devine activ
la momentul ncrcrii documentului respectiv n aplicaia Office. Acest tip
de soluie la nivel de document este relevant n cazul aplicaiilor Word i
Excel.
VSTO mai introduce un nou concept i anume soluie la nivelul
aplicaei. Astfel, soluia furnizat sub forma unui add-in se folosete pentru
a realiza o procesare specific i se poate aplica oricrui document deschis n
aplicaia pentru care a fost creat componenta.

5.2 Aplicaii ce interacioneaz cu aplicaii Office


Acest mod de interaciune cu aplicaiile din Office presupune
existena unei aplicaii principale care va avea ca scop construirea unei noi
instane a unei aplicaii Office, apoi prin folosirea modelului orientat obiect,
controlul interaciunii cu aceasta. La final, aplicaia Office trebuie nchis n
mod explicit deoarece nchiderea aplicaiei principale nu determin n mod
implicit i nchiderea aplicaiei Office. Pe de alt parte, aplicaia Office
ruleaz n background adic ea nu este vizibil pentru utilizator. Prin
schimbarea valorii proprietii Visible, fereastra aplicaiei Office devine
vizibil pentru utilizator astfel nct acesta poate realiza vizual alte operaii
folosind interfaa acesteia.
Pentru exemplificare, se va construi o aplicaie Windows Forms care
va conine dou controale, unul de tip TextBox i unul de tip DataGridView
pe care utilizatorul le poate ncrca cu date (figura 4.4). La apsarea unui
buton, textul din TextBox va fi exportat ntr-un document Word. De
asemenea i datele coninute n controlul de tip DataGridView se vor exporta
n document sub forma unui tabel. Dup efectuarea transferului, fereastra
aplicaiei Word va deveni vizibil astfel nct utilizatorul va putea salva,
tipri sau nchide documentul.
62

Figura 4.4 Forma aplicaiei principale completat cu date

La apsarea pe butonul Exporta in Word datele introduse n forma aplicaiei


vor fi exportate ntr-un document Word, dup cum se ilustreaz n figura 4.5.
Pentru ca o aplicaie s interacioneze cu un document al unei aplicaii
Word, prin modelul WOM, trebuie ca la proiect s se adauge referina ctre
componenta .NET: Microsoft.Office.Interop.Word, pentru care se adaug i
domeniul de nume sub forma:
using Word = Microsoft.Office.Interop.Word;

Figura 4.5 Document Word construit prin intermediul unei aplicaii de utilizator

63

A. Construirea documentului, necesit mai nti crearea cadrului de


lucru:
- Crearea unei noi instane a unei aplicaii Word:
Word.Application wapl = new Word.Application();

Construirea n cadrul acestei instane a unui nou document:


Word.Document wdoc = wapl.Documents.Add();

B. Popularea documentului cu date i formatarea lor corespunztoare:


Unul dintre cele mai utilizate i flexibile obiecte care sunt necesare
pentru explorarea i popularea cu date a unui document Word, prin
modelul WOM, este Range. Prin intermediul lui se definete un bloc
continuu de text dintr-un document. Dup ce documentul a fost creat
i este vid, se definete un obiect de tip Range mapat pe ntregul
document, prin apelul metodei Range() a obiectului document
(wdoc):
Word.Range wr = wdoc.Range();

Dup definirea unui astfel de obiect se poate seta proprietatea Text


pentru a scrie un anumit text n document, n zona marcat de obiectul
Range:
wr.Text = "\n\n"+titlu.Text+"\n";

din secvena de cod, se observ c s-au lsat dou linii vide n document, iar
textul celei de-a treia a fost preluat din obiectul titlu de tip TextBox care
conine irul: Stat de plata dup cum se poate observa n figura 4.4. Dup
scrierea acestui text se mai adaug o linie vid n cadrul documentului.
Textul din cadrul unui Range poate fi formatat corespunztor:
wr.Font.Name = "Times New Roman";
wr.Font.Size = 14;
wr.Font.Bold = -1;

din secven se observ c s-a ales fontul Times New Roman de dimensiune
14 i ngroat (Bold).
Pentru a continua cu adugarea de alte texte, la document, trebuie s
repoziionm n mod corespunztor obiectul de tip Range. In cazul
exemplului, se dorete ca noul Range s fie poziionat la sfritul celui
64

curent adic s permit adugarea unui text n continuarea celui care a fost
scris n document. Prin apelul metodei Collapse(), pentru un obiect de tip
Range, se realizeaz generare unei noi poziii care presupune ca poziia de
nceput s fie identic cu cea de sfrit. In funcie de direcia n care se
repoziioneaz domeniul, obiectul Range se poate poziiona la sfritul sau la
nceputul domeniului curent:
wr.Collapse(Word.WdCollapseDirection.wdCollapseEnd);

din apelul metodei se observ c direcia este indicat spre sfritul


documentului adic poziia de nceput a noii zone este identic cu cea de
sfrit a obiectului Range curent. Apelnd metoda InsertAfter() se poate
insera un text dup aceast nou poziie:
wr.InsertAfter("La data: " + DateTime.Now.Date.ToShortDateString()+
"\n");

linia de text adugat include i data sistem i determin trecerea la o nou


linie n document. Dup adugarea textului, el este formatat diferit de primul
text introdus n document:
wr.Font.Name = "Arial";
wr.Font.Size = 10;
wr.Font.Bold = 0; // neingrosat

Alinierea textului n pagin se face, n mod implicit, la stnga. Pentru


a modifica alinierea textului introdus n document se va modifica
proprietatea Alignment care este specific unui paragraf din document. Un
paragraf se termin cnd se introduce caracterul de linie nou n text; dup
care ncepe un nou paragraf. Astfel, se observ n figura 4.5 c textul Stat de
plat este centrat n pagin. Deoarece au fost ntroduse dou linii vide,
nseamn c textul Stat de plat formeaz cel de-al treilea paragraf din
document, care se centreaz prin secvena:
wdoc.Paragraphs[3].Alignment =
Word.WdParagraphAlignment.wdAlignParagraphCenter;

Datele din controlul gv de tip DataGridView s-au exportat, n


documentul Word, ntr-un tabel. Adugarea unui tabel la un document se
65

face prin intermediul unui obiect de tip Range. De aceea, s-a repoziionat
obiectul de tip Range la sfritul celui anterior definit:
wr.Collapse(Word.WdCollapseDirection.wdCollapseEnd);

S-a construit un tabel (ts) avnd un numr de linii identic cu numrul de linii
a controlului DataGridView (gv), n timp ce, la numrul de coloane a
controlului a mai fost adugat una, pentru a nscrie i numrul liniei din
tabel.
Word.Table ts = wr.Tables.Add(wr, gv.RowCount, gv.ColumnCount+1);

Limea coloanelor a fost stabilit n raport de limea paginii (latp) care s-a
calculat pornind de la limea paginii i a marginilor:
float latp = wdoc.PageSetup.PageWidth
(wdoc.PageSetup.RightMargin + wdoc.PageSetup.LeftMargin);

Pentru stabilirea propriu-zis a laimii coloanelor s-a aplicat un procent


spaiului disponibil (latp), astfel:
ts.Columns[1].Width = (float)0.10 * latp;
ts.Columns[2].Width = (float)0.70 * latp;
ts.Columns[3].Width = (float)0.20 * latp;

prima coloan are 10% din laimea total, cea de-a doua coloan are 70% iar
ultima 20%.
Capul de tabel s-a definit prin scrierea textului corespunztor n fiecare
celul a primului rnd. O celul (Cell) conine proprietatea Range prin
intermediul creia se scrie textul n celul:
ts.Cell(1, 1).Range.Text = "Nr. crt.";
ts.Cell(1, 2).Range.Text = gv.Columns[0].HeaderText;
ts.Cell(1, 3).Range.Text = gv.Columns[1].HeaderText;

Pentru a marca mai bine capul de tabel, primului rnd din tabel i s-a asociat
o culoare de fundal (culoarea gri):
ts.Rows[1].Shading.BackgroundPatternColor =
Word.WdColor.wdColorGray15;

Popularea cu date a tabelului s-a realizat n urmtoarea secven iterativ:


for (int i = 0; i < gv.RowCount - 1; i++)
{
ts.Cell(i + 2, 1).Range.Text = (i + 1).ToString();

66

ts.Cell(i + 2, 1).Range.Paragraphs.Alignment =
Word.WdParagraphAlignment.wdAlignParagraphRight;
ts.Cell(i + 2, 2).Range.Text =
gv.Rows[i].Cells[0].Value.ToString();
ts.Cell(i + 2, 3).Range.Text =
gv.Rows[i].Cells[1].Value.ToString();
ts.Cell(i + 2, 3).Range.Paragraphs.Alignment =
Word.WdParagraphAlignment.wdAlignParagraphRight;
}

Tabelul se completeaz linie cu linie, fiecare linie se completeaz celul cu


celul. Se observ c alinierea datelor din coloanele 1 i 3 se face la dreapta
deoarece ele sunt numerice.
Dup popularea cu date, tabelul se formateaz la nivel global n sensul c se
stabilete dimensiunea fontului, i se ngroa (Bold) doar capul de tabel:
ts.Range.Font.Size = 10;
ts.Range.Font.Bold = 0;
ts.Cell(1, 1).Range.Font.Bold = -1;
ts.Cell(1, 2).Range.Font.Bold = -1;
ts.Cell(1, 3).Range.Font.Bold = -1;

Se traseaz liniile de demarcaie (Borders) a celulelor tabelului:


ts.Borders.Enable = 1;

Fereastra aplicaiei Word care include i documentul nou construit devine


vizibil utilizatorului:
wapl.Visible = true;

iar acesta poate modifica, salva sau tiprii documentul.


Realizarea interaciunii cu documente Excel se va face folosind clase
din ierarhia EOM (Excel Object Model). Se va avea n vedere c trebuie s
se construiasc o instan a unei noi aplicaii Excel, aceasta poate conine o
colecie de documente care la rndul lor conin colecii de foi de calcul.
Accesul la datele efective ale unei foi de calcul se realizeaz prin obiecte de
tip Range sau prin obiecte de tip celul (Cell).
Ca exemplu, se consider un document Excel care este structurat
astfel nct s poat realiza calculul unei serii de date pornind de la o valoare
iniial i de la un procent de cretere a valorii respective, care se va aplica
anual, valorii aferente anului precedent. Perioada de timp, exprimat n ani,
67

va constitui un alt parametru de intrare al modelului. Documentul Excel, se


afl n fiierul sablon.xlsx i este folosit ca motor de calcul pentru a obine
rezultatele dorite. Astfel, foaia de calcul este organizat n modul urmtor:
- celule care conin date primare; valorile introduse n aceste celule
reprezint parametrii de intrare ai modelului; i
- celule care conin formule pentru a genera rezultatul, valorile acestor
celule reprezint parametrii de ieire ai modelului.
Foaia de calcul este prezentat n figura 4.6 iar celulele care au culoarea de
fundal gri sunt celule care conin valori elementare ce reprezint parametrii
de intrare ai modelului:
- perioada pentru care se face estimarea (C1);
- procentul de cretere anual (C2);
- anul iniial (E4);
- valoarea iniial (F4).
In funcie de perioad, se completeaz celulele E5, E6, .... i celulele F6, F7,
.... . Pentru diversitate, prin programare, se va nscrie formula n celula E5
dup care ea se va copia n toate celulele urmtoare, n concordan cu
perioada, pentru a genera anii seriei de timp, n timp ce pentru a estima
valorile, n celula F5 s-a introdus, n document, formula de calcul urmnd ca
prin programare aceasta s fie copiat i n celelalte celule. Formula din
celula F5 realizeaz o cretere a valorii iniiale cu procentul specificat prin
parametrul de intrare existent n celula C2 i are forma: =F4+F4*$C$2/100.
Aplicaia care controleaz aplicaia Excel este de tip Windows Forms i are
controlale de tip TextBox pentru a se putea introduce parametrii modelului
iar pentru vizualizarea rezultatelor s-a construit un control de tip
DataGridView dupa cum se poate observa n figura 4.7.

68

Figura 4.6 Foaie de calcul

Figura 4.7 Forma aplicaiei principale

Folosirea modelului EOM impune adaugarea referinei:


Microsoft.Office.Interop.Excel

la proiect i totodat utilizarea domeniului corespunztor ceea ce presupune


adugarea n codul surs a declaraiei:
using Excel = Microsoft.Office.Interop.Excel;

In cadrul clasei forma (Form1) se declar urmtoarele variabile:


Excel.Application eapl; // pentru a referi obiectul aplicaie Excel
Excel.Workbook wb; // pentru a referi obiectul document Excel
Excel.Worksheet sh; // pentru a referi o foaie de calcul din document

69

pentru a fi vizibile i utilizabile din orice metod a clasei form.


La ncrcarea formei se realizeaz deschiderea documentului sablon.xlsx i
valorile din celulele n care se stocheaz parametrii de intrare sunt
vizualizate n controalele de tip TextBox corespunztoare:
//se
eapl
//n
wb =

construiete o nou instan a unei aplicaii Excel


= new Excel.Application();
cadrul aplicaiei se deschide documentul
eapl.Workbooks.Open
(@"d:\post_doc\documentatie\aplicatii\VSTO\Sablon.xlsx");
//se refer prima foie de calcul din document (Sheet 1)
sh = wb.Sheets[1] as Excel.Worksheet;
//se ncarc n controale valorile existente n celulele indicate
vi.Text = ((double)sh.get_Range("f4").Value).ToString("f");
ani.Text =((int)sh.get_Range("e4").Value).ToString();
ca.Text = ((int)sh.get_Range("c2").Value).ToString();
per.Text = ((int)sh.get_Range("c1").Value).ToString();

unde, vi, ani, ca, per sunt numele controalelor de tip TextBox din forma
ilustrat n figura 4.7.
Se observ c referirea unei celule se face prin aplelul metodei get_Range
care returneaz un obiect de tip Range mapat pe un domeniu format dintr-o
singur celul. Stilul folosit pentru a adresa celula este de a indica coloana
printr-o liter iar linia printr-un numr, de exemplu f4. Prin intermediul
proprietii Value se acceseaz valoarea celulei care se convertete la un tip
numeric, pentru c acele celule conin valori numerice, dup care ea se
convertete la ir de caractere pentru a fi ncrcat n controlul de tip
TextBox.
Utilizatorul aplicaiei poate s modifice valorile iniiale prin editarea
elementelor coninute n controalele de tip TextBox dup care, pentru a
genera rezultatele aferente noului set de valori, se apas pe butonul
Genereaza Rezultate. La apsarea pe acest buton se realizeaz urmtoarele
procesri:
- se rescriu n celulele corespunztoare, din Excel, noile valori
introduse:
int t,i
sh.get_Range("f4").Value = Convert.ToDouble(vi.Text);
sh.get_Range("e4").Value = Convert.ToInt32(ani.Text);

70

sh.get_Range("c2").Value = Convert.ToInt32(ca.Text);
sh.get_Range("c1").Value = t = Convert.ToInt32(per.Text);

se genereaz anii seriei de timp (se pornete de la anul iniial i de la


perioada analizat)
Dup cum se poate observa din figura 4.6, n celula e4, se stocheaz
valoarea anului iniial. De aceea, pentru a genera anii perioadei analizate, pe
coloan, n celula e5 se va nscrie o formul care permite generarea valorii
celulei prin adunarea cifrei 1 la valoarea celulei anterioare:
sh.get_Range("e5").Formula = "=e4+1";

astfel, prin intermediul proprietii Formula, celulelor unui domeniu (Range)


li se asociaz formule.
Pentru a genera anii ntregii perioade, formula existent n celula e5 se
copiaz n toate celulele domeniului. Un domeniu se adreseaz prin dou
celule: cea care marcheaz colul stnga sus i cea care marcheaz colul
dreapta jos. In cazul n care domeniul este constituit dintr-o singur celul
atunci metodei get_Range i se furnizeaz doar un singur parametru care
indic celula respectiv. Domeniul n care se va copia formula, existent n
celula e5, se stabilete dinamic n funcie de numrul de ani ai perioadei de
referin. Astfel, domeniul este marcat de celula e5 i de celula e(4+t-1),
unde, t reprezint perioada:
sh.get_Range("e5").Copy(sh.get_Range
("e5", "e" + (4 + t - 1).ToString()));

- generarea valorilor seriei de timp


In cadrul documentului care joac rol de ablon, n celula f5 este deja scris
formula de cretere a valorii iniiale cu procentul specificat aa c, pentru a
genera valorile seriei se va face doar copierea formulei n domeniul indicat:
sh.get_Range("f5").Copy(sh.get_Range
("f5", "f" + (4 + t - 1).ToString()));

ncrcarea seriei de timp din foaia de calcul n controlul de tip


DataGridView (gv) din forma aplicaiei
In funcie de numrul de ani luai n considerare, se stabilete numrul de
coloane a gridului:
71

for (i = 0; i < t; i++)


{
gv.Columns.Add("c" + (i + 1).ToString(),
((int)sh.get_Range("e" + (4 + i).ToString()).Value).ToString());
gv.Columns[i].HeaderCell.Style.Alignment =
DataGridViewContentAlignment.MiddleCenter;
}

Fiecare coloan va avea ca text, n header, anul care va fi centrat pe limea


coloanei.
Valorile propriu-zise, se vor aduga n grid, din celulele domeniului
corespunztor din foia de calcul Excel i se vor alinia la dreapta:
gv.Rows.Add();
for (i = 0; i < t; i++)
{
gv.Rows[0].Cells[i].Value =
((double)sh.get_Range("f" + (4 + i).ToString()).Value).ToString("f");
gv.Rows[0].Cells[i].Style.Alignment =
DataGridViewContentAlignment.MiddleRight;
}

In figura 4.8 se prezint forma aplicaiei pentru care s-a generat o serie de
valori pentru un orizont de 5 ani.
In cazul n care utilizatorul dorete s vizualizeze i coninutul foii de calcul,
atunci se poate executa i instruciunea: eapl.Visible = true; ce determin
vizualizarea ferestrei aplicaiei Excel cu seria de timp generat, ca n figura
4.9.

Figura 4.8 Generarea seriei de timp

72

Figura 4.9 Foaia de calcul n care s-a generat seria de timp

nchiderea aplicaiei trebuie s realizeze nchiderea explicit a


instanei aplicaiei Excel altfel ea va ramne deschis n sistem lucru
care se poate observa n fereastra aplicaiei Task Manager. Inainte de
nchiderea propriu-zis a aplicaiei, utilizatorul trebuie s nchid
documentul (fiierul sablon.xlsx) lucru care se poate face, fie cu
salvarea n document a datelor, fie fr salvarea lor:

bool save = false;


if (MessageBox.Show("Doriti salvarea documentului?", "Salvati?",
MessageBoxButtons.YesNo, MessageBoxIcon.Question) ==
DialogResult.Yes)
{
save = true;
}
//inchiderea documentului
wb.Close(save);
//inchiderea aplicaiei Excel
eapl.Quit();
//inchiderea aplicaiei printe
Application.Exit();

Tot n aceeai idee de dezvoltare se propune construirea unei aplicaii


care s construiasc o prezentare PowerPoint pe care apoi s o treac n
regim SlideShow cu vizualizarea slide-urilor dinamic la un interval de 3
secunde. Construirea prezentrii se realizeaz dintr-o aplicaie de tip
Windows Forms care permite construirea a dou tipuri de slide-uri:

73

A. unul format din dou obiecte care conin text, unul fiind titlul slideului i cellalt cu coninutul propriu-zis;
B. unul care nu are nici un element predefinit (Blank Slide), elementele
vor fi construite pe slide la momentul execuiei dup cum urmeaz:
un titlu (element de tip TexBox) i o imagine (element de tip Picture)
care va afia o imagine preluat dintr-un fiier imagine.
Pe forma aplicaiei se afl butonul New PowerPoint care instaniaz aplicaia
Power Point i creeaz o nou prezentare. Butoanele Adauga Slide adaug
slide-uri de tipul asociat slide-ului iar butonul Vizualizare trece prezentarea
n regim SlideShow i pornete derularea prezentrii. Forma aplicaiei este
prezentat n figura 4.10, completat cu informaii care constituie coninutul
prezentrii format din dou slide-uri.

Figura 4.10 Forma aplicaiei ce genereaz o prezentare PowerPoint

Mai nti se apasa butonul New PowerPoint care instaniaz o aplicaie


PowerPoint i construiete o nou prezentare, dup care se vor aduga slideuri. Apasnd pe butonul Adaug Slide din grupul Slide Text se va aduga la
prezentare slide-ul ce conine elemente de prezentare bazate pe text iar daca
se apas pe butonul de la grupul Slide Imagine se va aduga la prezentare
slide-ul ce conine titlul i imaginea selectat de pe disc i care este
previzualizat n form. Prezentarea construit este vizualizat n figura
4.11.
Din punct de vedere al implementrii la aplicaia de generare a
prezentrii s-au adugat referine ctre Microsoft.Office.Interop.PowerPoint
i ctre Office iar n codul surs:
using PP = Microsoft.Office.Interop.PowerPoint;
using Office = Microsoft.Office.Core;

In clasa Form1 s-au adugat explicit variabilele:


PP.Application papl;

74

PP.Presentation pprs;
PP.Slide pslide;
string calea; //stocheaz fisierul ce contine imaginea

Figura 4.11 Prezentarea PowerPoint generat

In constructorul clasei forma se instaniaz aplicaia PowerPoint i se


atribuie null la variabila calea.
public Form1()
{
InitializeComponent();
papl = new PP.Application();
calea = null;
}

La click pe butonul New PowerPoint se construiete o nou prezentare i


aplicaia PowerPoint devine vizibil:
private void button1_Click(object sender, EventArgs e)
{
pprs = papl.Presentations.Add(Office.MsoTriState.msoTrue);
}

La click pe butonul Browse se deschide o fereastr de dialog de tip


OpenFileDialog care permite utilizatorului s aleag fiierul ce conine
imaginea care urmeaz a fi inclus n prezentare. Imaginea aleas va fi
afiat i n form n controlul pbx de tip PictureBox iar numele fiierului cu
tot cu cale se va afia n controlul img_fis de tip TextBox.
private void button4_Click(object sender, EventArgs e)
{

75

OpenFileDialog fd = new OpenFileDialog();


fd.InitialDirectory = "d:\\";
fd.Filter = "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|
All files (*.*)|*.*";
fd.FilterIndex = 1;
fd.RestoreDirectory = true;
if (fd.ShowDialog() == DialogResult.OK)
{
img_fis.Text = calea = fd.FileName;
Bitmap img = new Bitmap(fd.FileName);
pbx.Image = img;
}
}

Construirea propriu-zis a slide-urilor se face la apsarea pe butoanele


Adaug Slide. Codul asociat celui care genereaz slide-uri numai cu
controale de tip text are forma:
private void button2_Click(object sender, EventArgs e)
{
int nrs = pprs.Slides.Count;
// se stabileste un tip de slide adica cel care are doua textbox-uri
// unul pentru titlu si altul pentru continut (ppLayoutTitle)
PP.CustomLayout cl =
pprs.SlideMaster.CustomLayouts[PP.PpSlideLayout.ppLayoutTitle];
// se adauga un slide de acest tip la prezentare
pslide = pprs.Slides.AddSlide(nrs+1, cl);
// se seteaza textul asociat titlului din controlul (titlu) de tip
// textbox de pe forma aplicatiei
pslide.Shapes.Title.TextFrame.TextRange.Text = titlu.Text;
// textul pentru continutul propriu-zis se preia din controlul stitlu
// de tip textbox de pe forma aplicatiei
pslide.Shapes[2].TextFrame.TextRange.Text = stitlu.Text;
// se aliniaza textul din cea de-a doua form la stanga
pslide.Shapes[2].TextFrame.TextRange.ParagraphFormat.Alignment =
PP.PpParagraphAlignment.ppAlignLeft;
}

Butonul Adaug Slide care construiete un slide ce conine titlul i imaginea


pornete cu generarea unui slide fr nici un element dup care se
construiesc elementele grafice n care se va afia titlul i apoi imaginea:
private void button5_Click(object sender, EventArgs e)
{
int nrs = pprs.Slides.Count;
//tip de slide: blank slide (valoarea 7)
PP.CustomLayout cl = pprs.SlideMaster.CustomLayouts[7];
//adaugare slide de acest tip
pslide = pprs.Slides.AddSlide(nrs + 1, cl);
//preluarea latime si inaltime slide
float lat = pslide.CustomLayout.Width;

76

float inalt = pslide.CustomLayout.Height;


//adaugare textbox la slide cu localizare si directie de scriere
pslide.Shapes.AddTextbox(
Office.MsoTextOrientation.msoTextOrientationHorizontal,
10, 10, lat-20, 60);
//setare text pentru titlu din controlul s2titlu de pe forma
pslide.Shapes[1].TextFrame.TextRange.Text = s2titlu.Text;
pslide.Shapes[1].TextFrame.TextRange.Font.Size = 48;
pslide.Shapes[1].TextFrame.TextRange.ParagraphFormat.Alignment =
PP.PpParagraphAlignment.ppAlignCenter;
//adaugare imagine pe slide cu localizare si dimensionare
pslide.Shapes.AddPicture(calea, Office.MsoTriState.msoCTrue,
Office.MsoTriState.msoFalse, 10, 80, lat - 20, inalt-90);
}

Pentru vizualizarea prezentrii se apas pe butonul Vizualizare de pe form


ce are asociat codul:
private void button3_Click(object sender, EventArgs e)
{
//stabilirea domeniului de slide-uri (toate)
PP.SlideRange ssr = pprs.Slides.Range();
//stabilirea caracteristicilor de tranzitie slide-uri
PP.SlideShowTransition sst = ssr.SlideShowTransition;
//derularea sa se realizeze in timp
sst.AdvanceOnTime = Office.MsoTriState.msoTrue;
//intervalul dintre doua slide-uri de 3 secunde
sst.AdvanceTime = 3;
//efect de tranzitie slide-uri
sst.EntryEffect = PP.PpEntryEffect.ppEffectBlindsVertical;
//trecerea n modul SlideShow
PP.SlideShowSettings ssp = pprs.SlideShowSettings;
//stabilirea slide de inceput a vizualizarii
ssp.StartingSlide = 1;
//stabilirea slide de sfarsit
ssp.EndingSlide = pprs.Slides.Count;
//vizualizare slide-uri in mod slideshow
ssp.Run();
}

4.3 Dezvoltarea de extensii pentru aplicaiile Office


Personalizarea prelucrrilor n cadrul aplicaiilor Office se realizeaz
prin construirea de componente software care se ataeaz la cele oferite de
aplicaia de baz. Aceste componente poart denumirea de add-in i necesit
asocierea de elemente de interfa cu utilizatorul pentru ca acesta s poat
77

declana operaiile implementate. In acest subcapitol, se prezint modul n


care se construiesc astfel de module i de asemenea modul de organizare i
de interaciune cu ele din perspectiva versiunii 2007 a pachetului Office.
Incepnd cu versiunea Office 2007, aplicaiile Word, Excel etc folosesc un
nou element de interfa cu utilizatorul, mai precis ribbon-ul (panglica) care
substituie meniul aplicaiei. Acesta cuprinde mai multe grupuri de elemente
de interaciune, adic ceea ce la versiunile anterioare erau barele de
instrumente, care conin diverse controale, specializate, n funcie de natura
interaciunii cu utilizatorul.
Modalitatea oferit de aceste componente, n vederea personalizrii
procesrilor, presupune ca soluia s fie disponibil la nivelul aplicaiei. Cu
alte cuvinte, aplicaia Office conine componenta care poate fi executat pe
datele oricrui document se ncarc n aplicaie.
Pentru exemplificare, se va construi un grup de operaii care va
include un buton folosit pentru a declana efectuarea sumei elementelor de
pe diagonala principal a unei matrice de valori numerice. Matricea de valori
se va marca prin selecia unui domeniu de celule dintr-o foaie de calcul a
unui document xlsx. In aceste condiii, se poate deduce faptul c, se va
construi o component add-in pentru aplicaia Excel.
A. Se va construi un proiect n Visual C# din categoria Office 2007 de
tipul Excel 2007 Add-in avnd numele Op_matrice dup cum se
ilustreaz n figura 4.12.

78

Figura 4.12 Tip de proiect Add-in pentru Excel

A. Dup construirea proiectului, n fereastra Solution Explorer se d


click dreapta pe numele proiectului i se adaug un nou element la
proiect (Add/New Item) i va apare fereastra ilustrat n figura 4.13.

Figura 4.13 Adugarea unui nou element la proiect

La proiect se va aduga un nou element de tip panglic - Ribbon (Visual


Designer), pe care se vor insera elementele de interfa, mai precis, grupul
de operaii va conine butonul ce va declana prelucrarea. Dup cum se
79

observ n figura 4.14, dezvoltatorul are posibilitatea s-i personalizeze


elementele de interaciune din cadrul panglicii. Astfel, grupul de controale
denumit group1 poate fi personalizat prin intermediul proprietii Label
dndu-i un alt nume (Operaii matriceale). Implicit, grupul nu are incluse
controale ns ele pot fi ulterior adugate din grupul de controale care se pot
ataa panglicilor a se observa fereastra Toolbox din figura 4.14. Din grupul
de controale se adaug n grupul de operaii un control de tip Button (prin
drag and drop), iar proprietatea Label a acestuia conine textul ce apare pe
buton. Aceast proprietate se va modifica astfel nct, pe buton s apar
textul: Suma pe diagonala.

Figura 4.14 Proiectarea panglicii

Dup efectuarea acestor operaii, se va executa proiectul, care va


determina lansarea n execuia a aplicaiei Excel. In cadul aplicaiei Excel, se
alege panglica Add-Ins n cadrul creia se observ i grupul de operaii
construit anterior i care poart numele Operaii matriceale, dup cum se
observ n figura 4.15.

Figura 4.15 Personalizarea panglicii Add-Ins

80

A. Definirea funcionalitii butonului creat se realizeaz prin tratarea


evenimentului Click.
Acest lucru impune adugarea metodei de tratare a evenimentului Click n
clasa Ribbon1. In fiierul Ribbon1.cs se vor aduga declaraiile:
using System.Windows.Forms;
using Excel = Microsoft.Office.Interop.Excel;

pentru a putea lucra cu clase din Windows Forms cum ar fi, de exemplu,
MessageBox pentru afiarea de mesaje i pentru a putea folosi clase din
EOM.
In clasa Ribbon1 se va mai declara o variabil static de tip object care se va
iniializa cu Type.Missing: static object tm = Type.Missing; Aceasta
variabil se folosete pentru a furniza parametrii care nu sunt obligatoriu de
transmis n cadrul metodelor apelate.
Spre deosebire de modalitatea de dezvoltare a aplicaiilor bazate pe Office,
prezentat la punctul 4.2, n acest caz, exist o instan a aplicaiei Excel, un
document i o foaie de calcul. Cu alte cuvinte, aceste obiecte trebuie preluate
i utilizate n aplicaie:
Excel.Application eapl = Globals.ThisAddIn.Application;
Excel.Workbook wb = eapl.Workbooks[1];
Excel.Worksheet sh = wb.Sheets[1] as Excel.Worksheet;

In cadrul proiectului s-a generat clasa Globals care conine proprietatea


ThisAddIn care, la rndul ei, conine instana curent a aplicaiei Excel.
Pornind de la obiectul aplicaie, se refer documentul (Workbook) i din
cadrul documentului foaia de calcul (Worksheet).
Efectuarea operaiei de nsumare a valorilor de pe diagonala principal a
unei matrice impune selectarea domeniului de celule, din foaia de calcul,
care definete matricea. Obiectul Range rezultat prin selecie se obine astfel:
Excel.Range rs = eapl.Selection as Excel.Range;

Pentru acest obiect de tip Range se preiau informaii cu privire la numrul de


linii i numrul de coloane:
int m = rs.Rows.Count, n = rs.Columns.Count, i;

variabila i se folosete drept contor.


In continuare, se verific dac matricea este ptratic:
81

if (m != n)
{
MessageBox.Show("Matricea nu este patratica");
return;
}

In cazul n care este ptratic se declar o variabil n care s se memoreze


suma elementelor de pe diagonala principal a matricei: double s = 0;
Se itereaz elementele de pe diagonala principal pentru a le aduna. In cazul
n care exist celule care nu conin valori numerice se arunc o excepie i se
termin procesarea:
for (i = 1; i <= n; i++)
{
try
{
s += (double)((Excel.Range)rs.Cells[i, i]).Value;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Eroare",
MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}

Se observ c o celu individual din domeniu se refer prin colecia Cells,


adresarea fcndu-se prin furnizarea liniei i a coloanei. O celul astfel
adresat ntoarce tot un obiect de tip Range care prin proprietatea Value
ntoarce valoarea stocat n celula respectiv.
Suma elementelor de pe diagonala principal va fi stocat, n foaia de calcul,
n celula care urmeaz ultimei celule ce formeaz diagonala domeniului. In
figura 4.16 se poate observa domeniul de celule selectat iar dup apsarea pe
butonul Suma pe diagonala n celula E6, care continu diagonala, s-a nscris
rezultatul.
Un domeniu se refer furniznd celula din colul stnga sus i celula din
colul dreapta jos. O celul a unei foi de calcul se indic, n modul cel mai
obinuit, prin furnizarea coloanei prin liter (litere) i prin furnizarea liniei
prin numrul ei, de exemplu E6. Un alt stil de a referi o celul const n a
furniza linia i coloana prin numere, de exemplu R6C5, care refer tot celula
82

E6. In contextul aplicaiei, intereseaz care este ultima celul (dreapta jos) a
domeniului pentru a putea adresa celula urmtoare n vederea nscrierii
rezultatului operaiei.

Figura 4.16 Efectuarea sumei pe diagonal cu nscrierea rezultatului

Prin secvena:
string adresa = rs.get_Address(tm, tm, Excel.XlReferenceStyle.xlR1C1);

se obine n irul adresa, adresa domeniului selectat (rs) n stilul rnd coloan (R1C1). In exemplul prezentat n figura 4.16 irul adresa are
valoarea: R3C2:R5C4. Rezultatul operaiei se va nscrie n celula urmtoare
pe diagonal, adic n celula R6C5. Pentru a calcula celula urmtoare pe
diagonal s-a definit metoda get_celula_dest care primete irul adresa i
doi ntregi, prin referin, cu rol de ieire, care vor conine, dup apel,
numrul rndului i a coloanei unde se va nscrie rezultatul:
int a = 0, b = 0;
get_celula_dest(adresa, ref a, ref b);

Obinerea domeniului, prin metoda deja folosit, get_Range, folosete pentru


a marca domeniul numai stilul de adresare cu liter i cifr (E6). Pentru a
referi domeniul (n exemplul prezentat este vorba de o celul), n stilul
numr rnd, numr coloan se folosete construcia:
sh.Range[sh.Cells[a, b], sh.Cells[a, b]]

care returneaz un obiect de tip Range furniznd celula din colul stnga sus
dreapta jos prin colecia Cells care permite referirea celulei propriu-zise
83

prin indicarea numrului liniei i a coloanei. Inscrierea propriu-zis a valorii


sumei n celul se face:
sh.Range[sh.Cells[a, b], sh.Cells[a, b]].Value = s;

Metoda get_celula_dest are ca scop identificarea celulei n care se


va stoca rezultatul operaiei. Ca parmetru de intrare primete irul de
caractere care conine adresa domeniului selectat iar parametrii de ieire sunt
furnizai sub form de referin i ntorc, sub forma a dou numere ntregi,
linia i coloana n care se va nscrie rezultatul. Adresa domeniului se
furnizeaz n stilul numr rnd, numr coloan, irul ce conine adresa este
parsat astfel nct s se identifice numrul liniei i a coloanei pentru celula
dreapta jos a domeniului selectat. In prima etap se sparge irul n dou
subiruri, delimitatorul fiind caracterul : apoi se proceseaz al doilea subir
care refer celula din partea dreapta jos a domeniului. In cea de-a doua etapa
se identific subirurile delimitate de caracterele R i C care furnizeaz
numrul liniei i a coloanei care se convertesc din ir de caractere n numere
ntregi i se incrementeaz pentru a referi celula ce urmeaz, pe diagonal,
domeniului selectat, celul n care se va nscrie rezultatul operaiei.
private void get_celula_dest(string sir, ref int x, ref int y)
{
string[] vs = sir.Split(new char[] { ':' },
StringSplitOptions.RemoveEmptyEntries);
string[] snc = vs[1].Split(new char[] { 'R', 'C' },
StringSplitOptions.RemoveEmptyEntries);
x = Convert.ToInt32(snc[0]) + 1;
y = Convert.ToInt32(snc[1]) + 1;
}

4.4 Ataarea de cod documentelor Office


La punctul 4.3 a fost prezentat o modalitate de a aduga o procesare
personalizat unei aplicaii Office care permite efectuarea operaiei asupra
datelor unui document. In cadrul acestui subcapitol se vor definii operaii
personalizate care se vor putea efectua numai asupra datelor unui document
Office bine precizat. Cu alte cuvinte, n primul caz este vorba de
84

personalizare la nivel de aplicaie Office n timp ce, n al doilea caz este


vorba de personalizare la nivel de document.
Datorit faptului c personalizarea procesrii se face n acest caz la
nivel de document atunci tot la nivelul documentului se va defini i ncrca
interfaa cu utilizatorul pentru a putea declana aceste operaii. In cazul
personalizrii procesrii la nivelul aplicaiei s-a putut observa c interfaa a
fost construit la nivelul aplicaiei Office (sub forma unui grup de operaii
dintr-o panglic).
Exemplificarea unei astfel de aplicaii bazate pe Office se va face
atasnd cod unui document Word 2007 n forma docx. Astfel, se construiete
un ablon de document n care se vor insera controale specifice pentru un
document Word pentru ca utilizatorul s-i poat personaliza coninutul
documentului. Se va ataa documentului o fereastr de tip Document Actions
care va conine dou butoane cu funcionalitate personalizat: butonul
Adauga date in tabela are ca scop preluarea datelor introduse n controalele
inserate n document i stocarea lor ntr-o tabel a unei baz de date Access,
n timp ce, butonul Incarca date in document se va folosi pentru ca
utilizatorul s vizualizeze datele stocate n tabela Persoane, din baza de date,
sub form tabelar, cu posibilitatea de a selecta un tuplu pentru a retrimite
datele respective n documentul Word. Aceast modalitate de lucru combin
facilitatea de machetare, ce permite utilizatorului sa-i personalizeze
coninutul documentului, cu formatarea textului n cadrul unui document,
atribut specific aplicaiilor care realizeaz editarea de texte. In practic,
astfel de aplicaii sunt utile mai ales n domeniile unde se construiesc fie
pentru diverse entiti cum ar fi, de exemplu, fia de nscriere a unui cursant
la o coal de oferi care are o parte fix, nemodificabil de la un cursant la
altul ct i o parte ce depinde de datele personale ale individului, are un
format impus, trebuie s fie uor de listat pe suport hrtie i necesit
includerea unor elemente neconvenionale, cum ar fi poza cursantului.
Asocierea de cod unui astfel de document permite transformarea acestuia
dintr-un document static ntr-un document dinamic i astfel, se ofer
85

utilizatorului posibilitatea s implementeze funcionaliti specifice. In


exemplul descris anterior se pot arhiva documentele prin stocarea datelor
specifice fiecrui cursant ntr-o baz de date, partea fix a documentului
pastrndu-se n fiierul docx.
Dezvoltarea unei astfel de aplicaii n Visual Studio 2010 presupune
construirea unui proiect (WordDocument1) bazat pe Office 2007 de tipul
Word 2007 Document, dup cum se ilustreaz n figura 4.17.

Figura 4.17 Construirea proiectului tip Word 2007 Document

Deoarece aplicaia se ataeaz unui document atunci n pasul urmtor fie se


indic documentul cruia i se ataeaz codul, fie se construiete un
document nou prin interfaa Visual Studio (figura 4.18).

Figura 4.18 Alegerea documentului

86

In exemplu, s-a ales varianta construirii unui nou document


(WordDocument1.docx) n interfaa Visual Studio. Astfel, n modul
proiectare, va apare interfaa aplicaiei Word care permite editarea noului
document dup cum se poate observa n figura 4.19. Documentul este
construit sub forma unui ablon n sensul c are o parte fix reprezentat prin
texte obinuite i o parte ce se va personaliza cu informaii despre persoane
i care este reprezentat, n document, prin controale adecvate pentru
interaciune. Pentru simplificare, n exemplu, se propune un ablon de
document pentru descrierea unei persoane prin: nume, sex i salariu. Acestor
caracteristici li s-au asociat controale din grupul Word Controls, existent n
fereastra ToolBox, n vederea editrii datele dup cum urmeaz: pentru
cmpurile nume i salariu s-au folosit controale de tip
PlainTextContentControl pentru a se putea edita valorile iar pentru sex s-a
utilizat un control de tip DropDownListContentControl pentru a alege
valoarea din mai multe variante. Pentru lizibilitate, n document, culoarea de
fundal a controalelor este gri (figura 4.19). In mod vizual, controalelor li sau modificat proprietile:
- controlul pentru introducerea numelui a fost denumit cnume, prin
schimbarea valorii proprietii Name, prin proprietatea Text a fost
schimbat irul de caractere afiat n control (Vasile);
- controlul pentru alegerea valorii cmpului sex poart denumirea csx,
prin intermediul proprietii DropDownListEntries a fost definit
colecia de valori (Masculin, Feminin), prin intermediul proprietii
PlaceholderText s-a definit irul care apare vizualizat n control pn
la prima utilizare a lui (Alege o optiune);
- controlul pentru introducerea salariului a fost denumit csal;
Toate controalele au proprietatea LockContentControl cu valoarea true
pentru ca utilizatorul s nu poat terge controalele din document, ci s
opereze doar asupra coninutului lor.
Documentul WordDocument1.docx are asociat clasa ThisDocument
care permite programatorului s extind funcionalitatea documentului i s
87

rspund la evenimente declanate n lucrul cu documentul. Aceast clas


conine n mod implicit definiiile metodelor: ThisDocument_Startup care se
apeleaz la evenimentul de ncrcare a documentului n aplicaia Word i
ThisDocument_Shutdown pe evenimentul de nchidere document.

Figura 4.19 Editarea noului document

Datele care se vor introduce n controalele documentului se vor


prelua i se vor stoca n baza de date Access date_doc.accbd mai precis, n
tabela Persoane care are urmtoarea structur:
- ID, de tip AutoNumber care joac rol de cheie primar;
- nume de tip ir de caractere;
- sex de tip ir de caractere avnd marimea de un caracter;
- sal de tip numeric (valori ntregi).
Declanarea operaiilor de stocare a datelor n baza de date i de
ncrcare a ablonului cu date din baza de date se face prin apsarea a dou
butoane construite special n acest scop. In general, controalele de utilizator
se pot construi i vizualiza pe o form care apare odat cu documentul n
aplicaia Word i se numete Document Actions. Construirea acestei forme
88

ct i iniializarea controalelor incluse n documentul ablon se realizeaz pe


evenimentul de ncrcare a documentului (Startup). In cadrul clasei
ThisDocument se fac declaraiile:
// doua obiecte de tip buton
Button badd, bincarcare;
// sir de conexiune la sursa de date
string sircc = @"Provider=Microsoft.ACE.OLEDB.12.0;
Data Source=D:\post_doc\documentatie\aplicatii\date_doc.accdb";

Metoda care se apleleaz ca rspuns la evenimentul de ncrcare a


documentului este definit dup cum urmeaz:
private void ThisDocument_Startup(object sender, System.EventArgs e)
{
// initializare proprietati aferente controalelor Word
cnume.Text = "Aici introduce numele!";
csal.Text = "0";
// construirea butonului pentru a adauga datele din document
// in baza de date
badd = new Button();
// stabilirea textului ce va apare pe buton
badd.Text = "Adauga date in tabela";
// asocierea metodei care se va apela ca urmare a evenimentului Click
badd.Click += new EventHandler(badd_Click);
// adaugarea controlului pe forma asociata documentului
Globals.ThisDocument.ActionsPane.Controls.Add(badd);
// construirea butonului pentru a incarca date din
// baza de date in document
bincarcare = new Button();
// stabilirea textului ce va apare pe buton
bincarcare.Text = "Incarca date in document";
// asocierea metodei care se va apela ca urmare a evenimentului Click
bincarcare.Click += new EventHandler(bincarcare_Click);
// adaugarea controlului pe forma asociata documentului
Globals.ThisDocument.ActionsPane.Controls.Add(bincarcare);
}

Rularea aplicaiei determin ncrcarea documentului ablon, n Word, dup


cum se observ n figura 4.20. Se observ c, n controalele aferente numelui
i salariului s-au nscris valorile de iniializare n concordan cu codul
metodei ThisDocument_Startup. Pe de alt parte, se observ c, n partea din
dreapta a documentului a aprut forma (Document Actions) cu cele dou
butoane definite n metoda descris anterior. Fereastra Document Actions se

89

poate deschide / nchide apasnd butonul Document Actions ce ine de


grupul Show/Hide din panglica View.

Figura 4.20 Sablon de document cu interfaa asociat

Dup completarea cu date a controalelor din document (cele cu fundal gri),


dac se apas pe butonul Adauga date in tabela, datele vor fi adugate la
cele existente n tabela Persoane din baza de date date_doc.accdb. Pentru
ntroducerea cmpului sex utilizatorul trebuie s aleag o opiune (Masculin
sau Feminin). In control este afiat textul care joac rol de etichet i poate fi
modificat prin proprietatea Placeholder Text. Acest text se pstreaz vizibil
doar pn la prima utilizare a controlului dup care va apare n control doar
ultima opiune selectat. In cazul n care utilizatorul nu selecteaz nici o
opiune, el este notificat s aleag ceva din list pentru a putea aduga datele
n baza de date. In figura 4.21 se prezint i opiunile existente n list, ce
apar doar cnd se interacioneaz cu controlul.

Figura 4.21 Alegerea opiunilor

90

Codul care se execut la declanarea evenimentului Click pe butonul Adauga


date in tabela se afl n metoda badd_Click:
void badd_Click(object sender, EventArgs e)
{
// daca nu s-a ales nici o optiune,
// utilizatorul este atentionat sa o faca
if (csx.Text == string.Empty)
MessageBox.Show("Alegeti o valoare pentru sex!!!");
else
{
// se construieste un obiect de tip OleDbConnection
// care face conexiunea la sursa de date
OleDbConnection con = new OleDbConnection(sircc);
// formarea irului dintr-un singur caracter n urma optiunii
// introduse pentru sexul persoanei
string ssx = (csx.Text=="Masculin") ? "M" : "F";
// construirea sirului ce contine comanda de inserare
// a tuplului n tabela Persoane
string sinsert = @"INSERT INTO Persoane(nume, sex, sal) VALUES
('" + cnume.Text + "','" + ssx + "'," + csal.Text + ")";
//deschiderea conexiunii
con.Open();
//construirea obiectului comanda
OleDbCommand cinsert = new OleDbCommand(sinsert, con);
//executia comenzii de inserare
cinsert.ExecuteNonQuery();
//inchiderea conexiunii
con.Close();
//mesaj de confirmare pentru adaugarea datelor in tabela
MessageBox.Show("Date adaugate in tabela!!!");
}
}

Preluarea datelor din baza de date i ncrcarea lor n documentul ablon se


realizeaz prin apsarea butonului Incarca date in document care va
determina apariia unei ferestre de dialog n care se va afia un
DataGridView din care utilizatorul i va putea selecta tuplul dorit. Primul
pas n elaborarea acestei funcionaliti const n a construi o nou forma la
proiect (Project/Add New Item) i se selecteaz tipul de element - Windows
Form, eventual se asociaz un nou nume i se apas butonul Add. In cazul
exemplului prezentat a fost pstrat numele implicit pentru form (Form1).
Vizual, formei i se adaug elemente de interaciune cu utilizatorul. Astfel, se
adaug un control de tip DataGridView (gv) care se va lega de tabela
91

Persoane pentru afiarea tuplurilor, cmpurile afiate fiind: nume, sex i


salariu. Selecia unui tuplu din controlul de tip DataGridView marcheaz
datele care se vor ncrca n documentul Word, lucru care se realizeaz
efectiv prin apsarea butonului Incarca datele in document sau se anuleaz
operaia prin apsarea butonului Anulare. Butoanele de pe form au asociate
valori pentru proprietatea DialogResult: butonul Anulare are asociat
valoarea Cancel n timp ce butonul Incarca datele in document are asociat
valoarea OK. Ambele prin apsare determin nchiderea ferestrei de dialog.
Forma astfel construit este ilustrat n figura 4.22.
Metoda care se apleleaz ca urmare a evenimentului Click pe butonul
Incarca date in document este bincarcare_Click:
void bincarcare_Click(object sender, EventArgs e)
{
//se construieste o noua forma
Form1 fviz = new Form1();
//la apasarea pe butonul Incarca datele in document
if (DialogResult.OK == fviz.ShowDialog())
{
//se identifica rindul selectat
DataGridViewRow rind = fviz.gv.SelectedRows[0];
// se preiau valorile cmpurilor din rindul selectat i
// se nscriu n controalele din documentul Word
cnume.Text = (string)rind.Cells[0].Value;
csal.Text = ((int)rind.Cells[2].Value).ToString();
// pentru controlul din document (csx), de tip DropDownList,
// se reface optiunea asa dupa cum
// apare ea n lista de optiuni a controlului
string sitem = (string)rind.Cells[1].Value == "M" ?
"Masculin" : "Feminin";
// se itereaza prin lista de optiuni a controlului csx
// pina este identificata cea preluata din grid i aceasta se
// selecteaz pentru a fi afiat n control
int i;
for(i=1;i<=csx.DropDownListEntries.Count;i++)
if(sitem == csx.DropDownListEntries[i].Text)
csx.DropDownListEntries[i].Select();
}
}

Operaia de preluare a datelor din baza de date i ncrcarea lor n


documentul Word se ilustreaz n figurile 4.23 i 4.24. Astfel, apsarea pe
butonul Incarca date in document din forma Document Actions a
92

documentului Word determin apariia ferestrei de dialog construit n


proiect avnd controlul de tip grid populat cu datele din tabela Persoane a
bazei de date date_doc.accdb.

Figura 4.22 Fereastra de dialog pentru selectia datelor

Figura 4.23 Vizualizarea datelor i selecia tuplului

Utilizatorul poate selecta un tuplu din tabel, prin intermediul grid-ului


(figura 4.23) i apoi are dou opiuni: una s anuleze operaia, n acest caz
93

apas pe butonul Anulare sau s ncarce datele selectate, n document, prin


apsarea pe butonul Incarca datele in document. Dup apsarea butonului de
ncrcare a datelor n document se nchide fereastra de dialog iar datele
selectate se ncarc, n document, n cmpurile corespunztoare, dup cum
se poate observa n figura 4.24.

Figura 4.24 Incrcarea datelor selectate n documentul ablon

94

Bibliografie
1. ***, Exploring ArcObjects, ESRI Press, 2002;
2. ***, Understanding Map Projections, ESRI Press, 2000;
3. Baker, M., What is a Software Framework? And why should you like
'em?,
http://info.cimetrix.com/blog/?Tag=software+framework,
posted 2009;
4. Bruney, A., Professional VSTO 2005, Wiley Publishing, Inc., 2006;
5. Burke, R., Getting to Know ArcObjects: Programming ArcGIS with
VBA, ESRI Press, 2003;
6. Carter, E., Lippert, E., Visual Studio Tools for Office 2007, AddisonWesley, 2009;
7. Chang, K.-T., Programming ArcObjects with VBA, CRC Press, 2008;
8. Drdal, M., Accessing Excel files using XML format from Director
multimedia applications, The 3rd International Workshop IE & SI,
Facultatea de Stiine Economice, Universitatea de Vest, Timioara,
2006, Editura Mirton, Timioara, 2006;
9. Drdal, M., Communication between C#.NET applications and
Excel, The Proceedings of the Seventh International Conference on
Informatics in Economy, ASE Bucureti, 2005, n volumul Information
& Knowledge Age, ASE, Bucureti, 2005;
10. Drdal, M., Tua, E., Designing Informatics Systems Using
Economic Models Defined by Excel Spreadsheets, Economy
Informatics, vol. VI, nr. 1-4, Editura INFOREC, Bucureti, 2006;
11. Drdal, M., Implementarea structurilor de date dinamice ca obiecte
de tip colecie n C#, Sesiunea anual de comunicri tiinifice,
Universitatea European Drgan, Lugoj, Editura Dacia Europa
Nova, Lugoj, 2004;
12. Drdal, M., Reveiu, A., Using Resources in Visual C#.NET
Applications, Economy Informatics, vol V, nr. 1-4, Editura
INFOREC, Bucureti, 2005;
13. Drdal, M., Reveiu, A., Smeureanu, I., Using DLL as Interface
between API and VC#.NET Applications, Informatica Economic, vol.
X, nr. 1, Editura INFOREC, Bucureti, 2006;
14. Drdal, M., Smeureanu, I., Reveiu, A., Tehnologii multimedia, Editura
ASE, Bucureti, 2008;
95

15. Drdal, M., Smeureanu, I., Tehnologii de acces la date. ASP.NET,


Editura ASE, Bucureti, 2008;
16. Hillier, S., Microsoft SharePoint Building Office 2007 Solutions in
C# 2005, Apress, 2007;
17. Novak, I., Velvart, A., Granicz, A., Balassy, G., Hajdrik, A., Sellers,
M., Hillar, G., Molnar, A., Kanjilal, J., Visual Studio 2010 and
.NET4 SIX-IN-ONE, Wiley Publishing, Inc., 2010;
18. Reveiu, A., Techniques for Representation of Regional Clusters in
Geographical Information Systems, Revista Informatic Economic,
nr. 1/2011, ISSN 1453-1305, pag 129-139;
19. Rimmer, S., Multimedia Programing for Windows, McGraw-Hill,
1994;
20. Smeureanu, I., Drdal, M., Multimedia Programming Objects, Al
cincilea Simpozion de Informatic Economic, A.S.E., Bucureti,
2001;
21. Smeureanu, I., Drdal, M., Reveiu, A., Visual C#.NET, Editura
CISON, Bucureti, 2004;
22. Thangaswamy, V., VSTO 3.0 for Office 2007 Programming, PACKT
Publishing, 2009;
23. http://labs.cs.upt.ro/labs/lft/html/LFT00.htm
24. http://cursuri.cs.pub.ro/~cpl/Curs/CPL-Curs01.pdf
25. http://mszalai.xhost.ro/html/capitolul_ii1.html
26. http://mcpc.cigas.net/progenv.html

96

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