Titlul documentului


loarea DBDEMOS,apoi proprietatea TableName la valoarea EVENTS.DB si in



Yüklə 1,42 Mb.
səhifə10/16
tarix03.01.2019
ölçüsü1,42 Mb.
#89992
1   ...   6   7   8   9   10   11   12   13   ...   16

loarea DBDEMOS,apoi proprietatea TableName la valoarea EVENTS.DB si in

final proprietatea Active la valoarea TRUE.In final,selectati obiectul

DBImage1 si setati proprietatea DataSource la valoarea DataSource1 si

proprietatea DataField la valoarea Event_Photo.In acest moment in obiectul

DBImage va fi afisata o imagine.Tastati F9 si utilizati bara de navigatie

pentru a naviga in baza de date.

Pentru a evita stergerea din greseala a unor inregistrari,puteti

selecta obiectul DBNavigator,executati un dublu click pe proprietatea

VisibleButtons si setati False butoanele: nbInsert,nbDelete,nbEdit,nbPost

si nbCancel.

Daca analizati putin exercitiul,observati ca DataSource utilizeaza

obiectul TTable pentru a prelua datele din baza de date iar DBNavigator

si DBImage preiau datele din DataSource1(care este noua sursa de date).

Eventualele modificari efectuate,vor avea efect doar asupra datelor din

DataSource1.Pentru ca modificarile sa devina definitive,este necesara o

alta procedura care sa actualizeze baza de date cu cele din DataSource1.

Pentru a intelege si mai bine mecanismul,puteti sa adaugati si un

obiect TDBGrid (tot din DataControls).Apoi setati prporietatea DataSource

la valoarea DataSource1 si tastati F9.Observati deplasarea in tabel,la

fiecare apasare a butoanelor din DBNavigator.

Deplasati bara de scrol din DBGrid astfel incat sa puteti observa

denumirea fiecarei probe,sau data desfasurarii,pretul biletului,etc.

La nevoie,redimensionati cele doua obiecte,astfel incat sa aveti o imagine

de ansamblu.

Daca optiunea de editare nu este inactivata,selectati una dintre valo-

rile din tabel si introduceti o valoare noua (de exemplu schimbati data

desfasurarii,apoi navigati in tabel si reveniti la valoarea actualizata).

Valoarea se mentine atat timp cat exercitiul este in executie.Daca

inchideti fereastra si relansati programul,datele vor fi afisate cu

valoarea initiala (modificarile au fost temporare si au avut efect doar

asupra tamponului de memorie din DataSource1).

Modificarile din DataSource1 nu pot fi transferate direct asupra

bazei de date.Pentru o astfel de operatie,datele trebuiesc salvate

intr-un tampon de memorie,sau intr-o fila temporara,dupa care se va

utiliza tamponul sau fila temporara pentru a rescrie baza de date.Daca

sunteti incepator,nu este recomandabil sa modificati nici o baza de date

(nici macar cele personale).Pentru inceput,este bine sa exersati cat

mai multe metode de preluare si prelucrare a datelor.Calitatea programa-

torului se reflecta direct asupra modului de selectie a datelor.


-69- DataAccess - TTable

TTable este unul dintre obiectele utilizate pentru a accesa o baza de

date.Se utilizeaza impreuna cu TDataSource,care va prelua datele accesate

de TTable.Un obiect de tip TTable se poate utiliza pentru a prelua un

singur tabel,dintr-o singura baza de date.TTable permite accesul direct

la fiecare inregistrare din tabel.Se poate utiliza pentru baze de date

editate cu unul dintre programele: Paradox,dBASE,Access,FoxPro sau pentru

a prelua date de la un server din retea de tip Interbase,Oracle,Sysbase,

Informix sau DB2.

Prin proprietatile si metodele sale,tTable se poate utiliza si pentru

a prelua doar o parte din date,cu ajutorul unor filtre,care vor selecta

din tabel doar datele care respecta conditiile specificate.

TTable,impreuna cu celelalte componente nonvizuale,poate fi arhivat

intr-un modul de tip DataModule.Un astfel de modul poate contine toate

obiectele necesare pentru a accesa una sau mai multe baze de date.In

cazul in care se vor realiza mai multe aplicatii,care utilizeaza aceleasi

baze de date,modulul DataModule va putea fi utilizat pentru fiecare

dintre acestea.Astfel un proiect poate contine doua sau mai multe file

care utilizeaza acelasi modul,pentru a prelua datele din mai multe tabele.

Pentru a prelua datele din doua sau mai multe tabele,este necesar cate

un obiect TTable si cate un obiect TDataSource,pentru fiecare tabel:

EXEMPLU: (vezi si Prj60)

Salvati o fila noua si proiectul in Prj60.Adaugati din DataControls doua

obiecte TDBGrid si doua obiecte TDBNavigator.

Din File,alegeti New Data Module si adaugati in proiect un modul de

date.Adaugati in DataModule1 doua obiecte TDataSource si doua obiecte

TTable.Apoi selectati fila Form si din meniul File utilizati Use Unit

pentru a introduce modulul de date in lista de unitati a proiectului.

Reveniti in Datamodule1 si setati DataSource1 la DataSet=Table1 si

respectiv DataSource2 la DataSet=Table2.

Alegeti Table1,setati DatabaseName la DBDEMOS,TableName la MASTER.DBF

si Active=TRUE.Alegeti Table2 si setati DatabaseName la DBDEMOS,TableName

la HOLDINGS.DBF si Active la valoarea TRUE.

Selectati DBNavigator1 si setati DataSource la DataModule1.DataSource1.

Selectati DBNavigator2 si setati DataSource la DataModule1.DataSource2.

Selectati DBGrid1 si setati DataSource la DataModule1.DataSource1.

Selectati DBGrid2 si setati DataSource la DataModule2.DataSource2.

Tastati F9 si executati aplicatia.

In fereastra sunt doua tabele care pot fi accesate separat.Fiecare tabel

este prelucrat de o pereche de obiecte DataSource + TTable si afisat de

o pereche de obiecte DBGrid + DBNavigator.

Cele patru obiecte nonvizuale au fost grupate intr-un modul de date.

In viitor,daca doriti sa utilizati cele doua baze de date,intr-o alta

formula (de exemplu sa preluati doar coloanele care contin preturile),

este suficient sa adaugati modulul de date (cu Use Unit din File) in

lista de unitati a noii aplicatii,dupa care puteti selecta obiectele

