You are on page 1of 49

Visual FoxPro

Baza de date GESTIUNE


Tabela CLIENTI
cod_client den_client localitate
1 ALFA SRL IASI
2 GAMA SA BACAU
3 BETA SRL SUCEAVA
4 DELTA SRL BACAU
5 EPSILON SA IASI
6 SIGMA SA PIATRA NEAMT
7 THETA SRL BACAU
8 OMEGA SA IASI
9 PI SRL BACAU
10 OMICRON SRL BACAU
Tabela FACTURI_EMISE
Nr_factura cod_client data valoare
100 1 01/10/05 25150000
101 3 01/15/05 2500000
102 2 01/15/05 52500000
103 2 01/16/05 25000000
104 3 01/16/05 2000000
105 6 01/16/05 80000000
106 9 01/16/05 47000000
107 10 01/16/05 30000000
108 1 01/16/05 42000000
109 5 01/16/05 14000000
110 6 01/16/05 2000000
111 8 01/17/05 92500000
112 1 01/20/05 3000000
113 2 01/20/05 1500000
114 5 01/21/05 23000000
115 2 01/22/05 11000000
116 7 01/25/05 3000000
117 9 01/25/05 19000000
118 10 01/25/05 23000000
119 2 01/25/05 15500000
120 2 01/27/05 16250000
121 1 01/27/05 17500000
122 6 01/28/05 55000000
123 3 01/28/05 8200000
124 5 01/29/05 38500000
125 3 01/30/05 26000000

1
126 7 01/30/05 6500000
127 8 01/31/05 37400000
128 1 02/01/05 13000000
129 9 02/01/05 55000000
130 4 02/02/05 72000000

Tabela PRODUSE_DIN_FACTURI_EMISE
Nr_factur
cod_produs Pret_unitar cantitate
a
11 100 62000 100
19 100 52000 100
20 100 55000 250
12 101 10000 250
14 102 125000 200
15 102 110000 250
17 103 250000 100
12 104 10000 200
25 105 80000 1000
15 106 110000 200
17 106 250000 100
14 107 125000 100
21 107 70000 250
23 108 35000 200
24 108 70000 500
18 109 15000 200
20 109 55000 200
13 110 10000 200
16 111 130000 500
22 111 55000 500
13 112 10000 300
18 113 15000 100
23 114 35000 200
25 114 80000 200
15 115 110000 100
18 116 15000 200
22 117 55000 200
25 117 80000 100
12 118 10000 100
13 118 10000 100
15 118 110000 200
11 119 62000 250
21 120 65000 250
24 121 70000 250

2
22 122 55000 1000
25 123 82000 100
14 124 125000 100
16 124 130000 200
16 125 130000 200
21 126 65000 100
11 127 62000 200
14 127 125000 200
16 128 130000 100
20 129 55000 1000
15 130 110000 200
17 130 250000 200
Tabela PRODUSE
Cod_produ
den_produs unit_masura
s
11 vopsea alba kg
12 Var kg
13 Nisip kg
14 tabla aluminiu kg
15 geam sticla 5 mm mp
16 geam sticla 10 mm mp
17 tabla inox kg
18 Ciment kg
19 Adeziv kg
20 vopsea neagra kg
21 Diluant litru
22 plasa sirma kg
23 cuie 10 cm kg
24 vopsea verde kg
25 var lavabil cutie

Crearea bazelor de date în Visual FoxPro

Visual FoxPro este un SGBD care aplică principiile teoriei relaţionale, dispunând de
facilităţile unui SGBD relaţional performant. În Visual FoxPro se materializează conceptul de
bază de date (Database Container) în accepţiunea unei colecţii de tabele sau relaţii (Tables) între
care se realizează legături permanente prin intermediul cheilor primare şi străine. Se păstrează,
din raţiuni de compatibilitate, comanda SET RELATION care permite stabilirea de relaţii
temporare. Baza de date foloseşte un fişier cu extensia .DBC. De asemenea, aceasta posedă un
dicţionar de date (fişier cu extensia .DCT) şi un fişier index (cu extensia .DCX).
Elementul central al bazei de date este tabela (table). O tabelă corespunde noţiunii teoretice
de relaţie. Coloanele tabelei sunt denumite atribute sau câmpuri (fields). Noţiunii de tuplu îi
corespunde cea de înregistrare (record). Fiecare înregistrare are un număr intern (recno) care
depinde de ordinea "fizică" în care înregistrările au fost adăugate în tabelă. O mare parte din
comenzile SGBD-ului au ca domeniu toate înregistrările tabelei, în timp ce altele doar

3
înregistrarea curentă. Caracteristic categoriei de SGBD-uri din care face parte FoxPro este
prezenţa unui pointer intern (un fel de contoar) care memorează numărul înregistrării curente.
Informaţii despre înregistrări sunt furnizate de funcţii, precum:
• Recno() - furnizează numărul intern al înregistrării curente;
• Reccount() - furnizează numărul total de înregistrări din tabelă.
O bază de date FoxPro, ca orice bază de date relaţională, este alcătuită din una sau mai multe
tabele puse în legătură prin intermediul cheilor străine. Atât declararea cheilor primare, cât şi
acelor străine (şi implicit a restricţiilor referenţiale) se bazează în VFP pe indecşi asociaţi
tabelelor care sunt firesc incluşi în baza de date.
În Visual FoxPro o bază de date este alcătuită nu numai din tabele, dar cuprinde şi:
• tabele derivate (views) care pot fi locale sau la distanţă (remote - sunt utilizate pentru a
face legătura cu baze de date gestionate de alte SGBD-uri);
• conexiuni cu alte baze de date;
• proceduri stocate care sunt blocuri de program păstrate în dicţionarul de date. Cele mai
utlizate tipuri de proceduri stocate în VFP sunt funcţii şi proceduri pentru validarea
modificărilor în baza de date, funcţii pentru calcularea valorilor implicite ale unor
atribute şi declanşatoare (triggere).
Numele tabelelor, atributele care o compun, restricţiile de cheie, regulile de validare la nivel
de atribut şi înregistrare, legăturile permanente dintre tabele (cheile străine), declanşatoarele,
precum şi celelalte proceduri stocate sunt păstrate într-un fişier special, denumit dicţionar de date
care în VFP are extensia .DBC (DataBase Container). Tabelele au extensia .DBF, iar indecşii
.CDX.
Mecanismul de bază în declararea domeniilor de valori ale unui atribut are la bază
precizarea tipului şi lungimii fiecărui câmp dintr-o tabelă.

Tipuri de date Visual FoxPro


Datele sunt stocate pe suporturile de stocare într-un anumit format, în funcţie de tipul
fiecăruia. Tipul unei date este o caracteristică ce stabileşte modul în care data este înregistrată pe
suportul de memorare şi modul în care este interpretată şi prelucrată.
În VFP există o serie de tipuri de date predefinite, însă există posibilitatea definirii de către
utilizator a altor tipuri de date pe baza celor deja existente. Tipurile de date predefinite
implementate în VFP sunt numeric, şir de caractere, logic (boolean), dată calendaristică, memo şi
general.
Tipul Character (şir de caracter) este cel mai uzual tip de date folosit în majoritatea
tabelelor. Câmpurile caracter pot stoca între 1 şi 254 caractere. Pot conţine orice caracter ASCII.
Pentru date de dimensiuni mai mari se recomandă câmpurile memo.
Exemplu: Den_client, C, 20
Localitate, C, 15
Tipul Numeric (real, în virgulă fixă) descrie datele reprezentate în virgulă fixă. Lungimea
maximă este de 20 de cifre, din care maxim 19 poziţii zecimale, fiecare cifră necesitând un
spaţiu de stocare de un octet. În afară de cifre se pot folosi semnele +/- şi marca zecimală.
Exemplu: Cod_cl, N,3
Pret-unit, N,11,2
N, 11, 2 se interpretează astfel: 8 cifre pentru partea întreagă, 2 cifre pentru partea zecimală
şi marca zecimală.
Tipul de dată Numerc este tipul clasic, implementat şi în vesiunile anterioare de FoxPro,
VFP oferind şi următoarele tipuri de date numerice:
• Tipul Integer este destinat reprezentării numerelor întregi în cod complementar pe patru
octeţi.
Exempul: MARCA, I, 6
• Tipul Float (real, în virgulă mobilă) este destinat reprezentării numerelor foarte mici
sau foarte mari. Este o reprezentare pe 8 octeţi.

4
• Tipul Double (real, dublă precizie) presupune repreyentarea datelor numerice în virgulă
mobilă dublă precizie şi ste destinat reprezentării numerelor foarte mari sau foarte mici.
• Tipul Currency (format monetar) este utilizat pentru memorarea datelor referitoare la
tranzacţii în unităţi monetare.
Tipul Dată calendaristică este implementat prin Date (dată) şi DateTime (dată-oră)
• Date este utilizat pentru memorarea datelor calendaristice cuprinse în domeniul
01/01/100 şi 31/12/9999. Datele calendaristice se pot afişa în diferite formate stabilite
prin comanda SET DATE.
• DateTime permite o gestiune mai analitică a timpului prin includerea alături de date
calendaristică şi a momentelor de timp din cadrul unei zile. Ora este stocată în formatul
HHMMSS, unde HH reprezintă ora în formatul de 24 de ore., ora variind în domeniul
00:00:00 a.m. şi 11:59:59 p.m.
Exemplu:
Data_com, D
Data_nast, DT
Tipul Logical (logic) desemnează date ce nu pot lua decât două valori: True (adevărat) şi
Flase (fals). Are lungimea de un caracter. Pentru adevărat este asociată litera T sau cifra 1, iar
pentru fals litera F sau cifra 0.
Exemplu: taxabil, L, 1.
Tipul Memo se foloseşte pentru date tip caracter care depăşesc 254 de caractere şi prevede
o dimensiune de stocare variabilă de la înregistrare la alta. Un bloc reprezintă un număr fix de
caractere pe care FoxPro le rezervă pentru un câmp memo. În mod prestabilit, FoxPro utilizează
64 de octeţi pentru un bloc. FoxPro stochează valorile câmpurilor memo într-un fişier distinct
care are extensia .FPT şi cu acelaşi nume cu al tabelei. Utilizând câmpurile memo se pot memora
nu numai texte, ci şi alte informaţii: fişiere executabile DOS, imagini, biţi de sunet etc.
Tipul General apare începând cu versiunea FoxPro 2.5 sub Windows. Într-un câmp de tip
general pot fi păstrate obiecte de diferite tipuri: grafic, imagine, sunet, foaie de calcul, adică
obiecte create cu alte aplicaţii Windows. Datorită folosirii mecanismului OLE (Object Linking
and Embedding = legare şi încorporare de obiecte), un obiect poate fi păstrat într-un câmp de tip
general prin legare sau prin încorporare. În ambele cazuri între baza de date şi aplicaţia sursă cu
care a fost creat obiectul se realizează o legătură. Această legătură permite modificarea
obiectelor încorporate sau legate la baza de date, direct din FoxPro (apelarea aplicţiei sursă cu
care se modifică obiectul se face din FoxPro). În cazul acestei relaţii FoxPro este considerat
client pentru că foloseşte obiecte create cu alte aplicăii, acestea fiind servere.Un câmp General
este un câmp Memo specializat. FoxPro stochează câmpurile General în acelaşi fişier .FPT
utilizat de celelalte câmpuri Memo ale tabelului, însă acestea nu sunt utilizate în acelaşi fel.
Câmpurile General sunt utilizate în primul rând pentru stocarea referinţelor la obiecte OLE
legate. Prin legare obiectul nu este inclus fizic în document, ci se memorează doar referinţele
despre obiect necesare localizării şi descrierii obiectului. Prin încorporare o copie a obiectului
este inclusă fizic în document.
În VFP stocarea datelor se realizează de cele mai multe ori în tabelele care compun baza de
date. În afară de acestea, în VFP se pot utiliza variabile sau constante. Dacă datele memorate în
tabele sunt stocate pe disc şi le putem considera permante deoarece ele nu se pierd între două
sesiuni de lucru, datele memorate în variabile sunt stocate în memoria internă a calculatorului şi
au un caracter temporar deoarece la închiderea sesiunii de lucru ele vor fi pierdute. Variabilele şi
constantele sunt utilizate mai ales în cadrul programelor.
Variabilele de memorie pot fi simple sau structurate în tablouri. O variabilă are asociată o
locaţie de memorie în care se poate scrie sau citi o valoare. Referirea la o locaţie de memorie în
vederea citirii/scrierii unei valori se face doar prin nume, în cazul variabilelor simple de memorie
şi prin nume urmat de indicii care indică numărul liniei şi numărul coloanei (dacă este un tablou
bidimensional) pentru tablourile de date. De exemplu, tabloul IMP_SAL (2,3) poate stoca 6
valori în acelaşi timp.