dorite pentru afisarea datelor.

O alta situatie frecventa,este atunci cand mai multi utilizatori

au preferinte diferite pentru afisarea datelor preluate din aceleasi

baze de date.In acest caz,se poate utiliza un modul de date pentru

preluarea datelor si cate o fila de tip Form,pentru fiecare utilizator

(cu obiectele de prezentare a datelor alese de utilizator).


-70- DataAccess - TQuery

TTable contine si un numar destul de mare de proprietati si metode.

Se pot realiza o serie intreaga de filtre de selectie,sau artificii de

sortare si prezentare a datelor.

Un exemplu simplu: -cautarea unei anumite inregistrari in functie de

o anumita valoare cunoscuta.

EXEMPLU: (vezi si Prj61)

Salvati o fila si proiectul in Prj61.Adaugati in fila un obiect TData-

Source,un obiect TTable,un obiect TDBGrid,un obiect TDBImage si un buton.

Setati DataSet din DataSource1 la valoarea Table1.

Setati Databasename din Table1 la DBDEMOS,TableName la ANIMALS.DBF si

Active la valoarea TRUE.

Setati DataSource din DBGrid1 la DataSource1 si DataSource din DBImage tot

la valoarea DataSource1.

Acum obiectele sunt linkate si tabelul este afisat in DBGrid.Daca dorim

sa adaugam o procedura de cautare rapida,putem utiliza butonul pentru a

introduce si o functie Locate().De exemplu,pentru a cauta prima inregis-

trare in care animalul are dimensiunea de 5 inchi,se va edita urmatoarea

procedura OnClick:

procedure TForm1.Button1Click(Sender: TObject);

begin

Table1.Locate('SIZE','5',[loCaseInsensitive]);

end;

Tastati F9 si executati aplicatia.Apasand butonul OK,cursorul se va

deplasa automat la prima inregistrare care respecta conditia.

Acest procedeu,este util mai ales atunci cand utilizati foarte

frecvent o baza de date,din ce in ce mai mare,din care doriti sa selectati

doar una sau mai multe inregistrati.Puteti adauga cate un buton de cautare

rapida pentru fiecare inregistrare dorita.

Atentie la metodele care sterg datele din baza de date.TTable lucreaza

direct cu baza de date,astfel incat datele sterse nu pot fi recuperate.

Daca utilizati metode de stegere,este bine ca aceste metode sa fie in-

cluse in proceduri standardizate,verificate cu atentie.Evitati proce-

durile interactive,in care comenzile sunt introduse in timpul executiei,

deoarece un moment de neatentie va poate costa multe ore de munca.
TQuery -este asemanator cu TTable,dar utilizeaza o comanda in limbaj SQL,

pentru accesarea si selectarea datelor dintr-o baza de date.Mai mult decat

atat,comanda SQL permite ca datele sa fie preluate din doua sau mai multe

tabele si sa fie centralizate intr-un obiect de prezentare.Exemple simple

au fost prezentate impreuna cu limbajul SQL(vezi pagina 55) si Prj52.

Formularea comenzii in limbaj SQL,permite o mult mai mare maleabilitate

si selectivitate.Se poate extrage o singura coloana de date,sau chiar o

singura inregistrare,in loc de a afisa intregul tabel.In plus,datele din

doua tabele pot fi combinate,pentru a realiza un tabel comparativ,etc.

TQuery,nu numai ca permite accesara datelor,dar permite si transmiterea

de date,de la component catre baza de date,astfel incat bazele de date

pot fi modificate,actualizate,completate sau chiar sterse definitiv din

memorie.

Obiectul contine si un numar mare de proprietati,metode si evenimente,

care extind si mai mult posibilitatile acestui obiect.Alegeti acest

obiect ori de cate ori este necesara prelucrarea datelor(fie si minimala).


-71-

Pentru comenzile care contin o comanda de tip SELECT (comenzi care nu

modifica baza de date),nu este necesara nici o alta operatie preliminara.

Se introduce comanda in proprietatea SQL si apoi se activeaza setand

proprietatea Active:=True.

Pentru comenzile care contin INSERT,UPDATE sau DELETE (comenzi care

altereaza sau modifica baza de date) este necesara o operatie preliminara

de pregatire a bazei de date.Puteti prepara baza de date cu metoda Pre-

pare,sau puteti apela metoda ExecSql,care executa si o operatie de pre-

parare a bazei de date,inainte de a executa comanda propriu-zisa(continuta

in proprietatea SQL).

Daca nu cunoasteti limbajul SQL,puteti utiliza formula universala:

SELECT * FROM numele bazei de date

care va extrage toate datele din tabelul specificat(vezi si pagina 55).

De exemplu,pentru a selecta si afisa doar doua tipuri de date dintr-un

tabel complex se poate utiliza un exercitiu de genul:

EXEMPLU: (vezi si Prj62)

Salvati si arhivati o fila noua si proiectul,in Prj62.Adaugati un obiect

TDataSource si un obiect TQuery,apoi adaugati din DataControls un obiect

TDBMemo,un obiect TDBImage si un obiect TDBNavigator.

Alegeti DataSource1 si setati DataSet la valoarea Query1.

Alegeti Query1 si setati DatabaseName la valoarea DBDEMOS,apoi introduceti

in SQL urmatoarea comanda: SELECT Notes,Graphic,Category FROM Biolife.db

Apoi setati Active la valoarea True.

Alegeti DBNavigator1 si setati DataSet la valoarea DataSource1.

Alegeti DBMemo1 si setati DataSource=DataSource1 si DataField=Notes.

Alegeti DBImage si setati DataSource=DataSource1 si DataField=Graphic.

Tastati F9 si executati aplicatia.Din tabelul Biolife.db s-au utilizat

doar doua coloane (cele care contin datele utile).

Pentru a identifica rapid o anumita inregistrare,se poate adauga un

buton si o procedura Locate,astfel:

Adaugati un buton si atribuiti urmatoarea procedura OnClick:

procedure TForm1.Button1Click(Sender: TObject);

begin

Query1.Locate('Category','Shark',[loCaseInsensitive]);

end;

Observati ca am exploatat cea de a treia coloana selectata in comanda SQL.

Apasand butonul,se va selecta automat inregistrarea solicitata.

Puteti realiza un astfel de exercitiu,pentru un album de familie sau

un jurnal de calatorie,o lucrare ilustrata etc.

Pentru a realiza o si mai mare flexibilitate,TQuery poate fi cuplat cu

unul sau mai multe obiecte de tip TUpdateSQL.Obiectele de tip TUpdateSQL

permit schimbarea unei comenzi SQL cu o alta comanda,stergerea sau actua-

lizarea comenzii etc.Acest gen de operatie este utila,mai ales atunci cand

se solicita comenzi de modificare a tabelelor prin operatii de tip DELETE,

INSERT sau UPDATE.In mod normal,o astfel de operatie necestia o etapa de

pregatire si apoi necestia o noua comanda de redeschidere a bazei de date,

dupa ce s-au executat modificarile dorite.Cu ajutorul componentelor de

tip TUpdateSQL,aceste operatii se pot executa in succesiune,astfel incat

pentru utilizator apare ca o operatie simpla de modificare a unei inre-

gistrari.In mod curent,obiectele TQuery si TUpdateSQL necesare pentru

implementarea procedurii se grupeaza intr-un modul de tip DataModule.


-72- DataAccess - TClientDataSet

TClientDataSet este un obiect destinat tot pentru manipularea datelor

si poate fi utilizat atat in aplicatii simple cat si in aplicatii in care

obiectele prezinta mutiple legaturi intre ele (inlantuire multipla).

Poate prelua datele de la un obiect TRemoteServer,caz in care poate fi

sursa de date,pentru obiectele de tip TDataSource,la fel ca si TTable sau

TQuery.Practic,reprezinta o solutie alternativa de preluare a datelor

dintr-o baza de date,mai ales atunci cand baza de date este in conexiune

permanenta cu un obiect de tip TRemoteServer.

Dintre tabelele utilizate pentru exemplificarea componentelor(cele din

Demo/Data) doar tabelul Employee este in conexiune implicita cu obiecte-

le TRemoteServer generate local.Pentru a realiza si alte conexiuni,este

necesara existenta unui server activ.

TClientDataSet,detine un numar foarte mare de metode,care pot fi uti-

lizate pentru a prelua datele dintr-un tabel,pentru a transfera datele

intr-o fila locala,pentru a selecta sau identifica o anumita inregistrare,

pentru a determina numarul sau valoarea inregistrarii curente etc.

O alta utilizare frecventa,este atunci cand o aplicatie solicita mai

multe instante ale unei baze de date.In acest caz,se poate utiliza un

singur TRemoteServer si cate un obiect TClientDataServer pentru fiecare

instanta a tebelului pe care doriti sa o generati.

EXEMPLU: (vezi si Prj63)

Salvati o fila noua si proiectul in Prj63.Adaugati un obiect TDataSource,

un obiect TClientDataSet si un obiect TRemoteServer.

Selectati RemoteServer1 si setati ServerName la valoarea Serv.EmpServer.

Automat,proprietatea ServerGUID va contine un cod de identificare(practic

codul de interfata al tabelului Employee din DBDEMOS).Apoi setati pro-

prietatea Connected la valoarea True.Se va afisa o fereastra denumita

Employee Data Server,care va afisa numarul de clienti si numarul de

solicitari.Din acest moment,aplicatia este in conexiune permanenta cu

tabelul Employee.Daca in calculatorul d-voastra exista un server instalat,

continand baze de date,puteti alege valoarea ServerName dintr-o lista

intreaga de optiuni.

In continuare selectati obiectul ClientDataSet1 si setati proprietatea

RemoteServer la valoarea RemoteServer1.Apoi alegeti proprietatea

ProviderName si setati valoarea EmpQuery si proprietatea Active la valoa-

rea True.

Alegeti DataSource1 si setati DataSet la valoarea ClientDataSet1.

Apoi adaugati un obiect de tip TDBGrid (din DataControls) si setati

proprietatea DataSource la valoarea DataSource1.

Se vor afisa datele din tabelul Employee.

Tastati F9 si executati aplicatia.

Pentru a adauga o noua instanta a tabelului,adaugati un obiect TDataSource

si un obiect TClientDataSet.Alegeti TClientDataSet si setati RemoteServer

la valoarea RemoteServer1 si ProviderName la valoarea EmpQuery.Apoi setati

proprietatea MasterSource la valoarea DataSource1 si executati un dublu

click pe MasterFields.Alegeti FirstName din ambele coloane (Detail Fields

si MasterFields) apoi apasati butonul Add si apoi OK. Setati Active=True.

In acest moment noua instanta a tabelului Employee este legata de prima

instanta,doar pentru inregistrarile in care apare acelasi prenume.

Selectati DataSource2 si setati DataSet la valoarea ClientDataSet2.

Selectati TDBGrid si setati DataSource la valoarea DataSource2.

-73-

Cea de a doua instanta a tabelului contine doar doua inregistrari (cele

pentru care FirstName este identic-adica "Roberto").

Pentru a putea alterna cele doua instante,adaugati doua butoane si

atribuiti cate o procedura OnClick de genul:

DBGrid1.DataSource:=DataSource1 (pentru primul buton)

si respectiv:

DBGrid1.DataSource:=DataSource2 (pentru al doilea buton)

Pentru a adauga o noua instanta,se procedeaza identic.De exemplu,pentru

a adauga o instanta a tabelului cu angajatii care au fost incadrati la

aceeasi data:

Adaugati un obiect TDataSource si un obiect TClientDataSet.

Selectati ClientDataSet3 si setati RemoteServer=RemoteServer1,ProviderName

la valoarea EmpQuery si MasterSource la valoarea DataSource1.

Executati un dublu click pe MasterFields si alegeti in ambele coloane

valoarea HireDate,apoi tastati Add si OK.Setati Active=True.

Selectati DataSource3 si setati DataSet la valoarea ClientDataSet3.

Selectati TDBGrid si setati DataSource la valoarea DataSource3.

Pentru a putea alterna instantele in timpul executiei,adaugati un

nou buton si procedura OnClicK:

procedure tForm1.Button3Click(Sender: TObject);

begin

DBGrid1.DataSource:=DataSource3;

end;

Tastati F9 si executati aplicatia.Puteti utiliza butoanele pentru a

selecta alternativ cele trei instante ale tabelului (toate inregistrarile,

cele cu acelasi prenume si cele din aceeasi data calendaristica).

In mod similar,obiectele de tip TClientDataSet se pot utiliza in diver-

se combinatii,pentru a realiza legaturi multiple intre doua sau mai multe