5
Definirea unei variabile de memorie se poate face prin simpla atribuire a unei valori, iar în
cazul tablourilor de date se utilizează comanda DIMENSION.
Exemplu:
SAL_BRUT=1000000
DIMENSION IMP_SAL(2,3)
IMP_SAL(1,1)=0.15
IMP_SAL(1,2)=0.20
IMP_SAL(1,3)=0.22
IMP_SAL(2,1)=0.25
IMP_SAL(2,2)=0.30
IMP_SAL(2,3)=0.40
? SAL_BRUT*IMP_SAL(2,1)
În plus, FoxPro dispune de numeroase funcţii de conversie care dau posibilitatea
transformării datelor de diferite tipuri astfel încât acestea să fie compatibile pentru a fi utilizate în
expresii. De exemplu, conversia este necesară la specificarea expresiei indexului compus pentru
o tabelă, expresie care să combine o dată de tip şir de caractere cu date numerice sau date de tip
şi de caractere cu date calendaristice. În astfel de expresii toate datele trebuie să fie compatibile
din punct de vedere al tipului de dată.
Cele mai utilizate funcţii de conversie a tipului de dată sunt:
• Conversia datelor numerice în date de tip şir de caractere
STR(expresie numerică [,lungime [, număr_zecimale]]), în care lungime reprezintă numărul
de caractere pe care-l va conţine şirul de caractere returnat, iar număr_zecimale num[rul de
cifre de la partea fracţionară care-l va conţine şirul de caractere returnat.
• Conversia datelor de tip şir de caractere în date numerice
VAL(expresie_caracter)
• Conversia datelor calendaristice în date de tip şir de caractere
DTOC(expresie_dată[,1], în care parametrul '1' permite conversia unei date calendaristice
într-un şir de caractere potrivit pentru indexare, în sensul că se păstrază succesiunea
cronologică a înregistrărilor din tabelă.
• Conversia datelor de tip şir de caractere în date calendaristice
CTOD(expresie_caracter)
Crearea unei baze de date se realizează cu comanda CREATE DATABASE.

Crearea bazei de date


O bază de date poate fi creată în oricare din cele trei moduri de lucru ale VFP: asistat,
prin comenzi sau prin program.
Cel mai simplu mod de lucru este cel asistat. Din proiect se alege cadrul de pagină Data.
După selectarea pictogramei Databases se acţionează butonul New, iar dintre cele două butoane
afişate apoi - DataBase Wizard şi New Database - se execută clic pe al doilea. În continuare
sistemul solicită numele bazei de date - în cazul nostru Gestiune (salvată într-un fişier cu
extensia .DBC). Drept rezultat, pe ecran apare proiectantul bazei de date Database Designer. În
continuare, apelând la butonul New Table se trece la definirea structurii fiecărei tabele. Definirea
minimală a structurii presupune indicarea numelui fiecărui atribut, a tipului şi lungimii acestuia.
Pentru atributele de tip numeric real se poate preciza şi numărul de poziţii zecimale.

6
Inserează un câmp
nou deasupra
câmpului selectat

Şterge câmpul
selectat din
tabelă

Fig. nr..1. Caseta de dialog pentru crearea tabelelor în Visual FoxPro utilizând Table
Designer

Din cele trei cadre de pagină - Fields, Indexes şi Table este utilizat mai întâi primul. Cadrul
de pagină Fields este utilizat pentru definirea câmpurilor din tabelă, prin intermediul
următoarelor elemente:
• Name specifică numele câmpului. Spaţiile nu sunt acceptate. În Visual FoxPro numele
atributelor asociate tabelelor din baza de date container (Database Container) pot depăşi
10 caractere. Tabelele independente (free tables) trebuie să respecte însă limita de 10
caractere pentru numele câmpurilor, specifică versiunilor anterioare lui 3.0.
• Type specifică tipul câmpului.
• Width specifică numărul de caractere sau de cifre pentru fiecare câmp.
• Decimal precizează numărul de cifre de la dreapta punctului zecimal. Se precizează doar
la datele numerice, cu excepţia celor de tip întreg
• Index specifică dacă valorile câmpului sunt ordonate crescător sau descrescător.
• NULL - când este specificat, atributul respectiv poate accepta valori nule.
Imediat după declararea ultimului câmp, după salvarea structurii, pe ecran apare mesajul
"Input data records now?" . Dacă se răspunde cu Yes atunci se pot introduce înregistrări în
tabela nou creată.
ATENŢIE! Este recomandat ca introducerea înregistrărilor să se facă după definirea tuturor
tabelelor, a restricţiilor şi a relaţiilor dintre ele, pentru a asigura astfel consistenţa şi
corectitudinea datelor introduse.

Declararea cheii primare


Atât în mecanismul de declarare a cheilor primare, cât şi în cel de declarare a cheilor
străine (relaţii sau legături permanente între tabele), un rol esenţial îl au indecşii.
Declararea cheii primare în VFP se face creând un index de tip primar.Un index are un
nume (tag) şi o expresie pe baza căruia este construit. În expresia indexului primar se introduce
atributul (sau expresia de atribute dacă cheia primară este compusă).
Declararea indecşilor în modul asistat se realizează prin utilizarea cadrului de pagină
Indexes al proiectantuuli de tabele. Pentru tabela Clienţi numele indexului primar este
cod_client, tipul acestuia este Primary, iar expresia de indexare este alcătuită din atributul-cheie
primară al tabelei, cod_client. Săgeţile din stânga numelui indexului arată dacă indexul este în
ordine ascendentă sau descendentă.
Tipul indexului poate fi obişnuit (regular), unic sau candidat. Regular indică faptul că
VFP stochează în index valoarea generată de expresia indexului pentru fiecare linie a tabelului.
Dacă mai multe înregistrări au aceeaşi expresie, FoxPro stochează expresia de mai multe ori, cu

7
pointeri distincţi pentru fiecare înregistrare. În cazul tipului Unique sunt incluse doar valorile
distincte ale expresiei de construire a indexului. Dacă mai multe înregistrări generează aceeaţi
valoare a expresiei indexului, este stocată numai prima întâlnită. Candidate indică faptul că
expresia indexului respectiv este o cheie candidat (cheie alternativă), deci creează un index unic
care include fiecare înregistrare din tabel.
FoxPro nu limitează expresiile indecşilor la un singur câmp. Orice combinaţie de câmpuri
poate fi folosită drept expresie a unui index. Pentru a crea o expresie complexă se foloseşte
caseta de text Expression din Table Designer.
Dezavantajul comenzii INDEX este că nu permite declararea unui index primar şi,
implicit, a cheii sale de indexare ca şi cheie primară a tabelei curente. Din acest punct de vedere
de mare folos poate fi comanda SQL ALTER TABLE. Spre exemplu, pentru tabela CLIENTI se
poate crea indexul cod_client ce poate fi declarat index primar şi implicit atributul cod_client
este declarat cheie primară astfel:
ALTER TABLE CLIENTI ADD PRIMARY KEY COD_CLIENT TAG COD_CLIENT
sau
ALTER TABLE CLIENTI ALTER COLUMN COD_CLIENT N(5) PRIMARY KEY.
Indecşii creaţi prin ALTER TABLE fac obligatoriu parte din indexul structurat al tabelei.

Declararea legăturilor permanente între tabele şi a restricţiilor referenţiale


Şi declararea restricţiilor referenţiale se bazează pe indecşi. In baza de date luată ca
exemplu pentru tabela Clienţi cheia primară este cod_client, pentru tabela Facturi_emise este
număr_factură, pentru tabela Produse este cod_produs, iar pentru tabela
Produse_din_facturi_emise este i, o cheie compusă din atributele cod_produs şi număr_factură.
Restricţiile referenţiale se instituie între tabelele Facturi_emise şi Clienţi, între tabelele
Produse_din_facturi_emise şi Produse, respectiv între tabelele Produse_din_facturi_emise şi
Facturi_emise:
• între tabelele Facturi_emise (copil)şi Clienţi (părinte) atributul de legătură este cod_client;
• între tabelele Produse_din_facturi_emise (copil) şi Produse (părinte) atributul de legătură
este cod_produs;
• între tabelele Produse_din_facturi_emise (copil) şi Facturi_emise (părinte) atributul de
legătură este număr factură.
Pentru stabilirea legăturilor permanente (suportul restricţiilor referenţiale) este necesară
crearea în tabelele părinte a indecşilor primari şi în tabelele copil a indecşilor de tip Regular
pentru fiecare atribut cheie străină. Pentru tabela Produse_din_facturi_emise, de exemplu, acest
lucru este reflectat în fig. nr. Pentru simplificare, numele indecşilor obişnuiţi au acelaşi nume ca
şi al atributului din expresie.

8
Fig.nr.2. Indecşii tabelei Produse_din_facturi_emise
Cel mai simplu mod de creare a legăturilor permanente între tabele este pornind de la
proiectantul bazei de date (Database Designer) printr-o sinplă "tragere" de mouse între numele
indexului primar din tabela părinte şi numele indexului regular (obişnuit) corespondent din
tabela copil. Fig. nr. ilustrează acest lucru.

Fig. nr. 3. Legăturile permanente între tabelele bazei de date


Linia care uneşte tabelele Clienţi şi Facturi_emise este simplă înspre Clienţi şi trifurcată
spre tabela Facturi_emise. Aceasta înseamnă că relaţia între cele două tabele este de tip one-to-
many (una la mai multe).
Pentru declararea regulilor de urmat într-o restricţie referenţială se realizează un dublu-
clic pe linia dintre cele două tabele, în urma căruia va apărea fereastra Edit Relationship (vezi
fig. nr.4).

Fig. nr. 4. Fereastra Edit Relationship


Tabela părinte este Clienţi, indexul participant la relaţie fiind cod_client, iar tabela copil
este Facturi_emise, indexul participant fiind tot cod_client. După acţionarea butonului
Referential Integrity sunt definite regulile pentru:
• modificarea cheii primare în tabela părinte;
• ştergerea unei înregistrări în tabela părinte;
• inserarea unei înregistrări sau modificarea valorii cheii străine în tabela copil.
În constructorul de integritate referenţială prezentat în figura nr. s-au instituit următoarele reguli:
• modificarea valorii cod_client în tabela Clienti atrage modificarea în cascadă a tuturor
liniilor-copil (linii în care cod_client avea valoarea dinaintea modificării) în tabela
Facturi_emise;
9
• modificarea valorii nr_factura în tabela Facturi_emise atrage modificarea în cascadă a
tuturor liniilor-copil în tabela Produse_din_facturi_emise;
• modificarea valorii cod_produs în tabela Produse atrage modificarea în cascadă a
tuturor liniilor-copil în tabela Produse_din_facturi_emise;
• nu se şterg linii din tabela Clienţi dacă există linii-copil corespondente în tabela
Facturi_emise;
• nu se şterg linii din tabela Facturi_emise dacă există linii-copil corespondente în
tabela Produse_din facturi_emise;
• nu se şterg linii din tabela Produse dacă există linii-copil corespondente în tabela
Produse_din facturi_emise;
• nu se permite inserarea sau modificarea unei linii în tabela Facturi_emise dacă
valoarea cheii străine, cod_client nu există în tabela părinte Clienţi;
• nu se permite inserarea sau modificarea unei linii în tabela
Produse_din_facturi_emise dacă valoarea cheii străine, nr_factură nu există în tabela
părinte Facturi_emise;
• nu se permite inserarea sau modificarea unei linii în tabela Produse_din facturi_emise
dacă valoarea cheii străine, cod_produs nu există în tabela părinte Produse.

Fig. nr.5. Constructorul de integritate referenţială

Crearea bazei de date prin comenzi/program


Crearea bazei de date prin program se poate realiza prin comenzile CREATE
DATABASE şi CREATE TABLE.

CREATE DATABASE GESTIUNE

CREATE TABLE CLIENTI


(COD_CLIENT N(3), DEN_CLIENT C(15), LOCALITATE C(15),;
PRIMARY KEY COD_CLIENT TAG COD_CLIENT)

CREATE TABLE PRODUSE


(COD_PRODUS N(4), DEN_PRODUS C(25),UNIT_MASURA C(5),;

10
PRIMARY KEY COD_PRODUS TAG COD_PRODUS)

CREATE TABLE FACTURI_EMISE


(NR_FACTURA N(8), COD_CLIENT N(3), DATA D, VALOARE N(10),;
PRIMARY KEY NR_FACTUR[ TAG NR_FACTURA,;
FOREIGN KEY COD_CLIENT TAG COD_CLIENT,;
REFERENCES CLIENTI TAG COD_CLIENT)

CREATE TABLE PRODUSE_DIN_FACTURI_EMISE


(COD_PRODUS N(4), NR_FACTURA N(8), PRET_UNITAR N(6), CANTITATE N(4),;
PRIMARY KEY STR(COD_PRODUS)+STR(NR_FACTURA) TAG I;
FOREIGN KEY NR_FACTURA TAG NR_FACTURA;
REFERENCES FACTURI_EMISE TAG NR_FACTURA;
FOREIGN KEY COD_PRODUS TAG COD_PRODUS;
REFERENCES PRODUSE TAG COD_PRODUS)
Prin comanda CREATE TABLE nu pot fi definite restricţiile referenţiale, ci doar
precizate relaţiile permanante dintre tabele. Definirea modului de reacţie la adăugarea
/modificarea în tabelele copil sau modificarea /ştergerea în tabelele părinte presupune utilizarea
comenzii CREATE TRIGGER.
De exemplu, în tabela FACTURI_EMISE dorim să actualizăm nr_factură, adăugând doar
facturi cu număr mai mare sau egal cu 120.
USE FACTURI_EMISE
CREATE TRIGGER ON FACTURI_EMISE FOR UPDATE AS
NR_FACTURA>=1200
REPLACE NR_FACTURA WITH 90 && se afişează un mesaj de eroare “Trigger
failed”
REPLACE NR_FACTURA with 130

Structura unei tabele din baza de date poate fi modificată prin comanda MODIFY
STRUCTURE, iar vizualizarea acesteia se poate face cu comanda LIST STRUCTURE.
Deschiderea unei baze de date se face cu comanda OPEN DATABASE care are următoarea
sintaxă:
OPEN DATABASE [FileName | ?]
[EXCLUSIVE | SHARED]
[NOUPDATE]
[VALIDATE]
Accesul la datele din tabelele bazei de date este permis numai după deschiderea lor, adică
după asocierea zonei de lucru prin comanda USE. În Visual Fox Pro formatul acestei comenzi
este:
USE [[DatabaseName.]Table | SQLViewName | ?]
[IN nWorkArea | cTableAlias]
[ONLINE]
[ADMIN]
[AGAIN]
[NOREQUERY [nDataSessionNumber]]
[NODATA]
[INDEX IndexFileList | ?
[ORDER [nIndexNumber | IDXFileName
| [TAG] TagName [OF CDXFileName]
[ASCENDING | DESCENDING]]]]
[ALIAS cTableAlias]
[EXCLUSIVE]

11
[SHARED]
[NOUPDATE]
Închiderea tabelei se face tot prin comanda USE sau prin comenzile CLOSE TABLES,
CLOSE DATABASES sau CLOSE ALL.
Fiecare tabel al bazei de date are asociată o zonă de lucru prin intermediul căreia are loc
accesul la date. Gestionarea zonelor de lucru se realizează prin comanda SELECT care are
următoarea sintaxă:
SELECT nWorkArea | cTableAlias
Exemplu:
SELECT 1
USE CLIENTI
SELECT 2
USE FACTURI_EMISE
SELECT 3
USE PRODUSE
Ultima zonă deschisă se numeşte zonă curentă. Asupra tabelei din zona curentă au efect
comenzile date. Dacă se utilizează câmpuri ale tabelelor din alte zone, numele câmpurilor va fi
precedat de un prefix ce reprezintă numele sau alias-ul tabelului.
Exemplu:
SELECT 1
USE clienti
SELECT 2
USE facturi_emise
LIST FOR facturi_emise.cod_client=clienti.cod_cl

Actualizarea bazelor de date

Actualizarea unei baze de date (respectiv a unei tabele) se realizează după deschiderea
acesteia şi are în vedere trei acţiuni:
• adăugarea de noi înregistrări la cele existente în tabelă;
• ştergerea unor înregistrări;
• modificarea valorii unor atribute.

1.1. Adăugarea de înregistrări


Adăugarea de înregistrări se poate face în două moduri în funcţie de poziţia pe care o va
ocupa noua înregistrare în baza de date:
• adăugarea de înregistrări noi la sfârşitul bazei de date
• introducerea de înregistrări noi în interiorul bazei de date.
Prima metodă se realizează prin comenzile APPEND, APPEND FROM şi APPEND FROM
ARRAY. La comanda APPEND informaţiile sunt furnizate de utilizator, în mod interactiv.
Excepţie face clauza BLANK când se adaugă o înregistrare vidă la sfârşitul bazei de date.
Comanda APPEND FROM se foloseşte când informaţiile sunt luate dintr-o altă bază de date sau
din alt fişier. Comanda APPEND FROM ARRAY preia informaţiile dintr-un masiv (tablou) şi le
introduce în baza de date.
Cea de-a doua metodă perimite inserarea de înregistrări în interiorul bazei de date, folosind
comanda INSERT. Comanda INSERT are ca efect inserarea unei înregistrări noi după
înregistrarea curentă. Clauza BEFORE din comandă permite inserarea unei înregistrări înaintea
înregistrării curente.
Utilizând modul asistat, adăugarea de înregistrări se realizează utilizând meniul Table,
opţiunile Append New Record (CTRL/Y) sau Append Records.

12
Exemplu: Actualizaţi tabela CLIENŢI prin adăugarea unei înregistrări, a unei înregistrări vide şi
inserarea unei înregistrări vide după înregistrarea a doua a tabelei.
USE CLIENTI
APPEND
APPE BLANK
GOTO 2
INSERT BLANK

Creaţi tabela CLIENTI1 care cuprinde câmpurile COD_CLIENT şi DEN_CLIENT.


USE CLIENTI
COPY STRUCTURE EXTENDED TO INTERM
USE INTERM
LIST STRU
LIST
DELETE RECORD 3
PACK
CREATE CLIENT1 FROM INTERM
LIST STRU
APPEND FROM CLIENT
1.2. Ştergerea înregistrărilor
Ştergerea unei înregistrări se poate realiza în două etape:
• La nivel logic când înregistrarea nu este propriu-zis ştearsă din baza de date, ci ea este
marcată pentru ştergere (comanda DELETE). Există comenzi şi funcţii FoxPro care
înainte de accesarea unei înregistrări testează marcajul de ştergere al acesteia şi în
funcţie de el consideră înregistrarea absentă sau prezentă în fişier (de exemplu, funcţia
DELETED() care returnează valoarea adevărat dacă înregistrarea curentă este marcată
pentru ştergere sau fals dacă înregistrarea nu este marcată);
• La nivel fizic când înregistrarea este ştearsă efectiv din baza de date, ea nemaiputând fi
accesată sau refăcută (comanda PACK).
Marcarea pentru ştergere a uneia sau a mai multor înregistrări se face cu ajutorul comenzii
DELETE. Accesul la înregistrările marcate pentru ştergere este controlat de comanda SET
DELETED (cu sintaxa SET DELETED ON/OFF). Astfel, înregistrările marcate pentru ştergere
nu vor fi accesibile celorlalte comenzi care folosesc domeniul înregistrărilor dacă se alege
opţiunea ON a acestei comenzi.

Exemplu: Actualizaţi tabela CLIENŢI prin ştergerea clienţilor care au codul mai mare decât 7.
USE CLIENTI
CLEAR
SET DELETED OFF
DELETE FOR COD_CLIENT>7
NOTE se marchează pentru ştergere înregistrarile pentru care codul clientului este;
mare decât 7
LIST
NOTE toate înregistrările din baza de date sunt afişate, cele marcate pentru
ştergere având un asterisc în dreptul lor
USE

Exemplu: Actualizaţi tabela CLIENŢI prin ştergerea înregistrărilor al căror număr de înregistrare
este mai mare decât 8.
USE CLIENTI
DELETE FOR RECNO()>8 && sunt marcate pentru ştergere înregistrările ;

13
cu numărul de înregistrare mai mare decât 8
SET DELETED ON
LIST && înregistrările marcate pentru ştergere nu pot fi accesate prin această comandă
USE
O înregistrare marcată pentru ştergere nu este ştearsă fizic din baza de date. Eliminând
marcajul de ştergere, înregistrarea este refăcută, ea redevenind accesibilă pentru toate comenzile.
Înlăturarea marcajului de ştergere se realizează prin comanda RECALL.
Exemplu: Actualizaţi tabela CLIENTI prin ştergerea logică a înregistrărilor cu numărul de
înregistrare mai mic decât 3. După aceea refaceţi toate înregistrările marcate logic.
USE CLIENTI
DELETE FOR RECNO()<3
LIST
RECALL ALL && sunt refăcute toate înregistrările
LIST
USE
Ştergerea la nivel fizic se realizează prin comanda PACK care efectuează ştergerea fizică a
tuturor înregistrărilor marcate pentru ştergere din baza de date. În acest caz trebuie folosite
succesiv comenzile DELETE şi PACK.
Exemplu: Actualizaţi tabela CLIENŢI prin eliminarea definitivă a înregistrării numărul 4.
USE CLIENTI
DELETE RECORD 4 && se marchează pentru ştergere înregistrarea a 4-a
PACK && se şterge fizic a 4-a înregistrare
LIST
USE
O altă comanda cu privire la ştergerea înregistrărilor din baza de date este comanda ZAP
care şterge toate înregistrările din baza de date activă.
Comanda ZAP realizează ştergerea fizică a înregistrărilor din tabelele bazei de date într-o
singură etapă. Astfel secvenţa de comenzi:
USE CLIENTI
ZAP
este echivalentă cu:
USE CLIENTI
DELE ALL
PACK

Utilizând modul asistat, ştergerea înregistrărilor se realizează cu opţiunile Delete


Records..., Recall Records... şi Remove Deleted Records din meniul Table.
1.3. Modificarea conţinutului tabelelor din bazele de date
Modificarea informaţiilor stocate în baza de date se realizează cu comenzile CHANGE,
EDIT, BROWSE. Fiecare lucrează cu o fereastră de editare în care utilizatorul va modifica
informaţiile din baza de date. În modul BROWSE afişarea se face sub formă tabelară şi permite
accesul la mai multe înregistrări. În modul EDIT se afişează o singură înregistrare. Aceste
comenzi permit şi adăugarea de noi înregistrări în baza de date.
Exemplu:
USE CLIENTI
CHANGE FREEZE cod_client && în tabela CLIENTI se poate modifica doar câmpul
cod_client
CHANGE FIELDS COD_CLIENT :r && în tabela CLIENTI câmpul cod_client poate fi
vizualizat, fără a putea fi modificat.
Pe lângă modificarea manuală a conţinutului unei baze de date, FoxPro mai oferă şi o
metodă automată de modificare. Prin această metodă se pot modifica valori ale anumitor
câmpuri, calculate automat de FoxPro pe baza unor expresii furnizate de utilizator. Pentru

14
aceasta se alege opţiunea Replace Field a meniului Table pentru a fi deschisă pe ecran fereastra
cu acelaşi nume.

Fig. nr. 6. Fereastra Replace Field


Din lista ascunsă Field se selectează câmpul care va fi modificat. Valorile care vor fi
introduse în câmpul selectat vor fi precizate prin intermediul comutatorului With. Scope, For şi
While permit stabilirea înregistrărilor afectate de această comandă.

Interogarea bazelor de date


Prin interogarea bazelor de date utilizatorii pot să aibă acces la datele stocate corespunzător
cerinţelor informaţionale specifice. Comenzile de interogare cel mai des folosite sunt: LIST,
DISPLAY, LOCATE, CONTINUE, CREATE QUERY.
Cea mai simplă metodă de interogare a datelor conţinute într-o tabelă este utilizarea
comenzilor LIST sau DISPLAY. Acestea afişează conţinutul tabelei din zona de lucru curentă.
Cele două comenzi au aceeaşi sintaxă cu deosebirea că la comanda LIST domeniul implicit este
ALL, iar la DISPLAY domeniul implicit este înregistrarea curentă. De asemenea, comanda LIST
nu afişează înregistrările marcate pentru ştergere când SET DELETED ON este activ, pe când
DISPLAY le afişează. Sintaxa acestor comenzi este următoarea:
LIST
[FIELDS <expr list> | FIELDS LIKE <skel> | FIELDS EXCEPT <skel>]
[<scope>]
[FOR <expL1>]
[WHILE<expL1>]
[OFF]
[NOCONSOLE]
[NOOPTIMIZE]
[TO PRINTER [PROMPT] | TO FILE <file>]
Exemplu: Interogaţi tabela FACTURI_EMISE şi obţineţi o listă care să cuprindă date
privind numărul facturii, data şi valoarea facturilor emise pentru clientul cu codul 5. Să se
interogheze tabela până când se găseşte prima factură a cărei dată de emitere este anterioră datei
de 16 ianuarie 2005. Să se afişeze apoi doar date referitoare la înregistrarea cu numărul 5 din
tabela Facturi_Emise.
USE FACTURI_EMISE
LIST FIELDS NR_FACTURA, DATA, VALOARE FOR COD_CLIENT=5
NOTE se listează valorile câmpurilor din listă (număr factură, data facturii ;
şi valoare factură) doar pentru clientul cu codul 5.
GO TOP && pointer-ul de înregistrare este poziţionat pe prima înregistrare

15
LIST while data <{01/16/05} TO PRINTER && rezultatul listării se trimite la
imprimantă
DISPLAY RECORD 5 && se afişează doar valorile pentru înregistrarea numărul 5
Căutarea înregistrărilor dintr-o tabelă care respectă o anumită condiţie se mai poate face
utilizănd comenzile LOCATE şi CONTINUE. Comanda LOCATE are sintaxa:
LOCATE FOR <expL1>
[<domeniu>]
[WHILE <expL2>]
[NOOPTIMIZE]
La găsirea unei înregistrări care respectă condiţia <expL1>, indicatorul de înregistrări se va
poziţiona pe înregistrarea respectivă, iar funcţia FOUND() va returna valoarea .T. Dacă în tabela
respectivă există mai multe înregistrări care respectă o condiţie dată, căutarea acestora se va
realiza utilizând prima oară comanda LOCATE şi apoi comanda CONTINUE.
Exemplu: Să se găsească toate înregistrările din tabela FACTURI_EMISE pentru care codul
clientului este egal cu 9.
USE FACTURI_EMISE
LOCATE FOR COD_CLIENT=9 && se caută prima înregistrare pentru care ;
codul clientului este egal cu 9
?FOUND()
.T.
DISP
DO WHILE .NOT. EOF()
CONTINUE && se caută următoarea înregistrare care satisface criteriul
?FOUND()
DISP
ENDDO

FoxPro pune la dispoziţia utilizatorului facilităţi importante referitoare la extragerea


informaţiilor din tabele. O tehnică simplă şi eficientă este reprezentată de generatorul de filtre
(query). Visual FoxPro a dezvoltat noţiunea de interogare introducând mijloace de facilitare a
obţinerii unui query; de asemenea s-a introdus noţiunea de vizualizare (view). Spre deosebire de
query cu ajutorul unui view se realizează o interogare activă a tabelelor dintr-o bază de date în
sensul că modificarea rezultatului unui câmp al unui view atrage după sine modificarea valorii
respective în tabela iniţială. FoxPro cuprinde în compilatorul său un set de comenzi ale
limbajului SQL utilizat pentru interogarea bazelor de date şi a tabelelor. Comanda SQL SELECT
este o comandă cu o sintaxă foarte complexă care permite interogarea tabelelor şi trimiterea
rezultatului acestor interogări la o destinaţie prestabilită (într-o nouă tabelă, într-un raport, într-
un grafic erc). Un query este o modalitate prevăzută de limbajul FoxPro pentru a scrie fără bătaie
de cap o comandă SELECT.
Crearea interogărilor se realizează în Visual FoxPro cu Query Designer. Întrucât interogările
se fac asupra mai multor tabele mai întâi sunt selectate acestea în fereastra de dialog care va
apărea, după care se stabilesc relaţiile între tabele (condiţiile de join). Se definesc apoi câmpurile
incluse în query cu Fields, criteriile de selectare (cu Filter în Query Designer), iar rezultatele sunt
ordonate cu Order By. Înregistrările similare sunt grupate după unul sau mai multe câmpuri
(utilizând Group By), după care se stabileşte destinaţia rezultatelor interogării (o fereastră de
browse, o tabelă temporară read-only, o tabelă read-write, un grafic, un raport, o etichetă). În
orice moment se poate vizualiza comanda SQL SELECT corespunzătoare operaţiunilor
efectuate.
O altă modalitate de interogare a bazelor de date este realizarea de rapoarte sau etichete
utilizând comenzi specifice sau generoatorele corespunzătoare (Report Designer sau Label
Desiner). Se pot obţine rapoarte rapide (selectând opţiunea Quick Report) sau personalizate în
funcţie de cerinţele utilizatorului. Interogarea datelor utilizând rapoarte sau etichete se realizează

16
în două etape: crearea acestora utilizând comanda CREATE REPORT, respectiv CREATE
LABEL sau utilizând modul asistat (File/New/Report sau Label), după care se realizează afişarea
datelor în formatul creat, utilizând comenzile REPORT FORM, respectiv LABEL FORM. În
raport datele pot fi grupate utilizând opţiunea Data Grouping.

Sortarea şi indexarea bazelor de date

Sortarea şi indexarea sunt legate de două elemente foarte importante în lucrul cu bazele de
date. Pe de o parte, informaţiile cuprinse în baza de date trebuie prezentate diferit, ordonate după
criterii multiple, în funcţie de intenţiile utilizatorului sau de aplicaţiile care le
consultă/prelucrează. În al doilea rând, atunci când baza de date capătă proporţii serioase, iar
numărul celor care lucrează simultan cu baza este considerabil, viteza de acces la date este vitală.
Sortarea este operaţiunea prin care dintr-o tabelă se obţine o altă tabelă care va avea
înregistrările (liniile) ordonate după o anumită cheie de sortare (un atribut al tabelei). Tabela
rezultat poate avea aceeaşi structură ca tabela sursă, însă există şi situaţii în care sunt selectate
numai anumite atribute sau generate altele noi, prin expresii.
Spre deosebire de sortare, prin indexare nu se creează o altă tabelă, ci se asociază un tabel
special care conţine indecşii, respectiv cheia de indexare după care se ordonează înregistrările şi
adresa corespunzătoare înregistrărilor. Cheia de indexare poate fi un atribut sau o expresie
formată din atributele tabelei. Un fişier tip index nu conţine înregistrări, ci ordinea acestora, în
funcţie de o anumită cheie (atribut/combinaţie de atribute).

1 Sortarea bazelor de date


Formatul general al comenzii SORT este:
SORT TO <file> ON <field1>
[/A | /D] [/C]
[, <field2> [/A | /D] [/C] ...]
[ASCENDING | DESCENDING]
[<scope>]
[FOR <expL1>]
[WHILE <expL2>]
[FIELDS <field list> | FIELDS LIKE <skel> | FIELDS EXCEPT <skel>]
[NOOPTIMIZE]
Argumente:
file reprezintă numele tabelei destinaţie care va conţine înregistrările sortate. Pe disc se va
crea un nou fişier cu extensia .DBF.
field1 specifică atributul din tabela sursă pe baza valorilor căruia se face sortarea, altfel
spus, cheia de sortare. Implicit, ordinea de sortare este crescătoare. Nu pot fi chei de sortare
atribute de tip Memo sau General.
field2, field3 reprezinţă cheia secundară, terţiară etc. de sortare, şi au importanţă la
ordonarea liniilor atunci când valorile lui field1 (field2. etc.) sunt egale.
[/A | /D] [/C] Pentru fiecare câmp după care se face sortarea se poate preciza modul de
ordonare a valorilor: ascendentă /A sau decendentă /D. Prin opţiunea /C, la ordonare nu se face
distincţie între literele mici şi majusculele atributului de sortare. Se pot utiliza şi opţiuni
compuse: /AC sau /DC.
[scope] reprezintă domeniul comenzii. Pentru comanda SORT domeniul implicit este ALL.
FOR <expL1> determină sortarea, din tabela sursă, numai a înregistrărilor care îndeplinesc
condiţia exprimată în expL1.
WHILE <expL2> specifică o condiţie prin care înregistrările din tabela sursă sunt incluse
în tabela rezultat atâta timp cât este îndeplinită expL2.
field list sunt atributele din tabela sursă ce vor apare în tabela sortată. Dacă acestă clauză
lipseşte, vor fi preluate toate atributele.

17
FIELDS LIKE <skel> specifică o “mască” pe care numele atributelor din tabela sursă
trebuie să o verifice pentru a incluse în tabela sortată.
FIELDS EXCEPT <skel> specifică care din atributele care verifică “masca” introdusă în
clauza FIELDS LIKE nu vor fi totuşi incluse în tabela sortată (excepţiile de la mască).
Caracterele de tip specificator multiplu (sau joker) - wildcards sunt * sau ?.
NOOPTIMIZE dezactivează motorul de optimizare FoxPro (Rushmore)
Avantajul sortării îl constituie prezentarea înregistrărilor într-o ordine dorită de un
utilizatori/aplicaţie. Tabela sortată nu face parte din structura bazei de date, deci nu există riscul
alterării neautorizate a bazei, însă nici posibilitatea de a o actualiza.
Dezavantajul principal al sortării este legat de volumul mare de disc ocupat, care, atunci
când tabela sursă este voluminoasă iar tabela-destinaţie are acelaşi număr de atribute şi de liniii
ca şi cea sursă, poate încărca periculos discul.
Exemplul 1
Se dă tabela CLIENTI. Să se obţină o tabelă numită ClientiS cu aceeaşi structură ca şi
Clienti, dar cu înregistrările ordonate descrescător în funcţie de valoarea atributului cod_client.
USE CLIENTI
SORT TO ClientiS ON cod_client /D
Tabela rezultat al sortării, ClientiS, este prezentată în fig. nr. 7.

Fig. nr.7. Sortarea tabelei CLIENTI după cod_client


Exemplul 2
Pornind de la tabela CLIENTI, să se obţină o tabelă denumită ClientiS2 cu înregistrările
ordonate în ordinea descrescătoare a valorilor atributului Cod_Client, dar care conţine numai
clienţii care îşi au sediul în municipiul Iaşi, iar în structura sa sunt incluse numai atributele care
se termină cu următoarele trei caractere: “_cl” (respectiv Cod_client şi Den_client).
SELECT CLIENTI
SORT TO ClientiS2 ON Cod_client /D for localitate="Iasi" fields like "*_cl"
ClientiS2 va conţine deci numai două atribute şi trei linii (cele pentru care valoarea
atributului (câmpului) Localitate este “Iaşi”.

18
2. Indexarea bazelor de date
Indexarea este o facilitate frecvent folosită pentru afişarea datelor într-o anumită ordine, dar
şi pentru un acces rapid la date. În plus, indexarea este utilă şi pentru crearea unor relaţii
temporare între tabele.
În FoxPro există două tipuri de indecşi: simpli şi compuşi. Indecşii simpli sunt creaţi pe
disc sub forma unor fişiere cu extensia .IDX şi conţin o singură tabelă de indexare. Indecşii
compuşi sunt alcătuiţi din mai mulţi indecşi elementari (tag-uri).

.2.1. Crearea indecşilor


Cea mai cunoscută modalitate de creare a indecşilor este utilizarea comenzii INDEX ON a
cărei sintaxă este:
INDEX ON <expr> TO <idx file> | TAG <tag name> [OF <cdx file>]
[FOR <expL>]
[COMPACT]
[ASCENDING | DESCENDING]
[UNIQUE]
[ADDITIVE]
Argumente:
<expr> reprezintă cheia de indexare, alcătuită din unul sau mai multe atribute ale tabelei
curente. Pe baza cheii de indexare se afişează înregistrări sau se face accesul la date. Atributele
de tip Memo nu pot face parte singure din cheia de indexare, ci trebuie combinate cu cele de tip
caracter. Nu se recomandă utilizarea, în construirea cheii de indexare, a variabilelor de memorie
sau a atributelor din alte tabele. Lungimea unei chei de indexare poate fi între 1 şi 100 de
caractere pentru indecşi simpli şi între 1 şi 240 de caractere pentru indecşii elementari ce fac
parte dintr-un fişier .CDX.
TO <idx file > crează un fişier de tip .IDX.
TAG <tag name> [OF <cdx file] creează un index elementar (tag) inclus într-un index
compus (fişier cu extensia .CDX). Fiecare index elementar are un nume unic, alcătuit din până la
10 caractere (litere, cifre şi liniuţa de subliniere (undescore)). Numărul indecşilor elementari este
limitat numai de memorie şi spaţiul disponibil pe disc. Indecşii compuşi sunt compactaţi, deci
pentru ei nu se utilizează clauza COMPACT.
Există două tipuri de indecşi compuşi: structurali şi nestructurali. Prin neutilizarea clauzei
OF <cdx file> va fi creat un index compus structural, care are întotdeauna acelaşi nume ca cel al
tabelei căreia îi este asociat şi este deschis automat la deschiderea tabelei.
Prin includerea clauzei OF <cdx file> se crează un index compus nestructural ce trebuie
deschis explicit prin comanda SET INDEX sau utilizarea clauzei INDEX la comanda USE.
Dacă fişierul-index compus este deja creat şi deschis, atunci orice comandă INDEX ... TAG
<tag name> adaugă un index elementar la cele existente în indexul compus.
<cdx file> este numele unui index compus nestructurat asociat
FOR <expl> Prin utilizarea acestei clauze, în index sunt incluse numai înregistrările care
satisfac condiţia specificată.
COMPACT permite crearea unui index compact de tip .IDX.
ASCENDING are ca efect dispunerea valorilor cheii de indexare în ordinea crescătoare în
tabela de indexare pentru un index CDX. Utilizând DESCENDING ordinea se inversează.
Clauza DESCENDING nu poate fi utilizată în cazul indecşilor simpli (.IDX). Ordinea
descrescătoare poate fi totuşi specificată prim comenzile
SET INDEX şi SET ORDER.
UNIQUE Utilizarea acestei opţiuni are ca efect includerea în index numai a unei valori a
cheii de indexare (atunci când sunt dubluri).
ADDITIVE păstrează deschise orice indecşi deschişi anterior, care, altminteri ar fi închişi
automat, cu excepţia indecşilor elementari din indexul compus structural.

19
Obs.
Numărul indecşilor deschişi simultan este limitat numai de resursele sistemului
(memoria, în principal).
Exemplu:
Luăm în discuţie tabela CLIENŢI. Realizaţi indexarea după valorile atributului (câmpului)
Localitate cu un index simplu şi după valorile atributelor Cod_client şi Den_client utilizând
indexul structural.
Indexul simplu (.IDX), denumit Localit este obţinut pe baza atributului Localitate prin
secvenţa:
SELECT CLIENTI
INDEX ON Localitate to Localit
în timp ce indexul structural compus, ce are doi indecşi elementari, cod_client şi
den_client, este obţinut prin comenzile INDEX următoare:
INDEX ON cod_client tag codcl
INDEX ON den_client tag dencl

2.2. Deschiderea indecşilor, stabilirea indexului principal, actualizarea indecşilor


Deschiderea indecşilor şi stabilirea indexului principal
Deschiderea indecşilor se realizează diferit, în funcţie de tipul acestora. În orice caz, un
index nu poate fi deschis decât împreună cu tabela din care provine. Pentru indecşii compuşi
structurali, deschiderea este automată şi simultană cu deschiderea tabelelor cărora le sunt
asociaţi. Pentru ceilalţi indecşi, cel mai simplu mod pentru deschidere este la utlizarea comenzii
USE.
USE…
[INDEX <index file list> | ?
[ORDER [<expN> | <idx index file> | [TAG] <tag name> [OF <cdx file>]
[ASCENDING | DESCENDING]]]]
USE ...
[INDEX IndexFileList | ?
[ORDER [nIndexNumber | IDXFileName
| [TAG] TagName [OF CDXFileName][ASCENDING | DESCENDING]]]]
INDEX <index file list> specifică un set de indecşi ce se doreşte a fi deschişi odată cu
tabela. <index file list> poate conţine orice combinaţie de indecşi simpli şi compuşi. Primul din
setul enumerat va fi indexul principal, în funcţie de care vor fi accesate şi afişate înregistrările
tabelei. Atunci când primul în listă este un fişier index compus, întregistrările sunt afişate şi
accesate în ordinea lor fizică.
INDEX ? afişează un dialog pe baza căruia utlizatorul poate alege indexul dorit.
ORDER [<expN>] specifică indexul principal, care este simplu (.IDX) sau compus (.CDX),
altul decât primul din lista din clauza INDEX <index file list>. Indecşii simpli (.IDX) sunt
numerotaţi în funcţie de ordinea enumerării lor în <index file list>, iar indecşii elementari sunt
numerotaţi în funcţie de ordinea creării lor. Dacă <expN> este 0, înregistrările sunt accesate şi
afişate în ordinea lor fizică, deşi indecşii elementari rămân activi.
ORDER [<idx index file>] declară un index simplu, de tip .IDX, ca index principal al
tabelei.
ORDER [TAG <tag name>] [OF <cdx file>] specifică indexul elementar, din cele aflate
într-un index compus (.CDX). Dacă există indecşi elemenrari cu acelaşi nume, aflaţi în indecşi
comuşi diferiţi, atunci este necesară clauza OF <cdx file>.
ASCENDING respectiv DESCENDING determină modul în care vor fi accesate şi afişate
înregistrările tabelei.
Exemple:
USE CLIENŢI INDEX Localit
sau

20
USE CLIENŢI ORDER TAG CodCl
Pentru deschiderea unuia sau mai multor fişiere de tip index pentru tabela curentă, se poate
folosi şi comanda SET INDEX TO.
SET INDEX TO
[<index file list> | ?]
[ORDER <expN> | <idx index file> | [TAG] <tag name> [OF <cdx file>]
[ASCENDING | DESCENDING]]
[ADDITIVE]
Obs.
SET INDEX TO fără nici un argument închide toate fişierele index deschise pentru tabela
curentă, cu expecţia celui structural.
Stabilirea indexului principal al tabelei curente se realizează prin comanda SET ORDER
TO TAG.

SET ORDER TO
[<expN1> | <idx index file> | [TAG] <tag name> [OF <cdx file>]
[IN <expN2> | <expC>]
[ASCENDING | DESCENDING]]
Argumente:
<expN1> - vezi USE, SET INDEX...
IN <expN2> | <expC>. Această clauză stabileşte indexul principal pentru o tabelă deschisă
într-o altă zonă decât cea curentă.
Obs.
O tabelă poate avea mai mulţi indecşi deschişi simultan. Cu toate acestea, numai unul este
principal, în funcţie de care are loc accesul şi afişarea.
SELECT CLIENŢI
SET INDEX TO Localitate
sau
SET ORDER TO TAG dencl
Reindexarea
Indecşii pierd ultimele actualizări, când, la modificarea tabelei (modificări ale atributelor-
cheie de indexare), aceştia nu sunt deschişi. În asemenea situaţii, actualizarea se realizează prin
comanda REINDEX. Aceasta actualizează toţi indecşii deschişi în zona curentă.

2.3. Accesul la date pe baza indecşilor


Principalul atu al utilizării indecşilor ţine de posibilitatea accesului la înregistrările dorite
cunoscându-se valoarea cheii de indexare.
Comanda care permite acest lucru este SEEK.
SEEK <expr>
SEEK caută într-o tabelă prima apariţie a unei înregistrări a cărei cheie de indexare
corespunde expresiei de căutare, apoi deplasează pointerul tabelei pe respectiva înregistrare.
<expr> specifică cheia după care SEEK efectuează căutarea.
Obs.
În tabela se va identifica prima înregistrare pentru care valoarea atributului
(atributelor) cheie se potrivesc exact valorii expresiei de căutare, cu excepţia cazurilor
în care parametrul SET EXACT este setat pe OFF.
Dacă SEEK găseşte o înregistrare pentru care cheia se potriveşte, funcţia
RECNO( ) întoarce numărul respectivei înregistări, iar funcţia FOUND( ) întoarce true
(.T.), iar EOF( ) false (.F.). Când nici o înregistrare tabelei nu prezintă a valoarea
potrivită expersiei de căutare, RECNO( ) întoarce numărul total al înregistrărilor din
tabela curentă plus 1, FOUND( ) întoarce false (.F.), iar EOF( ) întoarce true (.T.).

21
Dacă parametrul SET NEAR este pe ON, pointerul este poziţionat pe înregistrarea
care se aproie cel mai mult de expresia specificată. Dacă SET NEAR este OFF,
pointerul este poziţionat la sfârşitul fişierului.
Exemple:
SELECT CLIENTI
SET ORDER TO TAG CODCL
SEEK 10
SGBD-ul vă căuta în tabela de indecşi a indexului elementar CODCL, pe prima coloannă
(cea a cheii), valoarea 10. O găseşte şi preia numărul înregistrării (Record_no).
Căutarea după o valoare de tip şir de caractere se face astfel:
SELECT CLIENTI
SET ORDER TO TAG DENCL
SEEK “Gama SRL”

SQL. Fraza SELECT

Exemplul 1
Care sunt clienţii din Iaşi ?
SELECT COD_CLIENT, DEN_CLIENT ;
FROM CLIENTI;
WHERE LOCALITATE = "IASI”
Exemplul 2
Care sunt produsele facturate după 23 ianaurie 2005?Rezultatul se va regăsi în tabela
prodfact..
SELECT Produse.den_produs, FACTURI_EMISE.data;
FROM FACTURI_EMISE INNER JOIN produse_din_FACTURI_EMISE;
INNER JOIN produse ;
ON Produse.cod_produs = Produse_din_FACTURI_EMISE.cod_produs ;
ON FACTURI_EMISE.nr_factura = Produse_din_FACTURI_EMISE.nr_factura;
WHERE FACTURI_EMISE.data >= {^2005/01/23};
INTO TABLE prodfact.dbf
USE prodfact
LIST
Exemplul 3
Care sunt produsele facturate între 23.01.2005 şi 31.01.2005 ?
SELECT Produse.den_produs, FACTURI_EMISE.data;
FROM FACTURI_EMISE INNER JOIN Produse_din_FACTURI_EMISE;
INNER JOIN Produse ;
ON Produse.cod_produs = Produse_din_FACTURI_EMISE.cod_produs ;
ON FACTURI_EMISE.nr_factura = Produse_din_FACTURI_EMISE.nr_factura;
WHERE FACTURI_EMISE.data BETWEEN {^2005/01/23} AND {^2005/01/31}
Exemplul 4
Care sunt clienţii al căror nume începe cu litera S şi sunt societăţi pe acţiuni ?
SELECT *;
FROM CLIENTI;
WHERE den_cl LIKE "S%SA"
Exemplul 5
Care sunt clienţii din localităţile Iaşi şi Bacău ?
SELECT cod_client, den_client
FROM CLIENTI
WHERE localitate = "Iaşi" OR localitate = "Bacau"

22
sau
SELECT *
FROM CLIENTI
WHERE localitate IN ("Iaşi", "Bacau")
Exemplul 6
Care sunt localităţile în care firma are clienţi ?
SELECT DISTINCT localitate
FROM CLIENTI

Exemplul 7
Care sunt localităţile în care firma are clienţi, ordonate după localitate?
SELECT DISTINCT Localitate
FROM CLIENTI
ORDER BY Localitate

SELECT *
FROM CLIENTI
ORDER BY localitate ASC, den_client DESC

Exemplul 8
Care este valoarea facturilor emise pentru clientul cu codul 5 ?
SELECT sum(valoare)
FROM FACTURI_EMISE
WHERE Cod_client =5
Exemplul 9
Care sunt facturile emise clienţilor din municipiul Iaşi ?
SELECT nr_factura, CLIENTI.cod_client, CLIENTI.den_client;
FROM FACTURI_EMISE, CLIENTI;
WHERE FACTURI_EMISE.cod_client= CLIENTI.cod_client;
And localitate="IASI"
Exemplul 10
Care sunt facturile emise în alte zile decât cea în care a fost întocmită factura cu numarul
105?
SELECT *
FROM FACTURI_EMISE
WHERE Data not IN
(SELECT Data
FROM FACTURI_EMISE
WHERE Nr_factura=105)
Exemplul 11
Care sunt clienţii pentru care s-au facturat produse după data de 18.01.2005 ?
SELECT DISTINCT den_client;
FROM CLIENTI;
WHERE Cod_Client IN ;
(SELECT Cod_Client;
FROM FACTURI_EMISEi;
WHERE Data>{^2005/01/18})
sau
SELECT DISTINCT den_client;
FROM CLIENTI, FACTURI_EMISE;
WHERE CLIENTI.Cod_Client=FACTURI_EMISEi.Cod_Client;
AND Data IN (SELECT Data;

23
FROM FACTURI_EMISE;
WHERE Data>{^2005/01/18})
Exemplul 12
Câţi clienţi are firma ?
SELECT COUNT (Cod_client) AS Nr_CLIENTI;
FROM CLIENTI
Exemplul 13
Pentru câţi clienţii s au emis facturi după 25.01.2005 ?
SELECT COUNT (∗);
FROM CLIENTI;
WHERE Cod_Client IN ;
(SELECT Cod_Cl ient
FROM FACTURI_EMISE
WHERE DATA>{^2005/01/25})
sau
SELECT COUNT (DISTINCT Cod_client);
FROM FACTURI_EMISE;
WHERE DATA>{^2005/01/25}
Exemplul 14
Care este valoarea totală a facturilor emise în luna ianaurie 2005?
SELECT SUM (valoare) AS Total_val;
FROM FACTURI_EMISE;
Where data>={^2005/01/01} and data<{^2005/02/01}
Exemplul 15
Care este totalul valorii facturilor emise clientului ALFA SRL ?
SELECT SUM (valoare) AS Total_val;
FROM FACTURI_EMISE, CLIENTI;
Where CLIENTI.cod_client = FACTURI_EMISE.cod_client;
AND den_client = "ALFA SRL"
Exemplul 16
Care este cea mai mică valoare a unei facturi emise?
SELECT MIN (valoare) AS valmin;
FROM FACTURI_EMISE
Exemplul 17
Care este cea mai mare valoare a unei factutri ?
SELECT MAX (valoare) ;
FROM FACTURI_EMISE
Exemplul 18
Care este totalul zilnic al facturilor emise?
SELECT Data, SUM (valoare) ;
FROM FACTURI_EMISE;
GROUP BY Data
Exemplul 19
Care este numărul facturilor emise pentru fiecare client ?
SELECT Den_client, count(nr_factura);
FROM CLIENTI, FACTURI_EMISE;
WHERE CLIENTI.Cod_Client=FACTURI_EMISE.Cod_client;
ORDER BY den_client;
GROUP BY FACTURI_EMISE.Cod_Client
Exemplul 20
Care este numărul facturilor emise în fiecare zi?
SELECT Data, count(nr_factura);

24
FROM FACTURI_EMISE;
GROUP BY Data

Exemplul 21
Câte facturi au fost emise în luna februarie 2005?
SELECT COUNT(Nr_factura);
From FACTURI_EMISE;
Where data>{^2005/01/31}
Exemplul 22
Care este totalul vânzărilor pe localităţi?
SELECT CLIENTI.localitate, sum(FACTURI_EMISE.valoare);
FROM CLIENTI inner join FACTURI_EMISE;
ON CLIENTI.cod_client=FACTURI_EMISE.cod_client;
GROUP BY CLIENTI.localitate;
ORDER BY CLIENTI.localitate
Exemplul 23
Care sunt produsele cu preţul unitar cel mai mare?
SELECT DISTINCT(cod_produs), pret_unitar;
FROM produse_din_FACTURI_EMISE;
WHERE pret_unitar=SELECT(MAX(pret_unitar);
FROM produse_din_FACTURI_EMISE)

ELABORAREA DE PROGRAME FOXPRO

1. Codificarea structurilor de control fundamentale

Cele trei structuri de control fundamentale (secvenţa, selecţia, iteraţia) se codifică în mod
direct prin comenzi specifice. Structurile de control secvenţiale se descriu prin specificarea unor
comenzi cum sunt: LIST, REPLACE, GOTO etc. Structurile de control alternative şi repetitive
presupun însă comenzi cu o sintaxă ceva mai complicată.

1.1. Structuri de control alternative

1.1.1. Structura alternativă dublă (IF … THEN … ELSE)

Structura alternativă dublă şi structura pseudoalternativă se codifică prin comanda IF care


are următorul format general:
IF <expresieL>
<comenzi1>
[ELSE
<comenzi2>]
ENDIF
Exemplu:
Dispuneţi de nomenclatorul de clienţi (CLIENTI.DBF – cod_cl, den_cl, localitate, strada,
nrstrada, distanta). Întocmiţi lista clienţilor pe categorii de distanţă. Lista va cuprinde: cod
client, denumire client, categorie. Categoria de distanţă va fi determinată astfel: până la 100 de
Km - aproape; de la 100 Km la 160 Km - departe; peste 160 Km - foarte departe.

25
Rezolvarea problemei este expusă în programul EX_IF.PRG prezentat mai jos. Se observă
că o comandă IF … ENDIF poate conţine la rândul ei o altă comandă IF … ENDIF. Pentru
urmărirea rapidă a combinării comenzilor IF în momentul depanării programelor se recomandă
scrierea indentată. Structura pseudoalternativă se codifică tot prin IF … ENDIF dar fără ELSE.
* EX_IF.PRG
* Program listare clienti pe categorii distanta
close all
clear
use clienti alias clienti
? 'Lista clientilor dupa distanta'
?
? 'Cod client Denumire client categorie distanta'
do while not eof()
if distanta < 100
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'Aproape'
else
if distanta <= 160
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'Departe'
else
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'foarte departe'
endif
endif
skip
enddo
? '_________________'
? 'Terminat'
return

1.1.2. Structura alternativă generalizată (DO CASE)


Structura alternativă generalizată se codifică prin DO CASE … ENDCASE care are
următorul format general:
DO CASE
CASE <expresieL1>
<comenzi>
[CASE <expresieL2>
<comenzi>
…]
[OTHERWISE
<comenzi>]
ENDCASE
Comanda DO CASE … ENDCASE este asemănătoare altor implementări ale structurii DO
CASE din limbaje de programare cum sunt C, PASCAL, BASIC etc. Fiecare alternativă este
exprimată printr-o expresie logică scrisă imediat după CASE. Dacă se îndeplineşte condiţia
specificată prin <expresieL> atunci se execută comenzile scrise pe rândurile următoare până la o
26
nouă linie CASE. Dacă nici una din expresiile logice de după CASE nu iau valoarea adevărat,
atunci se vor executa comenzile scrise după OTHERWISE sau se va trece la următoarea
comandă de după ENDCASE. Programul EX_DO.PRG exemplifică modul de utilizare a
comenzii CASE … ENDCASE. Şi aici se recomandă scrierea indentată.
* EX_DO.PRG
* program de determinare a trimestrului pe baza datei curente
close all
clear
set date to dmy
data_c = date()
do case
case month(data_c) <= 3
? 'Trimestrul 1'
case month(data_c) >= 4 and month(data_c) <= 6
? 'Trimestrul 2'
case month(data_c) >= 7 and month(data_c) <= 9
? 'Trimestrul 3'
case month(data_c) = 10 or month(data_c) = 11 or month(data_c) = 12
? 'Trimestrul 4'
endcase
return

1.2. Structuri de control repetitive

1.2.1. Structura repetitivă condiţionată anterior (DO WHILE)


Structura repetitivă condiţionată anterior (DO WHILE) se codifică direct prin comanda DO
WHILE … ENDDO care are formatul general prezentat mai jos. Programul EX_IF.PRG
utilizează pentru prelucrarea înregistrărilor din tabelul CLIENTI.DBF comendai DO WHILE …
ENDDO.
DO WHILE <expresieL>
<comenzi>
[LOOP]
[EXIT]
ENDDO
Modul de funcţionare a comenzii DO WHILE … ENDDO este următorul:
• Se evaluează <expresieL>;
• Dacă <expresieL> are valoarea adevărat se execută comenzile scrise pe liniile următoare
pâna la ENDDO;
• Când se ajunge la ENDDO se revine la evaluarea <expresieL>. Dacă <expresieL> are iarăşi
valoarea adevărat se execută din nou comenzile scrise pe liniile următoare pâna la ENDDO.
• Operaţiunile de mai sus se repetă până când <expresieL> ia valoarea fals.
• Dacă <expresieL> ia valoarea fals atunci se trece la următoarea comandă de după ENDDO.
Clauza LOOP determină ieşirea forţată din execuţia secvenţei de comenzi şi trecerea la
reevaluarea condiţiei exprimată de <expresieL>. Asfel se parcurge doar o parte din operaţiunile
specificate prin comenzile scrse între DO WHILE şi ENDDO.
Clauza EXIT determină, la fel, ieşirea forţată din execuţia secvenţei de comenzi dar
transferă controlul la următoarea comandă de după ENDDO. Deci se iese din structura repetitivă.
1.2.2. Comanda SCAN
Comanda SCAN codifică tot structura repetitivă condiţionată anterior ca şi DO WHILE …
ENDDO dar se aplică doar pentru prelucrările repetitive referitoare la înregistrările din tabelele

27
bazei de date. Prin comanda SCAN se gestionează şi indicatorul de înregistrări (pointer-ul)
nemaifiind necesară comanda SKIP. Formatul general al comenzii SCAN este următorul:
SCAN [<domeniu>] [FOR <expresieL1>] [WHILE <expresieL2>]
<comenzi>
[LOOP]
[EXIT]
ENDSCAN
Domeniul implicit este reprezentat de toate înregistrările tabelului activ. Restricţionarea
domeniului se poate face prin clauzele FOR, respectiv WHILE. Exemplul de la IF … ENDIF şi
DO WHILE … ENDDO poate fi exprimat şi prin SCAN … ENDSCAN. Clauzele LOOP şi
EXIT au acelaşi rol ca în DO WHILE … ENDDO.
* EX_SCAN.PRG
* Program listare clienti pe categorii distanta
close all
clear
use clienti alias clienti
? 'Lista clientilor dupa distanta'
?
? 'Cod client Denumire client categorie distanta'
scan
if distanta < 100
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'Aproape'
else
if distanta <= 160
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'Departe'
else
? str(cod_cl,3)+' '
?? den_cl+' '
?? 'foarte departe'
endif
endif
endscan
? '_________________'
? 'Terminat'
return

1.2..3. Structura repetitivă cu un număr definit de paşi (DO FOR)


Structura de tip DO FOR se codifică prin comanda FOR … ENDFOR. Variabila de control
este o variabilă de memorie (<variabila_mem>). Comanda are următorul format general:
FOR <variabila_mem> = <exprN1> TO <exprN2> [STEP <exprN3>]
<comenzi>
[LOOP]
[EXIT]
ENDFOR ¦ NEXT
Expresia numerică <exprN1> reprezintă valoarea iniţială a variabilei de control, expresia
numerică <exprN2> este valoarea finală a variabilei de control, iar <exprN3> reprezintă
incrementul.
28
Exemplu:
Datele relative la stocurile de produse finite se gestionează prin intermediul tablourilor de
date. Să se determine produsul cu stocul maxim.
Programul de mai jos descrie algoritmul de determinare a stocului maxim.
* ST_MAX.PRG
* program de determinare a stocului maxim
CLEAR
SET TALK OFF
INPUT "Nr. de produse: " to n
DIMENSION denp(n)
denp = space(25)
DIMENSION cant(n)
cant = 0
FOR i = 1 TO n
ACCEPT "Denumire produs: " to denp(i)
INPUT "Cantitate: " to cant(i)
ENDFOR
B=0
STORE 0 TO j
FOR i = 1 TO n
IF B < cant(i)
B = cant(i)
j=i
ENDIF
ENDFOR
? 'Produsul cu stocul maxim:'
? denp(j)
?? cant(j)
SET TALK ON
RETURN

2. Aplicaţii, programe şi proceduri

O aplicaţie FoxPro este formată din unul sau mai multe programe. La rândul lor programele
pot conţine una sau mai multe proceduri. Delimitarea program - procedură nu este absolută. De
obicei există un program coordonator (principal) care apelează subprogramele sau procedurile
după o anumită schemă.
Comanda pentru executia programelor/ procedurilor este DO cu următorul format general:
DO <nume_fişier1> [WITH <lista-parametri>] [IN <nume_fişier2>]
Numele specificat după DO trebuie să numele unui fişier cu extensia .PRG; .EXE; .FXP;
.SPR; .MPR; .QPR sau numele unei proceduri locale sau externe. Dacă nu este precizată
extensia fişierului sistemul caută automat un fişier cu extensia.EXE; .FXP; .PRG. Extensiile
.SPR, .MPR; .QPR trebuie să fie preznte în specificatorul de fişier.
Când este lansată un program/ o procedură cu ajutorul comenzii DO execuţia continuă până
la apariţia unuia din evenimentele următoare:
• întâlnirea unie comenzi CANCEL;
• întâlnirea unie comenzi QUIT;
• întâlnirea unie comenzi RETURN;
• sfârşitul procedurii
Procedurile locale sunt definite chiar în programul care le apelează. Procedurile pot fi şi
fişiere separate cu extensia .PRG. În acest caz este vorba de proceduri externe. În practică

29
procedurile se reunesc într-un fişier cu extensia .PRG de unde sunt apoi accesate, după comanda
SET PROCEDURE. Când se întâlneste o comandă DO căutarea procedurii de executat se face
astfel:
• mai întâi se caută procedura locală, din programul în curs de execuţie;
• se cecetează apoi fişierul indicat în comanda SET PROCEDURE;
• se caută procedura ca un fişier independent, cu extensia: .EXE; .APP; .FXP; .PRG.

CLOSE ALL
CLEAR
SET TALK OFF
USE CLIENTI
N=RECCOUNT()
STORE 0 TO I,CC,NS, DIST
STORE SPACE(15) TO DC, LC, STR
STORE .T. TO MODIFICARE
STORE " " TO RASP1,RASP2
DO WHILE MODIFICARE=.T.
CLEAR
@2,1 SAY "NR. INREGISTRARII PENTRU MODIFICARE" GET I
READ
IF I<=N
GO I
DISPLAY
@3,1 SAY "SUNTETI SIGUR?(D/N)" GET RASP1
READ
IF RASP1="D"
CLEAR
@2,1 SAY "COD CLIENT" GET CC PICT "999999"
@3,1 SAY "DENUMIRE CLIENT" GET DC
@4,1 SAY "LOCALITATE" GET LC
@5,1 SAY "STRADA" GET STR PICT “9999”
@6,1 SAY "NUMAR STRADA" GET NS PICT “99999”
@7,1 SAY "DISTANTA” GET DIST PICT”9999”
READ
REPLACE COD_CL WITH CC
REPLACE DEN_CL WITH DC
REPLACE LOCALITATE WITH LC
REPLACE STRADA WITH STR
REPLACE NRSTRADA WITH NS
REPLACE DISTANTA WITH DIST
ENDIF
ELSE
@3,1 SAY "INREGISTRAREA NU EXISTA"
ENDIF
@12,1 SAY "MAI MODIFICATI O INREGISTRARE?(D/N)" GET RASP2
READ
IF RASP2="N"
STORE .F. TO MODIFICARE
USE
ENDIF
ENDDO

30
CLEAR
CLOSE ALL

Crearea rapoartelor în Visual Fox Pro


Visual FoxPro este dotat cu un instrument puternic pentru crearea formularelor (forms)
cu scopul de a pune la dispoziţia utilizatorului mijloace de introducere a datelor într-o bază de
date. Visual FoxPro dispune de numeroase instrumente pentru a extrage date dintr-o bază de
date. Utilizatorii pot învăţa câteva comenzi simple pentru afişarea datelor, pot lista (cu ajutorul
comenzii LIST) conţinutul unei tabele, pot deschide simple ferestre "browse", pot executa simple
fraze SELECT sau pot utiliza tehnologia ODBC pentru a deschide datele Visual FoxPro în alte
aplicatii. Majoritatea utilizatorilor însă utilizează rapoartele ca forma de colectare şi prezentare a
informaţiilor.
Report Designer-ul din Visual FoxPro este o interfaţă vizuală pentru proiectarea
"manuală" a rapoartelor şi etichetelor. Puteţi crea un raport prin plasarea a diferite obiecte cum ar
fi câmpuri, text, imagini şi expresii "pe suprafaţa" respectivului raport. Opţiunea Quick Report
din meniu poate grăbi întreg procesul prin stabilirea unui stil implicit pentru rapoarte. Mai mult,
Report Wizard-ul poate asista utilizatorul în prototipizarea şi crearea rapidă a unor rapoarte ce
pot fi ulterior modificate cu uşurinţă.

TIPURI DE RAPOARTE
În Visual FoxPro rapoartele pot prezenta informaţiile în mai multe moduri. De exemplu,
datele pot fi aliniate în coloane distincte într-un format reminiscent de la spreadsheet-uri (fig.
nr.1). O altă modalitate ar fi prezentarea datelor ce constituie o înregistrare unele sub altele ca
într-un formular (fig.nr.2). Datele pot fi prezentate aşa cum sunt sau pot fi grupate, agregate
(adunate, numărate, calculată media, calculate subtotaluri etc.). Pentru reprezentarea datelor se
pot include diverse grafice sau chart-uri. Sursa datelor pentru rapoarte este reprezentată de
tabele, interogări sau vederi (views). Într-un raport pot apare chiar şi câmpuri calculate (câmpuri
a căror valoare este calculată cu ajutorul unei expresii) sau câmpuri ce conţin rezultatele unor
funcţii (operaţii de prelucrare a datelor) definită de către utilizator.

31
Fig. nr.1. Raport "pe coloane"

Fig. nr. 2. Raport cu datele unei înregistrări aranjate una sub alta

CREAREA RAPOARTELOR VIA QUICK REPORT


Opţiunea Quick Report asigură o modalitate uşoară şi rapidă de creare a rapoartelor, lăsând
Visual FoxPro să se ocupe de detaliile de proiectare. Utilizarea opţiunii Quick Report este
uşoară:
1. Deschideţi tabela ce conţine datele pe care doriţi să le includeţi în raport (Selectaţi File,
Open şi apoi alegeti numele tabelei din fereastra de dialog deschisă sau apelaţi la
comanda USE <nume tabelă> în fereastra de comenzi.
2. Din meniul principal, alegeţi File, New şi apoi Report. Selectaţi apoi New File. (În mod
alternativ puteţi utiliza comanda CREATE REPORT în fereastra de comenzi).
3. Selectaţi Report, Quick Report. Apare fereastra de dialog Quick Report (fig. nr. 3).
4. Alegeţi stilul (layout) pe care îl preferaţi şi efectuaţi click, selectând alte opţiuni pe care
le doriţi pentru raportul dvs. Apoi click OK.

Fig.nr.3. Fereastra Quick Report


Fereastra de dialog Quick Report include câteva opţiuni principale privind stilul
raportului ce urmează a fi creat. Butoanele Field Layout permit utilizatorului să aleagă între un
stil column-style sau row-style.
Căsuţa de validare Titles (căsuţa de validare = check box) include numele câmpului,
deasupra sau lângă valoarea câmpului (depinzând de stilul adoptat). În majoritatea rapoartelor
utilizatorul va dori să dispună de un marker de identificare pentru fiecare câmp aşa încât această
căsuţă de validare va fi selectată. Dacă însă, de exemplu, raportul este o simplă listă de nume şi
adrese, probabil nu se va dori şi numele câmpului.
Căsuţa de validare Add alias indică dacă numele alternative (nume alternativ = alias) sunt
adăugate în mod automat la expresiile pentru fiecare câmp. Cu alte cuvinte, această opţiune
indică dacă numele câmpului va fi afişat. Probabil, utilizatorii vor dori ca numele alias să fie
selectate, mai ales dacă se intenţionează crearea unor rapoarte pe baza mai multor tabele.
Opţiunea Add table to data environment adaugă tabelul curent la fereastra Data
Environment. Dar, despre Data Environment mai târziu, în secţiunea intitulată "Să profităm de
Data Environments şi Data Sessions."

32
REPORT DESIGNER-UL
Chiar dacă v-aţi obişnuit să utilizaţi opţiunea Quick Report, veţi dori probabil să apelaţi la
facilităţile oferite de Report Designer în aplicaţiile dvs. Aţi vazut deja cum se creează un simplu
raport cu ajutorul opţiunii Quick Report. Un raport poate fi creat însă în mai multe moduri. Iată
cele mai comune modalităţi:
• Alegeţi File, New. Click butonul Report, apoi click New Report.
• Din fereastra Project Manager, click tab-ul (eticheta) Documents, selectaţi icon-ul Report
în lista de documente, apoi click pe butonul New. Apoi selectaţi New Report.
• În fereastra de comenzi introduceţi comanda Create Report sau comanda Modify
Report <numele raport>.
• Utitlizaţi Report Wizard-ul (asistentul) pentru a crea un raport, salvaţi-l şi modificaţi-l
apoi după dorinţă.
Veţi învăţa despre utilizarea Report Wizard în secţiunea intitulată "Crearea unui raport cu
Report Wizard". În continuare, explorăm Report Designer-ul.
Nu contează cum creaţi un nou raport, Visual FoxPro va lansa în mod automat Report
Designer-ul (fig. nr. 5). Report Designer-ul are câteva componente:

Fig. nr. 5. Report Designer-ul ("Proiectantul" de rapoarte)


• "Suprafaţa" raportului este reprezentarea vizuală a raportului pe care îl proiectaţi,
suprafaţa pe care plasaţi câmpuri, etichete sau grafice.
• Toolbar-ul (linia de instrumente) Report Designer toolbar vă permite să accesaţi cu
uşurinţă toate liniile de instrumente specifice rapoartelor şi alte functii importante.
SFAT
Liniile de instrumente specifice rapoartelor în Visual FoxPro au
ToolTips (texte explicative) ataşate pentru a vă ajuta să vă amintiţi sau
reamintiţi scopul lor. Ţineţi cursorul mouse-ului deasupra pictogramelor
de pe o linie de instrumente câteva secunde şi veţi beneficia de acest
ajutor.
• Linia de instrumente Report Controls toolbar vă permite să "amplasaţi" în raportul dvs.
şase tipuri de controale: etichete, câmpuri, linii, dreptunghiuri, dreptunghiuri cu colţuri
rotunjite şi imagini "legate" sau alte controale "legate".
• Paleta Color palette vă permite să specificaţi culorile de fundal sau proprii oricărui
control.
PRECAUŢII
Nu vă jucaţi cu culorile într-un raport. report. Nu toţi utilizatorii au
imprimante color şi, chiar şi cei care au, apreciază mai degrabă un
raport obţinut rapid, decât un raport cu un fundal de culoare galben
lămâi. Utilizaţi culorile doar dacă doriţi să atrageţi atenţia asupra unui
rezultat.

33
• Paleta Layout palette permite alinierea sau dimensionarea unuia sau mai multor controale
(vezi "Formatarea controalelor unui raport").
• Butoanele Data Grouping şi Data Environment asigură controlul rapid asupra modalităţii
de prezentare a datelor dvs.
SFAT
Puteţi amplasa liniile de instrumente specifice rapoartelor imediat sub
zona meniului principal al aplicaţiei. Puteţi, de asemenea, să le
redimensionaţi (în limite rezonabile) pentru a fi pe placul dvs. - tot ce
trebuie să faceţi este să plasaţi cursorul mouse-ului deasupra
"marginilor" liniilor de instrumente şi să "trageţi" în direcţia în care
doriţi.

Lucrul cu controalele unui raport


Report Designer-ul suportă trei tipuri de obiecte sau controale: obiecte text, obiecte câmp şi
obiecte grafice. Aceste obiecte sunt similare obiectelor ce apar într-un formular, însă prezintă şi
unele diferenţe. În primul rând, controalele unui raport prezintă un set mult mai limitat de
proprietăţi privind formatarea şi caracteristicile datelor. În al doilea rând, nu pot fi apelate în
cadrul codului sursă (prin program). Mai mult, prin natura lor, nu sunt interactive: astfel,
utilizatorii nu vor putea introduce text într-un raport.
Cu obiectele unui raport se lucrează relativ uşor şi sunt suficient de flexibile pentru a permite
design-ul unor rapoarte sofisticate şi/sau profesionale. Obiectele text conţin text pe care îl tastaţi
direct în Report Designer. Obiectele câmp sunt utilizate pentru afişarea datelor stocate în
câmpuri ale înregistrărilor sau a datelor calculate prin expresii, formule sau funcţii ale
utilizatorilor. Obiectele grafice sunt imaginile, liniile sau dreptunghiurile.

Imaginile dintr-un raport Visual FoxPro pot fi stocate în câmpurile unui tabel sau pe disc în
diverse formate grafice: .BMP, .ICO, .ANI, .JPG, .GIF, sau .CUR. Această capabilitate
constituie pentru Visual FoxPro un plus faţă de versiunile anterioare ale programului, ce nu
suportau decât fişiere Windows Paintbrush cu extensia .BMP.
Pe măsură ce adaugaţi obiecte pe suprafaţa raportului, le puteţi manipula după cum doriţi.

Selectarea unui obiect al unui raport


Pentru a selecta un obiect, asiguraţi-vă mai întâi că butonul Select Objects (săgeata) este selectat
în linia de instrumente Report Controls. Executaţi click pe tipul de obiect dorit. Obiectul va fi
vizibil "selectat" cu dreptunghiuri sau puncte de manevrare (handles).
Executaţi click pe suprafaţa raportului unde doriţi să apară obiectul (sau, mai clar, click în
punctul unde va fi amplasat colţul din stânga sus al obiectului). Obiectul va avea o mărime
implicită asignată de Visual FoxPro; obiectul va putea fi ulterior redimensionat după necesităţi.
Există posibilitatea de a adăuga un control într-un raport şi de a-l dimensiona în acelaşi timp.
Pentru aceasta, click şi selectaţi tipul de obiect pe care doriţi să-l adăugaţi. "Dragaţi" mouse-ul pe
suprafaţa raportului pentru a stabili dimensiunea dreptunghiului în care se va încadra obiectul,
apoi eliberaţi butonul stâng al mouse-ului. Controlul va fi adăugat la raport şi va avea
dimensiunea specificată.

Ştergerea unui obiect


Pentru a şterge un obiect, selectaţi obiectul pe suprafaţa raportului şi apăsaţi tasta Delete sau
alegeţi Edit, Cut. Această procedură funcţionează şi pentru mai multe obiecte.

Copierea unui obiect


Pentru a duplica un obiect, selectaţi obiectul pe suprafaţa raportului, alegeţi Edit, Copy (sau
Ctrl+C), apoi Edit, Paste (sau Ctrl+V). Dacă procedaţi astfel, o copie a obiectului apare lângă

34
obiectul original. Puteţi selecta cu un click obiectul şi, utilizând tastele săgeţi sau mouse-ul, să-l
deplasaţi într-o nouă locaţie.
SFAT
Cea mai uşoară modalitate de a redimensiona un obiect al unui raport
este de a selecta obiectul, de a ţine apăsată tasta Shift şi de a apăsa şi o
tastă săgeată. Cu fiecare apăsare a tastei săgeată, obiectul este expandat
sau contractat cu un pixel sau unitate de scară. De asemenea, puteţi ţine
apăsată tasta Shift şi puteţi utiliza mouse-ul pentru redimensionarea
unui obiect, dar este dificil să lucraţi cu precizie.

Lucrul cu câmpurile
Obiectele de tip text şi graficele sunt importante, însă utilizatorii sunt mai degrabă interesaţi de
datele incluse într-un raport. Pentru a afişa datele într-un raport, utilizaţi obiectul text box pentru
a adăuga un câmp, o variabilă, o expresie sau o funcţie definită de utilizator. Pentru a adăuga un
câmp pe suprafaţa raportului, selectaţi controlul text box / field din linia de instrumente Report
Controls. Când efectuaţi click pe suprafaţa raportului pentru a adăuga controlul, apare fereastra
de dialog intitulată Report Expression (Fig.nr 6). De notat ca puteţi accesa această fereastră de
dialog şi mai târziu, efectuând click dreapta pe un control de tip câmp (field) şi selectând
Properties din meniul shortcut.

Fig. nr. 6. Fereastra de dialog Report Expression


În fereastra de dialog Report Expression, puteţi introduce sau construi o expresie ce va evalua
datele prezentate în raport. De asemenea, puteţi specifica o serie de proprietăţi cheie, descrise în
secţiunile următoare.

Modificarea expresiilor câmpurilor


Caseta de text Expression include expresia, numele câmpului sau apelul la funcţia ce va evalua
datele ce se doresc a fi prezentate. Puteţi introduce un câmp (numele acestuia) sau o expresie în
caseta de text sau puteţi utiliza butonul pentru a afişa fereastra Expression Builder (Fig nr. 7).
Expression Builder-ul include un număr de instrumente ce va ajuta în adăugarea datelor la un
raport, inclusiv o listă a câmpurilor disponibile, a funcţiilor Visual FoxPro şi a variabilelor de
sistem Visual FoxPro.

35
Fig nr. 7. Fereastra Expression Builder.
Puteţi include orice nume de variabilă sau apel la funcţie în Expression, însă aceste
variabile şi funcţii trebuie să fie utilizate atunci când raportul este rulat; în caz contrar, obţinem o
eroare.
SFAT
Puteţi include IF-uri imediate în formatul următor în caseta de text expression:
IIF(condiţie,rezultat dacă este true, rezultat dacă
nu este true)
Aceste "statements" (IIf-urile) pot fi deosebit de utile. Puteţi modifica
valoarea True sau False a unui câmp logic, de exemplu, în ceva mult mai
informativ sau "ochios" cu ajutorul următoarei expresii:
IIF(situatie = .T.,"Asta e!","Sorry, sucker!")

Modificarea formatului câmpurilor


În câmpul Format al ferestrei de dialog Report Expression, puteţi specifica tipul de formatare a
textului sau datelor numerice rezultate. Executând click pe butonul pentru această proprietate
se accesează fereastra de dialog Format prezentată în fig nr.8 . Puteţi utiliza această fereastră de
dialog pentru a formata rapid datele pe care le doriţi în raportul dvs., după care vă întoarceţi la
fereastra de dialog Report Expression.

Fig nr. 8. Opţiunile de formatare a unui câmp în fereastra Format.


Field Position indică unde doriţi să fie amplasat câmpul relativ la "banda" sa. Puteţi opta pentru
un câmp flotant (float) ceea ce înseamnă că poziţia sa este relativă la alte câmpuri din cadrul

36
benzii. Sau puteţi stabili ca poziţia câmpului să rămână relativă la marginea de sus sau de jos a
benzii intitulate Detail, ceea ce înseamnă că acesta va fi întotdeauna la o distanţă fixată faţă de
una din marginile benzii, indiferent de dimensiunile oricăror alte controale.
Caseta de validare Stretch with Overflow (check box) indică dacă un control de tip câmp poate
"creşte" pe verticală destul pentru a afişa tot textul dintr-un câmp sau o variabilă. În caz contrar,
doar o porţiune a rezultatului expresiei va fi afişată şi implicit imprimată. Această opţiune este
utilă mai ales atunci când se lucrează cu date din câmpuri de tip Memo.
Butonul Calculations permite specificarea unui subtotal sau a unui calcul. Pentru a crea un
subtotal pentru un câmp, click pe acest buton, iar apoi, în fereastra de dialog Subtotal sau
Calculate Field, indicaţi tipul calculului şi unde să apară. În fig. nr. 9, de exemplu, se specifică
faptul că se doreşte să se calculeze câte valori au fost în câmpuri, la sfârşitul fiecărei pagini.
Acest control se amplasează în banda intitulată Page Footer.

Fig. nr. 9. Stabilirea calculelor în fereastra Calculate Field.


Butonul Print When din fereastra de dialog Report Expression permite a se stabili dacă un câmp
dintr-un raport este imprimabil sau nu. Efectând click pe acest buton se deschide fereastra de
dialog Print When (Fig nr. 10). Implicit, un obiect este imprimat ori de câte ori continutul benzii
în care se afla este imprimat, dar aceasta comportare implicita se poate schimba. De exemplu,
puteti alege sa nu imprimati valori care se repeta, sau intr-un raport in care exista gruparea
datelor, puteti alege sa imprimati un câmp doar atunci când baza de grupare se modifica. Caseta
de text Print Only When Expression Is True permite definirea altei expresii ce determina când un
câmp se imprima sau nu. Puteti utiliza acest câmp, de exemplu, pentru a limita imprimarea unor
câmpuri in anumite conditii de securitate.

Fig. nr. 10.Fereastra de dialog Print When

37
În fereastra de dialog Print When puteţi specifica în ce condiţii vor apare expresiile dintr-un
raport la imprimantă.
Puteţi utiliza porţiunea Comment din fereastra de dialog Report Expression pentru a introduce
comentarii comments pentru dvs. sau pentru alţi utilizatori. Comentariile nu apar nicăieri în
raport.
Lucrul cu variabile într-un raport
Puteţi defini variabile ce vor fi utilizate în raportul dvs. prin slectarea opţiunilor Report,
Variables (fig nr.11). De ce să utilizaţi variabile în rapoarte? Ei bine, aţi putea dori să stocaţi
anumite valori sau rezultate ale raportului pe care să le utilizaţi şi după încetarea rulării
raportului.

Fig. nr.11. Fereastra de dialog pentru definirea variabilelor.


Dacă selectaţi caseta de validare Release After Report din fereastra de dialog, variabilele
raportului au caracter privat (ceea ce înseamnă că orice funcţie definită de către utilizator pe care
o apelaţi le poate accesa). Dacă nu selectaţi caseta de validare, variabilele vor rămâne în
memorie ca variabile publice, având caracter global.

Lucrul cu forme şi text


Puteţi adăuga cu uşurinţă o formă geometrică sau o linie de text la un raport Visual FoxPro: nu
trebuie decât să selectaţi controlul dorit şi să-l amplasaţi în raport. De asemenea, puteţi controla
comportamentul formelor şi textului într-un raport, la fel cum stabiliţi proprietăţile câmpurilor.
Efectuând dublu-click pe un obiect de tip text dintr-un raport; apare fereastra de dialog Text (fig.
nr. 12.

Fig. nr 12. Fereastra de dialog Text


În fereastra de dialog Text, puteţi controla stilul şi comportamentul unui obiect de tip text dintr-
un raport.
Dacă efectuaţi click pe butonul Print When se deschide fereastra de dialog Print When
(prezentată anterior). Utilizând această fereastră de dialog, puteţi exercita acelaşi control asupra

38
textului şi formelor ca şi în cazul câmpurilor. Acelaşi lucru este valabil şi în cazul controlului
poziţiei unui obiect de tip text sau a poziţiei unei forme geometrice: utilizaţi grupul de butoane
de opţiune Object Position pentru a determina aceste proprietăţi. Controalele Rectangle şi Line
au o serie de opţiuni suplimentare faţă de cele ale obiectelor de tip text (fig nr.13). Dacă efectuaţi
dublu-click pe o linie dintr-un raport, puteţi indica şi cum se dimensionează aceasta relativ la
banda de care aparţine. Opţiunea No Stretch restricţionează redimensionarea liniilor verticale sau
dreptunghiurilor. Opţiunea Stretch Relative to Tallest Object in Group permite unei linii verticale
sau unui dreptugnhi să se "întindă" până la înalţimea celui mai "înalt" obiect din cadrul grupului,
în timp ce opţiunea Stretch Relative to Height of Band permite unei linii verticale sau dreptunghi
să se "întindă" în funcţie de înălţimea benzii sale.

Fig. nr. 13. Fereastra de dialog Rectangle/Line


În fereastra de dialog Rectangle/Line puteţi controla stilul şi comportamentul dreptunghiurilor şi
liniilor din cadrul unui raport.
Controlul Round Rectangle are o fereastră de dialog similară, dar conţine cinci butoane diferite
pentru a indica diverse stiluri (fig. nr. 14).

Fig. nr. 14. Fereastra de dialog Round Rectangle


În fereastra de dialog Round Rectangle puteţi controla stilul şi comportamentul dreptunghiurilor
rotunjite din cadrul unui raport.

39
LUCRUL CU IMAGINI ŞI GRAFICE
Adăugarea obiectelor de tip text sau a formelor este utilă dar dacă se doreşte ca raportul să "ia
ochii" în sensul de a atrage atenţia la anumite informaţii cum ar fi, de exemplu, logo-ul
companiei, este necesar să se lucreze cu imagini şi grafice. Puteţi adauga grafice la un raport
dintr-un câmp general al unui tabel Visual FoxPro sau dintr-un fişier de pe disc. De exemplu, fig.
nr. 15 prezintă un raport ce include o imagine.

Fig. nr. 15. Exemplu de raport ce include o imagine


Puteţi adăuga o imagine la un raport cu uşurinţă, urmând aceşti paşi:
1. Selectaţi controlul Picture / OLE Bound din linia de instrumente Report Controls.
2. Click punctul de start al imaginii şi trageţi până ce cadrul este suficient de mare pentru a
include imaginea dorită. Când eliberaţi butonul mouse-ului, apare fereastra de dialog
Report Picture (Fig. nr. 16).

Fig. nr. 16. Fereastra de dialog Report Picture


3. Stabiliţi opţiunile (discutate în următoarele paragrafe) pentru a-i "spune" Visual FoxPro-
ului unde se găseşte imaginea şi cum să o dimensioneze relativ la banda în care va fi
amplasată.
4. Click OK. Imaginea dorită apare unde aţi stabilit.
Zona Picture From din fereastra de dialog include butoanele File şi Field şi câmpurile
corespunzătoare pentru a specifica sursa imaginii. Pentru a include o singură imagine dintr-un
fişier în raport, click pe butonul File şi alegeţi fişierul dorit. Pentru a alege o imagine dintr-un
câmp al unei tabele, click Field, după care selectaţi câmpul dorit.
Zona If Picture and Frame Are Different Sizes are trei opţiuni diferite: Clip Picture; Scale
Picture, Retain Shape; şi Scale Picture, Fill the Frame. Când imaginea este mai mare decât cadrul
pe care l-aţi adăugat raportului, opţiunea Clip Picture "spune" Visual FoxPro-ului să decupeze
imaginea la dreapta şi jos în aşa fel încât să se încadreze în cadrul specificat. Opţiunea Scale

40
Picture, Retain Shape "spune" Visual FoxPro-ului să afişeze întreaga imagine "umplând" pe cât
posibil cadrul specificat şi menţinând proporţiile imaginii. În fine, opţiunea Scale Picture, Fill the
Frame afişează imaginea completă, "umplând" complet cadrul, chiar dacă acest lucru
distorsionează imaginea. Caseta de validare Center Picture este utilizată pentru imaginile stocate
în câmpurile generale ale unei tabele. Imaginile din fişiere de pe disc nu sunt afectate de această
opţiune. Dacă imaginea dintr-un câmp este mai mică decât cadrul specificat, validarea casetei de
validare va face ca imaginea să fie centrată în respectivul cadru.
Butonul Print When lucrează în mod similar cu imagini ca şi cu alte controale. Puteţi opta pentru
afişarea unei imagini doar dacă sunt îndeplinite anumite condiţii.
Zona Object Position a ferestrei de dialog are trei opţiuni: Fix Relative to Top of Band, Fix
Relative to Bottom of Band, and Float. Opţiunea Fix Relative to Top of Band menţine poziţia
textului în legătură cu marginea de sus a benzii şi nu permite redimensionarea câmpului pentru a
afişa o altă imagine cu altă dimensiune. Opţiunea Fix Relative to Bottom of Band va permite
redimensionarea câmpului pentru a accepta date mai "mari" (sau mai lungi), dar va menţine
poziţia imaginii relativ la marginea de jos a benzii. Opţiunea Float permite textului să "floteze"
în relaţie cu poziţia benzii.
Puteţi utiliza porţiunea Comment a ferestrei de dialog pentru a adăuga comentarii despre
imagine, pentru dvs. sau pentru alţi utilizatori. Comentariile nu afectează în nici un fel raportul
imprimat.

FORMATAREA CONTROALELOR UNUI RAPORT


Atunci când lucraţi cu Report Designer apare un nou submeniu în meniul principal: Reports. În
plus, anumite opţiuni din alte meniuri pop-up sunt activate sau au valori speciale. Unele din
aceste opţiuni sunt disponibile şi prin liniile de instrumente. De exemplu, meniul Format include
câteva instrumente pentru alinierea şi dimensionarea datelor, ce "copie" din funcţionalitatea liniei
de instrumente Layout.
Alinierea
Pentru a alinia o serie de casete de text, de exemplu, începeţi prin a selecta casetele de text
(puteţi face acest lucru ţinând apasată tasta CTRL în timp ce efectuaţi click sau ţineţi apăsat
butonul stâng al mouse-ului şi "desenaţi" o zonă dreptunghiulară în jurul controalelor pe care
doriţi să le selectaţi). Apoi, cu controalele selectate, alegeţi Format, Align. Puteţi alege cum
doriţi să aliniaţi controalele selectate: la stânga, la dreapta, sus, jos, centrate vertical sau centrate
orizontal. Acest proces de aliniere nu are nici un efect asupra alinierii textului caracteristic
fiecărui control. În loc de acest lucru, determină modul în care controalele sunt amplasate unul
faţă de altele.
Mărimea
Meniul Format include un număr de opţiuni Size ce permit proiectantului să dimensioneze cu
usurinţă mai multe controale. Alegând Format, Size, To Grid unul sau mai multe controale sunt
dimensionate la aceeaşi dimensiune fiind "legate" (amplasate) la cea mai apropiată linie de
ghidare (grid line) din fereastra Report Designer. Celelalte opţiuni determină mărimea mai
multor controale pe baza celui mai "scund", "înalt", "scurt" sau "îngust" control selectat.
Spaţierea
Opţiunile Format, Spacing vă permit spaţierea a trei sau mai multe controale la distanţe egale, fie
vertical, fie orizontal. De exemplu, aţi putea să nu observaţi dacă o casetă de text dintr-o serie de
casete de text este la câţiva pixeli distanţă faţă de celelalte. Un contabil, însă, care "măsoară
datele cu şublerul" va observa cu siguranţă acest lucru. Încercaţi să utilizaţi toate opţiunile de
formatare. Astfel, rapoartele dvs. vor arăta profesional.
Gruparea
Opţiunea Format, Group option vă permite să trataţi două sau mai multe controale ca pe unul
singur. Aceasta posibilitate este în special utilă atunci când centraţi controale. Dacă selectaţi mai
multe controale în Report Designer şi selectaţi una din proprietăţile de centrare, fiecare control
este centrat, ceea ce însemnă că există posibilitatea ca acestea să se suprapună. dacă mai întâi le

41
grupaţi şi apoi le centraţi, veţi obţine rezultatul dorit: controalele, ca grup, vor fi centrate în
cadrul paginii.
Dacă selectaţi un control care a fost deja "grupat" opţiunea se modifica în Ungroup.
Snap to Grid şi Grid Scale
Opţiunea View, Grid Lines "umple" suprafaţa raportului cu linii de ghidare verticale şi
orizontale, permitându-vă să "simţiţi" şi să apreciaţi distanţele dintre controale. Cele două opţiuni
din Format - Snap to Grid şi Grid Scale - vă permit să modificaţi lungimea şi lăţimea zonelor de
ghidare, şi să aliniaţi un control la cea mai apropiată linie orizontală sau verticală.
Opţiuni Text
Opţiunea Format, Font vă permite să specificaţi un font pentru un control sau un grup de
controale. Puteţi utiliza orice font disponibil specific Windows.
Alinierea textului determină alinierea textului în cadrul unui control. Opţiunile Format, Align
determină poziţionarea controalelor unele faţă de altele. Opţiunile de aliniere a textului vă permit
să aliniaţi textul la stânga, la dreapta, centrat sau justify.
Opţiunile Fill şi Pen
Opţiunile Fill şi Pen options asigură un mecanism intern de modificare a şabloanelor de umplere
şi realizare a chenarelor. Opţiunea Fill afişează un submeniu ce include o serie de şabloane de
umplere sau o opţiune implicită de non-umplere. Opţiunea Pen lansează un submeniu de lăţimi
ale conturului şi tipuri de linii.
Opţiunea Mode determină dacă background-ul (fundalul) unui control este transparent sau opac,
afectând doar obiectele text, dreptunghiurile şi dreptunghiurile rotunjite.
Benzile Rapoartelor
Report Designer-ul din Visual FoxPro utilizează abordarea orientată pe benzi ce a devenit atât de
populară în crerea rapoartelor în ultimii ani. Diferitele benzi reprezintă diferite secţiuni ale
raportului.
Principalele benzi ale unui raport. Aproape fiecare raport pe care îl proiectaţi va avea o aşa-
numită detail band (banda detaliilor), ce conţine datele afişate în porţiunea principală a
raportului. Controalele din această secţiune reprezintă probabil "inima" raportului. Controalele
amplasate în această banda vor fi afişate imediat pentru fiecare înregistrare din sursa de date.
Controalele din title band sunt afişate doar odată, pe prima pagină a raportului în timp ce
controalele din "summary band" vor apare doar la sfârşitul raportului. Benzile de titlu sunt
utilizate în mod curent pentru titluri. Benzile de sumar sunt utilizate pentru informaţii de "sumar"
cum ar fi totaluri de câmpuri numerice, "numărări" de înregistrări incluse în raport etc.
SFAT
Spre deosebire de marea majoritate a produselor de realizare a
rapoartelor, Visual FoxPro permite "dragarea" controalelor dintr-o
banda în alta.
Banda page header band va fi afişată în partea de sus a fiecărei pagini, iar banda page footer
band ar trebui să includă doar acele obiecte pe care doriţi să le vedeţi afişate în partea de jos a
fiecărei pagini.
SFAT
Page footers sunt cel mai bun loc pentru numere de pagină, date,
nume ale rapoartelor sau orice altă informaţie de care utilizatorii ar
avea nevoie în eventualitatea pierderii accidentale a unor pagini sau a
întregului raport.
Alte benzi ale rapoartelor. Dacă alegeţi să grupaţi datele, veţi fi capabili să amplasaţi
informaţiile în aşa-numitele benzi group header şi group footer. Benzile group header şi group
footer vă permit să aranjaţi rapoartele prin gruparea datelor şi să precizaţi informaţii privind
aceste grupuri. De exemplu, aţi putea sorta lista pacienţilor unui spital după tipul asigurării
medicale. O posibilitate ar fi să afişaţi fiecare nume şi fiecare tip de asigurare dar o altă opţiune
mai bună ar fi să grupaţi datele, afişând tipul asigurării doar o dată pentru mai multe nume.

42
Dacă alegeţi să creaţi un raport cu coloane multiple, aţi putea dori să includeţi headere şi footere.
Pentru a crea un raport cu coloane multiple, selectaţi File, Page Setup şi introduceţi numărul de
coloane în fereastra de dialog, precum şi lăţimea coloanelor şi spaţiul dintre acestea.
Tabelul 1. Controalele ferestrei de dialog Page Setup
Control Descriere
Number spinner Utilizaţi acest "spinner" (contor) pentru a creşte sau descreşte
numărul de coloane din raportul dvs.
Width spinner Utilizaţi acest spinner pentru a stabili lăţimea coloanelor.
Spacing spinner Utilizaţi acest spinner pentru a stabili lăţimea spaţiului dintre
coloane.
Print Area options Utilizaţi aceste opţiuni pentru a determina modul în care marginile
de imprimare sunt "manevrate" de către raport. Dacă selectaţi
Printable Page, zona imprimabilă a paginii este determinată în
concordanţă cu specificaţiile implicite ale imprimantei şi este
afişată în zona Page Layout a ferestrei de dialog. Dacă selectaţi
Whole Page, raportul dvs. va "umple" întreaga pagină.
Print Setup button Utilizaţi acest buton pentru a deschide fereastra de dialog
Windows Print Setup, unde puteţi modifica setările implicite ale
imprimantei instalată implicit sub Windows.
Print Order buttons Utilizaţi aceste butoane pentru a determina umplerea coloanelor
verticale de sus în jos şi de la stânga la dreapta începând din partea
de sus a paginii.
Left Margin spinner Utilizaţi acest spinner pentru a stabili lăţimea marginii din stânga.

ORDONAREA ŞI GRUPAREA DATELOR ÎN RAPOARTE


Datele din raport vor fi afişate în ordinea furnizată de sursa de date. Nu puteţi stabili o ordine
specială de afişare a datelor într-un raport, însă puteţi stabili ordinea sau indexarea în tabela sau
vederea pe care se bazează raportul.
Având în vedere majoritatea rapoartelor "columnare", veţi subdiviza datele în grupuri. Puteţi
adăuga un grup efectuând un click asupra butonului Insert. Tastaţi expresii în caseta de text sau
efectuaţi click asupra butonului elipsă pentru a deschide Expression Builder-ul din Visual
FoxPro. Atunci când se utilizează grupuri, raportul începe un nou grup ori de câte ori se modifică
expresia de bază pentru grup. Din acest motiv, sursa de date trebuie să fie ordonată în
concordanţă cu criteriul de grupare: Visual FoxPro nu poate căuta toate înregistrările relative la
un grup. De îndată ce rezultatele expresiei de grupare se modifică, se calculează subtotaturi de
grup, se imprimă banda grupului şi începe un nou grup .
SFAT
Expresia Group va fi cel mai adesea un câmp, dar poate fi şi o variabilă sau o
funcţie definită de către utilizator. De fapt, poate fi şi o expresie concatenată
ce combină două câmpuri.
Zona Group Properties indică comportamentul modificării fiecărui grup. Dacă raportul dvs. are
mai mult de o coloană, caseta de text Start Group asupra New Column afişează o nouă coloană
de fiecare dată când se modifică expresia de grupare. Startând Each Group într-o New Page
inserează un "page break" ori ce câte ori expresia grup se modifică. Resetaţi Page Number la 1
pentru Each Group pentru a indica faptul că contorul de pagină va fi restartat pentru fiecare nou
grup. Acestă utilitate este suficientă dar un raport urmează a fi "împărţit" şi trimis la mai mulţi
recipienţi. Header-ul Reprint Group pe fiecare Each Page box, atunci când este selectat, "spune"
Visual FoxPro-ului să afişeze header-ul grupului pe fiecare pagină pe care este afişat.
Controlul Start Group pe New Page When Less Than spinner control ajută în prevenirea unui
header de grup să fie prea aproape de josul unei pagini. Atunci când aţi terminat definirea
43
grupurilor, click OK pentru a închide fereastra de dialog. Benzile pentru noile grupuri vor apare
în raport. Cu toate acestea, implicit, acestea nu ocupă nici un fel de spaţiu.

SĂ PROFITĂM DE AVANTAJELE LUI DATA ENVIRONMENTS ŞI DATA SESSIONS


Pentru a deschide fereastra Data Environment, alegeţi View, Data Environment sau efectuaţi
right-click pe suprafaţa raportului, selectaţi opţiunea Environment din meniul shortcut.
În oricare mod veţi obţine o reprezentare vizuală a mediului datelor (Data Environment) şi veţi
putea alege să adăugaţi tabele, cursoare sau vederi după cum doriţi. Fiecare obiect este adăugat
ca un obiect de tip cursor, împreună cu setul complet de proprietăţi, evenimente şi metode. Puteţi
stabili relaţii vizuale între obiectele cursor sau puteţi accesa proprietăţile, evenimentele şi
metodele tabelelor, cursoarelor şi relaţiilor via ferestrele Code (pentru cod) şi Properties (pentru
proprietăţi).
Pentru a adăuga tabele sau vederi la Data Environment, selectaţi Data Environment, Add, sau
efectuaţi click dreapta pe „designer-ul” Data Environment şi selectaţi Add. Dacă o bază de date
este deja deschisă,acea bază de date şi tabelele sau vederile sale vor apare în fereastra de dialog
Add Table or View . Dacă nu există o bază de date curentă deschisă, sau dacă alegeţi Other, o
fereastra de dialog GetFile va apare pentru dvs. pentru a alege o tabelă.. Dacă selectaţi o tabelă
ce aparţine unei baze de date ce nu a fost încă deschisă, Visual FoxPro „leagă” tabela la baza de
date şi deschide tabela în mod automat.
Dacă doriţi să lucraţi într-o „vedere” în loc de o tabelă selectaţi butonul de opţiune View iar lista
tabelelor va fi înlocuită de lista vederilor din baza de date..
Odată ce o tabelă sau o vedere a fost adăugată la Data Environment, o puteţi browsăi efectuând
right-click pe tabela sau vedere şi selectând Browse din shortcut menu. De asemenea, puteţi
selecta Data Environment, Browse din meniul principal, dar doar dacă tabela sau vederea a fost
deja selectată (selectaţi-o prin clicking it). De aici, puteţi drag and drop câmpuri pe suprafaţa
raportului.
După adăugarea unei tabele sau vederi la Data Environment, puteţi accesa proprietăţile sale prin
fereastra Properties.
Lucrul cu relaţii în Data Environment Designer
Crearea unei relaţii între obiectele cursor din Data Environment este uşoară. Selectaţi câmpul
relaţie din sursa de date părinte, apoi dragaţi-l peste sursa de date copil..Tabelul copil trebuie să
posede un index pe acest câmp. În caz contrar, Visual FoxPro se oferă să creeze un index pentru
dvs.
Aşa cum Data Environment face ca raportul dvs. să ruleze mai uşor, sesiunile private de date fac
ca procesul de "curăţare" după rularea raportului să fie banale. O sesiune privată de date este o
zona mică, relativ protejată a aplicaţiei dvs, permiţând unui raport să modifice pointerii
(indicatorii către înregistrări), ordinea indecşilor, relaţiilor sau a oricăror alte setări fără a afecta
formularul curent sau mediul datelor.
Puteţi asigna cu uşurinţă un raport sesiunii sale de date. Alegeţi doar Report, Private Data
Session din meniul sistem. Astfel se stabileşte atributul sesiunii private de date on sau off.

STRATEGII DE PROIECTARE
O planificare adecvată vă poate ajuta să economisiţi mult timp şi efort, evitând totodată
rapoartele ce nu furnizează utilizatorilor informaţiile necesare. Atunci când proiectaţi rapoarte,
sarcina dvs. este de a prelua datele furnizate de o tabelă sau de o interogare şi să le transformaţi
într-un raport ce asigură informaţiile într-o manieră ce are sens pentru utilizator. Iată câţiva paşi
sau etape utile în proiectarea unui raport:
• Discutaţi forma raportului cu utilizatorii şi, dacă este posibil, căutaţi să examinaţi copii
ale unor rapoarte existente.
• Proiectaţi forma pe hârtie şi specificaţi orice operaţii de grupare, calculare a unor
subtotaluri sau de formatare.

44
• Decideţi dacă puteţi utiliza o sesiune privată de date şi Data Environment sau dacă veţi
crea un "cursor" în una curentă înainte de rularea raportului.
• Proiectaţi raportul în Visual FoxPro.
• Previzualizaţi sau tipăriţi raportul, apoi căutaţi feed-back-ul din partea utilizatorilor.

CREAREA UNUI RAPORT CU REPORT WIZARD


Asistentul Visual FoxPro Report Wizard asigură o modalitate automată de creare a unui raport
într-o diversitate de stiluri şi moduri. Pentru a lansa Report Wizard-ul, selectaţi Tools, Wizards,
Report. Va apare fereastra de dialog prezentată în fig. nr. 17.

Fig. nr. 17. Fereastra de dialog de selectare a tipului de raport


Rapoartele One-to-many sunt utilizate pentru a crea rapoarte "relaţionale", ce afişează o
înregistrare din tabela primară (sau tabela "părinte") împreună cu toate înregistrările asociate din
tabela secundară sau tabela "copil". Raportul standard "one-source report" afişează datele aşa
cum apar acestea într-o singură sursă de date.
Executând click pe butonul OK sau dublu-click pentru a alege tipul raportului pe care doriţi să îl
creaţi va apare fereastra de dialog prezentată în fig. nr. 18:

Fig. nr. 18. Primul pas al asistentului Report Wizard


Selectaţi baza de date dorită şi tabela asociată din opţiunile Databases şi Tables din stânga. Veţi
observa o listă de câmpuri disponibile. Puteţi efectua click pe butonul de comandă "săgeată spre
dreapta" pentru a muta câmpurile pe care doriţi să le selectaţi în ordinea în care doriţi. Butonul
"Săgeată dublă" va deplasa toate câmpurile disponibile în lista intitulată Selected fields.
Următoarea fereastra de dialog prezentată în fig. nr. 19 permite selectarea tabelei "copil" pe baza
căreia se va realiza raportul.

45
Fig. nr. 19. Al doilea pas al asistentului Report Wizard
Fereastra de dialog din fig. nr. 20 permite stabilirea modalităţii de legătură dintre cele două
tabele utilizate pentru realizarea raportului.

Fig. nr. 20. Al treilea pas al asistentului Report Wizard


În fereastra de dialog asociată pasului 4 puteţi selecta ordinea pentru raportul dvs. (fig. nr. 21).
Reamintiţi-vă că ordinea pe care o alegeţi trebuie să corespundă criteriilor dvs. de grupare pentru
ca acestea să funcţioneze corect.

46
Fig. nr. 21 Pasul patru al asistentului Report Wizard
În următoarea fereastră de dialog puteţi selecta un stil pentru raportul dvs., din cele cinci stiluri
disponibile şi puteţi stabili dacă raportul va fi imprimat în modul landscape sau portrait (Fig. nr.
22).

Fig. nr. 22. Al cincilea pas al asistentului Report Wizard


Utilizând butonul Summary Options din fereastra pasului 5 al asistentului puteţi solicita unul sau
mai multe tipuri de calcule asupra unuia sau mai multor câmpuri ale raportului creat (Fig. nr.23).

47
Fig. nr. 23. Fereastra de dialog Summary Options
Ultima fereastră de dialog întreabă dacă doriţi să salvaţi raportul în vederea unei utlizări
ulterioare, să-l salvaţi şi să-l rulaţi imediat sau să-l salvaţi şi să-l modificaţi imediat (fig. nr. 24).

SFAT
Asistentul Report Wizard poate fi un instrument util pentru crearea
unui simplu form, prototipizarea unui form sau învăţarea mai multor
lucruri despre obiectele Report Designer şi modul în care acestea
lucrează.

.
Fig. nr. 24. Ultimul pas al asistentului Report Wizard

RULAREA RAPORTELOR
Puteţi imprima un raport completat utilizând una din următoarele metode:
• Din Project Manager, click tab-ul Document, click şi selectaţi un raport, apoi click
butonul Print din linia de instrumente Standard.
• Din fereastra de comenzi (sau din cod program), utilizaţi comanda Report Form.
Această comandă are următoarea sintaxă:

48
REPORT FORM nume_raport TO PRINT | PREVIEW | TO
filename | FOR filter expression
Reţineţi că rapoartele dvs. vor fi formatate pentru imprimanta instalată implicit.
Pentru a rula aceleaşi rapoarte la o imprimantă diferită unele alinieri şi spaţieri ar
trebui reactualizate. Visual FoxPro face o treabă bună în general în rezolvarea
diferenţelor dacă imprimantele utilizate sunt relativ standardizate şi nu foarte
diferite una faţă de alta.
Alegerea unei destinaţii
Utilizând comanda Report Form puteţi direcţiona "ieşirea" unui raport către una sau mai
multe destinaţii. Dacă doriţi să imprimaţi raportul comanda va arăta astfel:
REPORT FORM Raportul_meu TO PRINT
Dacă doriţi să previzualizaţi raportul în loc să-l trimiteţi direct la imprimantă utilizaţi următoarea
comandă:
REPORT FORM Raportul_meu TO PRINT PREVIEW
Dacă doriţi să salvaţi textul raportului într-un fişier ASCII:
REPORT FORM Raportul_meu TO FILE Fişierul_meu.txt
ASCII

În mod implicit, rapoartele rezultate sunt afişate şi pe ecran în timp ce sunt generate. Pentru a
preveni acest lucru, utilizaţi opţiunea NOCONSOLE.

49

You might also like