obiecte.Este preferabil totusi sa alegeti intotdeauna solutia cea mai

simpla,sau sa explicati succint modul si rostul legaturilor realizate (

pentru a simlipica cat mai mult munca celui care va depana programele).
TRemoteServer este un obiect destinat pentru a mentine o conexiune fixa

cu o baza de date,in cadrul unei aplicatii cu legaturi interne multiple.

Singurul RemoteServer implicit este cel care conecteaza tabelul Employee.

Pentru a realiza si alte legaturi fixe,trebuie sa cunoasteti codul de

identificare al interfeetei respective si sa specificati acest cod in

proprietatea ServerGUID (GUID=globally unique identifier).

Codul GUID are o structura de forma:

'{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx}' unde x este hexazecimal

TRemoteServer se poate utiliza pentru:

-a realiza o legatura fixa cu o baza de date

-a mentine o lista de obiecte Provider accesibile prin aceasta conexiune

-a obtine o interfata IProvider

-a mentine o lista,ce contine bazele de date accesibile prin RemoteServer

-a intrerupe conexiunea actuala (desface legatura fiza)

Un TRemoteServer poate fi utilizat impreuna cu un numar nelimitat de

obiecte TClientDataSet,pentru a realiza instante diferite ale unui tabel

din baza de date (vezi mai sus exemplul Prj 63).

Metodele se pot utiliza pentru a stabili sau intrerupe conexiunea

(DoConnect si DoDisconnect),etc. Pentru exemplificare vezi Prj63.


-74- DataAccess - TDataBase si TSession

TDatabase este un obiect conceput pentru a realiza o conexiune fixa cu

o baza de date,in special pentru conexiunile cu o baza de date situata

intr-un server de retea,care necesita o parola de acces si un cod de

identificare a utilizatorului.

TDatabase permite controlul conexiunii cu o singura baza de date.Daca

aplicatia utilizeaza mai multe baze de date,este necesar cate un obiect

de tip TDatabase pentru fiecare dintre acestea.Controlul exercitat asupra

conexiunii include utilizarea unei denumiri alias,specificarea unui anumit

driver pentru realizarea conexiunii,control asupra schimburilor de date

(tranzactiilor).In situatiile in care nu se declara in mod explicit un

astfel de obiect,programul va crea un obiect temporar de tip TDatabase,

care va fi utilizat doar in timpul executiei cu un set de proprietati

implicite,suficiente pentru executarea aplicatiei.Puteti declara explicit

un astfel de obiect,ori de cate ori doriti sa alegeti driver-ul de

conexiune sau doriti sa utilizati o denumire alias pentru baza de date.

EXEMPLU: (vezi si Prj64)

Salvati o fila noua si proiectul in Prj64.Adaugati un obiect de tip

TDataSource,un obiect TDatabase,un obiect TTable si un control TDBGrid.

Selectati obiectul TDatabase si setati DatabaseName la valoarea

Reservat.db,apoi AliasName la valoarea DBDEMOS.In final setati proprieta-

tea Connected la valoarea True.

Selectati obiectul Table1 si alegeti DatabaseName.Observati ca in lista

de optiuni a aparut si Reservat.db.Selectati optiunea Reservat.db.Apoi

setati si TableName la valoarea Reservat.db si Active la valoarea True.

Selectati DataSource1 si setati DataSet la valoarea Table1.

Selectati DBGrid1 si setati DataSource la valoarea DataSource1.

Tastati F9 si executati aplicatia.

In situatia in care doriti sa utilizati TDatabase pentru o conexiune cu

un tabel situat intr-un server,de exemplu un tabel de tip FoxPro,va fi

necesar sa setati si proprietatea DriverName,care va solicita numele uti-

lizatorului si parola de acces.Pentru tabele locale,este mai simplu sa

mutati tabelul in directorul Demos/Data.

Observati ca pentru a intrerupe conexiunea se poate utiliza atat pro-

prietatea Active din Table1 cat si proprietatea Connected din Database1.

In plus,obiectul TDatabase contine si proprietatea SessionName.Aceasta

proprietate se poate utiliza impreuna cu obiecte de tip TSession pentru

a crea mai multe instante ale bazei de base.Fiecare instanta va fi reali-

zata cu ajutorul unui obiect de tip TSession.Astfel,baza de date cu care

se realizeaza conexiunea fixa,va putea fi deschisa si redeschisa,in mod

repetat in timpul executiei,utilizand un singur obiect de tip TDatabase.

Fiecare instanta va putea utiliza o comanda SQL diferita (vezi mai jos).
TSession este un obiect destinat pentru a gestiona o linie de executie,

in cadrul aplicatiilor cu comanda multipla (mai multe linii de executie,

sau mai multe instante ale unui obiect).Pentru fiecare aplicatie Delphi

se creaza automat si un obiect TSession implicit.Nu este necesar sa

definiti explicit un astfel de obiect,decat atunci cand proiectati apli-

catii care au mai mult decat o linie de comanda (comenzi pe port paralel,

sau instante multiple).Un obiect de tip TSession exercita un control

global asupra tuturor obiectelor de tip TDatabase conectate la acest

obiect.


-75-

De exemplu,daca doriti sa utilizati mai multe formule de comanda SQL

pentru a deschide o baza de date,aceste comenzi nu vor putea fi executate

concurential.Puteti utiliza cate un obiect TQuery pentru fiecare comanda

si cate un obiect TSession pentru fiecare executie.

O alta situatie posibila este atunci cand utilizati mai multe baze de

date,situate la locatii diferite,pentru a centraliza datele intr-un singur

tabel.In acest caz,puteti utiliza cate un obiect de tip TDatabase pentru

fiecare conexiune si un obiect TSession pentru a lega intre ele obiectele

TDatabase utilizate pentru fiecare comanda.Se pot realiza astfel legaturi

de tip arborescent,care pot gestiona orice situatie logica.

TSession se utilizeaza pentru a conecta intre ele mai multe obiecte

care vor fi utilizate intr-o anumita linie de comanda.Exista trei tipuri

distincte de aplicatii care utilizeaza TSession: standard,multifila si

multicomanda.

Aplicatia standard este cea implicita si se implementeaza automat pentru

orice aplicatie Delphi.

Aplicatia multifila se realizeaza atunci cand sunt necesare mai multe

file,situate la adrese diferite in retea,pentru a centraliza datele intr-o

singura fila locala.

Aplicatia multicomanda se realizeaza atunci cand sunt necesare mai

multe comenzi (uneori simultane) pentru a centraliza datele intr-un

singur tabel local.In acest caz,aplicatia va realiza mai multe conexiuni

paralele cu aceeasi baza de date si va executa comenzile in sesiuni dife-

rite.

EXEMPLU: (vezi si Prj65)

Salvati o fila noua si proiectul in Prj65.Adaugati un obiect TDataSource,

un obiect TDatabase,2 obiecte TSession si 2 obiecte TQuery.

Selectati obiectul Database1 si setati DatabaseName la valoarea Biolife.db

si AliasName la valoarea DBDEMOS.

Selectati Session1 si setati SessionName la valoarea Ses1 si apoi alegeti

Session2 si setati SessionName la valoarea Ses2.

Selectati Query1 si setati DatabaseName la valoarea Biolife.db,SessionName

la valoarea Ses1 si SQL la valoarea: SELECT Category FROM Biolife.db

Selectati Query2 si setati DatabaseName la valoarea Biolife.db,SessionName

la valoarea Ses2 si SQL la valoarea: SELECT * FROM Biolife.db

Apoi adaugati doua butoane,denumite Sesiunea 1 si Sesiunea 2 si atribuiti

urmatoarele proceduri OnClick:

procedure TForm1.Button1Click(Sender: TObject);

begin

Session2.Active:=False;

Session1.Active:=True;

Database1.SessionName:='Ses1';

Query2.Active:=False;

Query1.Active:=True;

DataSource1.DataSet:=Query1;

end;

Observati ca una dintre liniile de comanda trebuie sa fie inactivata in

timp ce cea de a doua linie de comanda va fi activata.Daca ambele linii

de comanda raman activate in acelasi moment,se creaza o comanda concuren-

tiala care returneaza un mesaj de eroare (una dintre comenzi gaseste

conexiunea "busy" deoarece este ocupata de catre cealalta comanda).


-76-

Adaugati si cea de a doua procedura (butonul al doilea):

procedure TForm1.Button2Click(Sender: TObject);

begin

Session1.Active:=False;

Session2.Active:=True;

Database1.SessionName:='SES2';

Query1.Active:=False;

Query2.Active:=True;

DataSource1.DataSet:=Query2;

end;

Tastati F9 si executati aplicatia.Fiecare din cele doua butoane va

declansa una dintre cele doua sesiuni,respectiv va executa una dintre

cele doua linii de comanda.Obiectul TDatabase nu este strict necesar,dar

a fost adaugat exemplificativ,pentru a ilustra modul de conectare la

doua sesiuni diferite.Nici obiectele TSession nu sunt strict necesare,

deoarece baza de date este locala,dar acesta este modelul de conectare

in cazul in care se utilizeaza mai multe baze de date sau mai multe

comenzi concurentiale.Modul de interconectare al obiectelor face deliciul

fiecarui programator.Este bine sa alegeti intotdeauna solutia cea mai

simpla,sau sa adaugati un minimum de explicatii.Nu uitati ca de cele mai

multe ori,cel care va depana aplicatiile va fi cel care le-a programat.

Este bine ca si asezarea obiectelor in Form sa respecte modul lor de

conectare,astfel incat depanarea lor sa fie cat mai simpla.Atunci cand

utilizati un numar mare de obiecte,este bine sa grupati obiectele in

module,astfel incat depanarea programului sa se reduca doar la depanarea

unui singur modul.Cea mai frecventa situatie care poate afecta un program

functional,este generata de "supradoparea" unui tampon de memorie.In

aceste situatii,este bine ca obiectul,sau modulul din care face parte

sa poata fi inlocuit cat mai usor (este mult mai usor decat sa incercati

sa eliberati tamponul de meorie cu sectoare defecte).

Aplicatiile mari,pot sa utilizeze atat baze de date diferite cat si

comenzi multiple pentru fiecare baza de date.Pentru a simplifica procesul

de depanare,puteti grupa obiectele care executa aceeasi sesiune,sau

obiectele care opereaza asupra aceleiasi baze de date,in module separate.

Calitatea programatorului se poate observa de la prima vedere,dupa modul

de organizare si gestionare a obiectelor si a proceselor aflate in exe-

cutie la un anumit moment dat.Programele de calitate sunt simple,clare,

usor de aplicat si usor de depanat sau modernizat.Este bine sa nu epuizati

toata memoria de operare pentru executarea unei aplicatii.Este bine sa

lasati intotdeauna loc pentru actualizari si modernizari viitoare.

Programele concepute modular,nu numai ca sunt mult mai usor de depanat,

dar pot fi separate in elemente componente.Prin cuplarea unor astfel de

elemente (module) preluate din mai multe programe se poate realiza un

program nou,aproape fara nici un efort.Este bine ca fiecare modul sa

fie conceput cat mai clar si cat mai general,astfel incat sa poata fi

aplicat in programe diferite.In timp,puteti realiza o colectie proprie

de module specializate,astfel incat sa rezolvati orice problema de

programare prin simpla conectare a unui numar de astfel de module.

Pentru programele care urmeaza sa fie utilizate extensiv,este bine sa

arhivati pe langa copia de siguranta si un numar oarecare de module

pregatite pentru depanarea "de urgenta" a programului.


-77- DataAccess - TBatchMove

TBatchMove este un obiect conceput special pentru a copia usor datele

dintr-un tabel in alt tabel.Principala sa utilizare este fie pentru a

copia un tabel dintr-un server de retea la o adresa locala (download),fie

pentru a incarca un tabel de la o adresa locala intr-un server de retea

(upload).Intr-o baza locala,poate face o copie de siguranta automata.

TBatchMode se poate utiliza fie pentru a actualiza doar un anumit grup

de date,fie pentru a copia intregul tabel.

TBatchMode se poate utiliza si in interiorul aceleiasi baze de date.

In aces caz,se poate utiliza pentru a copia un tabel cu un nume nou,

pentru a sterge o parte dintre inregistrarile unui tabel sau pentru a

adauga un set de inregistrari noi.Tipul de operatie efectuat este deter-

minat de proprietatea Mode(batAppend,batCopy,batDelete,batUpdate).

Pentru a specifica grupul de coloane si modificarile efectuate se poate

utiliza proprietatea Mappings.

Tabelul sursa se va specifica in proprietatea Source iar tabelul de desti-

natie va fi setat in proprietatea Destination.

Pentru executarea efectiva a trensferului de date se va apela metoda

Execute.Pentru ca transferul sa poata fi efectuat este necesar ca pro-

prietatile Source,Mode si Destination sa contina valori valide.

Din considerente prectice,este bine sa utilizati pentru specificarea

sursei si a destinatiei obiecte de tip TTable sau TQuery,la care proprie-

tatea Active este setata False (in caz contrar linia de acces la baza de

date va fi identificata ca "busy").

EXEMPLU: (vezi si Prj66)

Salvati o fila noua si proiectul in directorul Prj66.Adaugati un obiect

TDataSource,2 obiecte TTable si un obiect TBatchMove.

Selectati Table1 si setati DatabaseName la valoarea DBDEMOS si TableName

la una dintre valorile optionale (de exemplu VENUES.DB).

Selectati Table2 si setati DatabaseName la valoarea DBDEMOS si TableName

la o valoare oarecare (De exemplu: Tabel2.dbf).Numele introdus va fi

numele bazei de date pe care o realizati copiind tabelul din Table1.

Selectati BatchMove si setati Source=Table1,Destination=Table2 si Mode

la valoarea batCopy.

Pentru a putea vizualiza operatia efectuata,adaugati si un control de tip

TDBGrid.Setati DataSource1 la valoarea DataSet=Table2 si apoi setati in

DBGrid1 DataSource=DataSource1.

Pentru a efectua transferul datelor,adaugati un buton OK si urmatoarea

procedura OnClick:

procedure TForm1.Button1Click(Sender: TObject);

begin

Table2.Active:=False;

BatchMove1.Execute;

Table2.Active:=True;

end;

Tastati F9 si executati aplicatia.La apasarea butonului OK,datele din

Venues.db vor fi copiate in tabelul Tabel2.dbf nou creat.

Un exemplu complet gasiti si in directorul Help/Examples/Batchmv.
Obiectele de tip TStoredProc si TProvider necesita prezenta unui server

instalat si nu vor face obiectul acestui manual.Sunt destinate pentru a

prelua datele,sau comenzile(proceduri fixe), dintr-un server de retea.

-78- Data Controls - TDBGrid

Paleta de obiecte incluse sub numele de DataControls este formata din

obiecte specializate pentru afisarea datelor (preluate dintr-o baza de

date cu ajutorul obiectelor descrise la paleta DataAccess).Legatura dintre

obiecte,se realizeaza de obicei cu ajutorul unui obiect de tip DataSource.

Obiectele din acest grup,sunt obiecte vizuale si formeaza interfata gra-

fica dintre program si utilizator.In functie de experienta si in functie

de necesitatile de moment,programatorul va alege unul sau mai multe astfel

de obiecte,pentru a prezenta datele,intr-un anumit fel.Pentru tabelele

mici,cu putine date,se vor prefera obiectele care afiseaza intregul tabel.

In cazul tabelelor mari,cu multe coloane si mii de inregistrari,se vor

prefera obiectele care afiseaza cat mai selectiv datele dorite.

TDBGrid este obiectul care permite afisarea si editarea datelor sub

forma de tabel.Este obiectul cel mai frecvent utilizat pentru prezentarea

integrala a tabelelor.Datele sunt preluate de obicei de catre un obiect

TTable sau TQuery si sunt mediate de un obiect TDataSource.

TDBGrid poate fi utilizat si pentru manipularea sau editarea datelor,

sau pentru schimbarea aspectului (culori,fonturi etc.).Prin proprietatea

Fields se poate accesa fiecare obiect de tip TField care formeaza inre-

gistrarile din tabel si implicit si toate proprietatile obiectelor de

tip TField.Prin combinarea acestora,cu proprietatile specifice obiectului

TDBGrid (destul de multe),se obtine o paleta foarte larga de optiuni,care

permit programatorului sa personalizeze modul de prezentare a datelor.

EXEMPLU: (vezi si Prj67)

Salvati o fila noua si proiectul in Prj67.Adaugati un obiect TDataSource,

un obiect TTable si un obiect TDBGrid.

Selectati TTable si setati proprietatea DatabaseName la valoarea DBDEMOS,

TableName la valoarea VENDORS.DB si Active la valoarea True.

Selectati TDataSource si setati DataSet la valoarea Table1.

Selectati TDBGrid si setati DataSource la valoarea DataSource1.

Redimensionati obiectul DBGrid1 astfel incat sa fie la dimensiunile

dorite.Daca doriti sa umple intreaga pagina,pur si simplu setati proprie-

tatea Align la valoarea alClient.

Pentru a schimba aspectul coloanelor,selectati proprietatea Columns

(dublu click) si in fereastra Editing DBGrid1.Columns alegeti butonul

AddAllFields.Apoi selectati pe rand fiecare element(coloana) si utilizati

din ObjectInspector proprietatile Color si Font pentru a selecta paleta

de culori si de fonturi preferate.

Pentru a schimba culoarea cadrului general al tabelului puteti utiliza

proprietatea FixedColor,iar pentru a schimba culoarea paginei in care se

va afisa tabelul puteti utiliza proprietatea Color.

Un set suplimentar de optiuni poate fi accesat executand un dublu

click pe semnul + situat in fata proprietatii Options.

Daca doriti ca tabelul sa fie afisat doar dupa apasarea unui buton,

setati proprietatea Visible la valoarea False si apoi adaugati o procedura

OnClick care seteaza Visible:=True.In acest mod,un set intreg de tabele

poate fi afisat succesiv in aceeasi fereastra de tip utilizator.

Metodele obiectului nu sunt extrem de numeroase,in schimb sunt imple-

mentate un numar destul de mare de evenimente,care permit transmiterea de

mesaje informative despre toate operatiile efectuate in obiect.Cele mai

frecvent utilizate sunt OnCellClick,OnColEnter,OnColExit si OnTitleClick.

Navigarea in tabel poate fi facilitata de un obiect de tip TNavigator.


-79-

Trebuie remarcat faptul ca modificarile datelor realizate in obiectul

TDBGrid nu afecteaza baza de date,ci doar tamponul de memorie in care se

realizeaza reformatarea datelor.Astfel,pentru Tabelul VENDORS.db,puteti

utiliza din Columns butonul Delete pentru a sterge in intregine coloana

Address2 (care nu contine date).Modificarea va fi definitiva doar

pentru aplicatia in care este utilizat tabelul DBGrid1,dar nu va afecta

baza de date originala (daca deschideti tabelul Vendors.db cu un alt

obiect,coloana Address2 este nemodificata).

Ca rezultat,puteti modifica fara frica aspectul tabelelor prezentate,

deoarece datele nu se vor pierde definitiv si puteti reveni oricand la

un format anterior.Pentru ca datele sa fie modificate definitiv,trebuie

fie sa rescrieti fila sursa,fie sa utilizati o comanda SQL.

Alegeti culorile si fonturile preferate.Este bine totusi,ca tabelele sa

nu fie excesiv de colorate.Prea multe culori distrag atentia si obosesc

ochiul.Este bine sa marcati cu culori contrastante doar datele asupra

carora doriti sa atrageti atentia.Eventual,puteti utiliza un efect de

clipire,sau un efect de schimbare alternativa a fondului,pentru datele

pe care doriti sa le evidentiati.

Pentru a prelua din tabel date izolate,puteti utiliza orice combinatie

de proprietati si metode.De exemplu,pentru a prelua datele din celula

de tabel selectata,se poate utiliza urmatoarea procedura:

EXEMPLU: (vezi si Prj68)

Salvati o fila noua si proiectul in Prj68.Adaugati un obiect TDataSource,

un obiect TTable,un obiect TDBGrid si un obiect TLabel.

Setati Table1 la valorile: DatabaseName=DBDEMOS, TableName=COUNTRY.DB si

Active=True.

Setati DataSet din DataSource1 la valoarea Table1.

Setati DataSource din DBGrid1 la valoarea DataSource1.

Apoi alegeti evenimentul OnCellClick si adaugati urmatoarea procedura:

procedure TForm1.DBGrid1CellClick(Column: TColumn);

var text:variant;

begin

text:=DBGrid1.SelectedField.Value;

Label1.Caption:=text;

end;

Selectati Label1 si setati fontul si culoarea dorita,apoi adaugati in

Caption textul: "Textul Selectat: "

Tastati F9 si executati aplicatia.Selectati cateva celule din tabel si

observati ca obiectul TLabel a preluat datele din celula.

In mod similar,puteti edita proceduri care efectueaza diverse operatii

asupra datelor preluate din tabel.Datele pot fi preluate pe linii sau

coloane intregi,pot fi preluate izolat sau pot fi preluate aleator de

catre o functie random,etc.

O aplicatie utila este atunci cand,datele citite selectiv sunt arhi-

vate intr-un tabel sintetic secundar.In acest mod,puteti prelua date

de la un server de retea,dintre care arhivati local doar inregistrarile

care sunt importante pentru utilizator.

Este bine sa conspectati si proprietatile obiectelor TField,care ofera

o paleta destul de larga de expresie si permit un numar destul de mare

de operatii cu datele din fiecare celula a tabelului (mai ales operatii

de schimbare a formatului).


-80- Data Controls - TDBNavigator

TDBNavigator este un obiect format din butoane destinate pentru de-

plasarea cursorului in interiorul bazei de date,sau pentru editarea dete-

lor.Cu ajutorul acestor butoane,utilizatorul se poate deplasa rapid la

inregistrarea dorita,sau poate efectua operatii simple asupra datelor:

adaugarea,actualizarea sau stergerea unei inregistrari.

Butoanele au urmatoarea semnificatie:

First -deplaseaza cursorul la prima inregistrare din tabel

Prior -deplaseaza cursorul la inregistrarea precedenta

Next -deplaseaza cursorul la inregistrarea urmatoare

Last -deplaseaza cursorul la ultima inregistrare din tabel

Insert -insera la pozitia curenta o inregistrare noua

Delete -sterge inregistrarea curenta

Edit -seteaza baza de date in starea Edit(permite scrierea datelor)

Post -scrie in baza de date modificarile efectuate

Cancel -anuleaza modificarile efectuate

Refresh -anuleaza tamponul actual de memorie si creaza un tampon nou

(rescrie datele din tabel intr-un tampon de memorie nou)

TDBNavigator se utilizeaza doar impreuna cu alte controale utilizate

pentru prezentarea datelor(TDBGrid,TDBEdit,TDBImage etc.).

Pentru a controla paleta de butoane afisate,se poate utiliza proprietatea

VisibleButtons.Pentru a exclude un buton setati butonul respectiv False

(Exemplu : nbPost=False).

Butoanele Edit,Post si Delete permit efectuarea de operatii definitive

asupra bazei de date.Utilizati cu atentie aceste butoane.Scrierea datelor

se va efectua doar dupa inchiderea aplicatiei,astfel incat aveti timp

suficient sa reverificati modificarile efectuate.Daca doriti sa utilizati

DBNavigator doar pentru afisarea datelor,este mai bine sa inactivati

aceste butoane pentru a nu fi apasate din greseala.Atunci cand efectuati

modificari frecvente,este bine sa aveti in permanenta si o copie de sigu-

ranta a tabelului initial.

EXEMPLU: (vezi si Prj69)

Salvati o fila noua si proiectul in Prj69.Adaugati un obiect TDataSource,

un obiect TTable,un obiect TDBGrid si un obiect TDBNavigator.

Selectati TTable si setati Databasename=DBDEMOS,TableName=EMPLOYEE.DB si

Active=True.Apoi alegeti DataSource1 si setati DataSet=Table1.

Selectati DBGrid1 si setati DataSource=DataSource1.

Selectati TDBNavigator si setati DataSource=DataSource1

Tastati F9 si executati aplicatia.

Utilizati butoanele pentru a va deplasa in tabel pana la litera numelui

d-voastra,apoi apasati butonul Insert(marcat cu +).In tabel se va include

o inregistrare noua,libera.Introduceti numele,prenumele si datele perso-

nale,apoi apasati butonul Post(marcat cu o pipa) si inchideti aplicatia.

La urmatoarea executie,cu Run,numele d-voastra va figura in tabel,printre

angajatii firmei.Daca doriti sa stergeti intregistrarea,deplasati cursor-

ul la pozitia dorita si apasati butonul Delete(maracat cu -).

Obiectul contine si cateva metode si evenimentele BeforeAction si

OnClick,care pot fi utilizate pentru a adauga noi proceduri sau noi

functionalitati initializate de apasarea unui anumit buton.

Pentru efectuarea operatiilor preliminare se utilizeaza tamponul de memo-

rie din DataSource.Operatia Refresh,nu face decat sa reactualizeze acest

tampon de memorie.Post si Delete actioneaza direct asupra bazei de date.


-81- Data Controls - TDBText

TDBText este un obiect special conceput pentru prezentarea unei singure

celule din tabel(DataField).Este similar cu un obiect TLabel standard,dar

dar utilizeaza un component de tip DataSource pentru preluarea datelor.

Datele afisate nu pot fi modificate (interfata ideala cu utilizatorul).

Datele afisate sunt cele situate la pozitia actuala a cursorului din

DataSource,pentru coloana specificata prin proprietatea DataField.Datele

afisate se modifica o data cu deplasarea cursorului in DataSource.Pentru

deplasare in baza de date,se poate utiliza un TDBNavigator legat de

DataSource.

Obiectele din acest tip se utilizeaza fie pentru a economisi spatiu in

interfata cu utilizatorul,fie pentru a prezenta date din alt tabel decat

cel prezentat in restul obiectelor din interfata (De exemplu,utilizatorul

introduce adresa intr-un tabel de clienti,iar un obiect TDBText afiseaza

simultan,din alta baza de date,codul postal pentru adresa respectiva).

Se pot utiliza astfel de obiecte si pentru a afisa comparativ datele

similare preluate din mai multe tabele (Exemplu: pretul unui produs in

diverse oferte electronice din retea).

Dintre proprietati,pe langa DataSource si DataField,utilizate pentru

preluarea datelor,puteti utiliza proprietatea AutoSize in cazul in care

obiectul va prelua succesiv date cu fonturi diferite.In acest caz,daca

AutoSize este True,obiectul se va redimensiona automat in functie de

atributele datelor preluate.

Metodele nu prezinta facilitati deosebite,in schimb TDBText este

proiectat cu un numar destul de mare de evenimente,care permit o gama

larga de aplicatii: efecte de clipire sau de schimbare a culorii,schim-

barea fonturilor,preluarea automata a datelor,compararea automata a

datelor cu un sablon fix,filtrarea datelor,reformatarea datelor etc.

Cea mai simpla aplicatie,afiseaza selectiv un anumit tip de data:

EXEMPLU: (vezi si Prj70)

Salvati o fila noua si proiectul in Prj70.Adaugati un obiect DataSource

un obiect TTable,un obiect TDBNavigator si 3 obiecte TDBText.

Selectati Table1 si setati Databasename=DBDEMOS,TableName=PARTS.DB si

Active=True.Selectati DataSource1 si setati DataSet=Table1.

Selectati DBNavigator1 si setati DataSource=DataSource1.

Selectati DBText1: -setati DataSource=DataSource1 si DataField=Description

Utilizati Color si Font pentru a obtine aspectul grafic dorit.

Selectati DBText2: -setati DataSource=DataSource1 si DataField=Cost

Alegeti culoarea si fontul dorit.

Selectati DBtext3: -setati DataSource=DataSource1 si DataField=VendorNo

Alegeti Color si Font in functie de preferinte.

Eventual,adaugati cate un camp TLabel care explica ce contine fiecare

obiect DBText.Tastati F9 si executati obiectul.

Din DBNavigator nu sunt utile decat butoanele pentru deplasare.Nu se

pot edita campurile dar se pot utiliza butoanele Insert si Delete.Pentru

a evita stergerea nedorita a unor inregistrari,este mai bine sa inactivati

ultimele patru butoane.

Daca datele sunt preluate dintr-o baza de date mai mare,puteti utiliza

in loc de TTable un obiect TQuery si o formula de comanda SQL cat mai

restrictiva.De exemplu,puteti realiza un filtru care sa excluda toate

inregistrarile mai vechi de o luna.Similar,puteti realiza un filtru care

mascheaza toate datele care nu respecta un anumit format,etc...


-82- Data Controls - TDBEdit

TDBEdit este un obiect similar cu TDBText,dar permite si editarea

datelor afisate.Este conceput pentru aplicatii in care exista o inter-

actiune intre utilizator si baza de date.Se utilizeaza mai ales pentru

a actualiza anumite campuri de date,dintr-un tabel.La fel ca TDBText,

utilizeaza un obiect de tip DataSource pentru a prelua datele si afiseaza

pozitia curenta a cursorului din DataSource,pentru coloana specificata

prin DataField.Navigarea in baza de date se poate face cu TDBNavigator.

TDBEdit afiseaza o singura linie de text,din tabelul selectat in Data-

Source.La fel ca si TMaskEdit,TDBEdit poate utiliza un sablon (o masca)

pentru a forta editarea datelor dupa un anumit format predefinit.

Pe langa proprietatile DataSource si DataField utilizate pentru pre-

luarea datelor,TDBEdit contine si proprietatea ReadOnly care permite sau

interzice editarea datelor afisate.Daca setati proprietatea ReadOnly la

valoarea True,TDBEdit va fi echivalent cu un obiect TDBText.

Metodele (in principal mostenite) si evenimentele nu ofera functio-

nalitati deosebite fata de TDBText.Practic,toate metodele proprii sunt

implicite si nu pot fi apelate direct.

Se prefera acest tip de obiect,atunci cand doriti ca utilizatorul sa

poata efectua modificari asupra datelor din tabel.

EXEMPLU: (vezi si Prj71)

Salvati o fila noua si proiectul in Prj71.Adaugati un obiect TDataSource,

un obiect TTable,un obiect TDBNavigator si 3 obiecte TDBEdit.

Selectati Table1 si setati: DatabaseName=DBDEMOS,Tablename=CUSTOMER.DB si

Active=True.Selectati DataSource1 si setati DataSet=Table1.

Selectati DBNavigator1 si setati DataSource=DataSource1.

Selectati DBEdit1 si setati: DataSource=DataSource1 si DataField=Company.

Alegeti Color si Font dupa preferintele personale.

Selectati DBEdit2 si setati: DataSource=DataSource1 si DataField=Addr1.

Setati preferintele pentru fonturi si culori.

Selectati DBEdit3 si setati DataSource=DataSource1 si DataField=Phone.

Alegeti culorile si fonturile dorite.

Tastati F9 si executati aplicatia.Puteti utiliza butoanele pentru a

naviga in baza de date.Puteti utiliza campurile DBEdit pentru a modifica

dupa bunul plac,datele din tabel.

Daca doriti sa preluati si sa sintetizati intr-o fila separata doar o


Yüklə 1,42 Mb.

Dostları ilə paylaş:
1   ...   6   7   8   9   10   11   12   13   ...   16




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin