Sunteți pe pagina 1din 132

Baze de date SGBD FoxPro

Cap. I INTRODUCERE
1.1 Organizarea datelor

Calculatoarele personale au apărut din necesitatea


stocării şi prelucrării cât mai rapide a informaţiilor. Evoluţia
tehnicii de calcul a dus la o creştere substanţială a capacităţii
de memorare şi a vitezei de prelucrare a datelor. Ţinând cont
de aceşti doi parametrii, problemele rezolvate cu ajutorul
calculatorului pot fi clasificate în:
- probleme care implică prelucrări reduse asupra unui
volum mare de date;
- probleme care implică un volum mediu de prelucrări
asupra unui volum mediu de date;
- probleme care implică un volum mare de prelucrări
asupra unui volum mic de date;
Sistemele de gestiune a bazelor de date reprezintă
sisteme informatice specializate în stocarea şi prelucrarea unui
volum mare de date, deci în rezolvarea problemelor de primul
tip.
Organizarea datelor ocupă un loc important în
proiectarea sistemelor informatice, de aceasta depinzând
eficienţa sistemului informatic. Organizarea datelor
presupune:
- definirea, structurarea, ordonarea şi gruparea datelor
în colecţii omogene de date ;
- stabilirea legăturilor (relaţiilor) între date, între
elementele unei colecţii de date, respectiv între colecţii de
date;
- reprezentarea datelor pe un suport informaţional
prelucrabil într-un sistem de calcul.
Pe lângă cerinţele legate de timpul de acces la date, de
spaţiul de memorie, organizarea datelor urmăreşte realizarea
unicităţii datelor.

5
Baze de date SGBD FoxPro

1.2 Concepte utilizate în organizarea datelor

Conceptele de bază introduse în literatura de


specialitate o dată cu apariţia bazelor de date sunt :
- entitate
- atribut
- valoare
Aceste trei concepte sunt legate între ele. Prin entitate
se înţelege un obiect concret sau abstract reprezentat prin
proprietăţile sale. Orice proprietate a unui obiect poate fi
exprimată printr-o pereche de tipuri atribut-valoare. Prin
urmare, entităţile se pot exprima printr-o mulţime de perechi.
Un exemplu de entitate : (persoană /nume: Popescu,
vârsta: 25, adresa…).
Mulţimea unor atribute se poate uneori asocia mai
multor entităţi. Astfel atributele nume, vârstă din exemplul
anterior pot caracteriza în general orice persoană, deci
atributul caracterizează nu doar o entitate, ci poate caracteriza
o clasă de entităţi numită uneori entitate grup. Elementele
unor entităţi grup cu aceleaşi atribute sunt de acelaşi tip, de
aici denumirea de tip de entităţi pentru clase de entităţi.
Noţiunea de atribut este cunoscută şi sub denumirea de
câmp sau caracteristică. Atributul este caracterizat de natura
valorii sale. Astfel, dacă de exemplu valoarea sa este
numerică, atributul are tipul numeric.
Un alt concept este cel de dată. Data reprezintă un
model de organizare a informaţiei. O dată indivizibilă în raport
cu informaţia pe care o reprezintă, dar şi în raport cu modul de
prelucrare se numeşte dată elementară. Mai multe date
elementare pot forma o dată compusă. Data poate fi definită
din punct de vedere logic prin identificator, atribut şi valoare.
Din punct de vedere fizic, datei îi corespunde o zonă de
memorie de o anumită mărime, situată la o adresă absolută.

1.3 Structuri de date

Structurile de date sunt colecţii de date între care s-au


stabilit o serie de relaţii care conduc la un mecanism de
selecţie şi identificare a componentelor. Mulţimea de date
asociată structurii poate conţine date de acelaşi tip sau de mai
multe tipuri. Localizarea componentelor structurii poate fi
făcută fie prin nume identificator, fie prin poziţia ocupată în
6
Baze de date SGBD FoxPro

structură. Dacă localizarea se face prin parcurgerea


componentelor aflate înaintea sa în ordinea specificată, atunci
accesul este secvenţial. Dacă o componentă poate fi selectată
fără a ţine seama de celelalte componente, atunci structura are
un acces direct. Componentele unei structuri de date pot fi
simple sau chiar structuri de date. Asupra unei structuri de
date pot fi efectuate o mulţime de operaţii, cele mai importante
fiind:
- Crearea şi memorarea datelor în forma iniţiala pe
suport magnetic
- Consultarea (accesul) la componentele structurii în
vederea prelucrării informaţiilor
- Actualizarea (schimbarea) stării structurii prin
adăugarea sau ştergerea unor elemente, modificarea valorii
unor elemente, modificarea relaţiilor dintre ele.
- Sortarea (aranjarea elementelor unei structuri după
anumite criterii)
- Ventilarea (spargerea structurii de date în două sau
mai multe structuri)
- Copierea
Toate structurile de date care au aceeaşi structură şi sunt
supuse aceloraşi operaţii, formează un tip de structură de date.

1.4 Baze de date

Conceptul de baze de date a apărut în anul 1969, cu


ocazia prezentării primului raport CODASYL într-o conferinţă
pe probleme de limbaje de gestiune a datelor. Ideea principală
constă în existenţa unui fişier de descriere globală a datelor.
Conceptul a fost ulterior dezvoltat şi s-a ajuns la următoarele
tipuri de baze de date :
- Baze de date reţea (distribuite)
- Baze de date relaţionale
- Baze de date orientate pe obiecte
În esenţă, conceptul de bază de date se defineşte ca una
sau mai multe colecţii de date în interdependenţă, împreună cu
descrierea datelor şi a relaţiilor dintre ele. O bază de date
trebuie să îndeplinească următoarele condiţii :
- a) Să asigure o interdependenţă sporită a datelor faţă
de program şi invers

7
Baze de date SGBD FoxPro

- b) Conceperea structurii bazei de date trebuie şi se


facă astfel încât să asigure informaţii necesare şi suficiente
pentru cerinţele de informare şi decizie
- c) Să asigure o redundanţă minimă (redundanţă = ceva
care se repetă)
- d) Să permită accesul rapid la informaţiile stocate în
baza de date
Bazele de date sunt extrem de variate. Arhitectura
bazelor de date evidenţiază structura acestora şi este
standardizată. Arhitectura generală cuprinde următoarele
elemente:
- baza de date propriu-zisă, în care se memorează
colecţia de date
- sistemul de gestiune a bazei de date, acesta fiind un
ansamblu de programe care realizează gestiunea şi prelucrarea
complexă a datelor
- un dicţionar al bazei de date (metabaza de date) care
conţine informaţii despre date, structura acestora, elemente de
descriere a semanticii, etc.

1.5 Sisteme de gestiune a bazelor de date (SGBD)

Data Base Management System – DBMS în engleză


Un sistem de gestiune a bazelor de date asigură
realizarea următoarelor activităţi :
- Definirea structurii bazei de date
- Încărcarea datelor în baza de date
- Accesul la date (interogare, actualizare)
- Întreţinerea bazei de date
- Reorganizarea bazei de date
- Securitatea datelor
Deci un sistem de gestiune a bazelor de date este un
sistem complex de programe care asigură interfaţa între o bază
de date şi utilizatorii acestuia. În vederea satisfacerii
obiectivelor informaticii (culegerea, verificarea, transmiterea,
stocarea şi prelucrarea automată a datelor), precum şi a
cerinţelor impuse de nevoia de informare eficientă, un SGBD
trebuie să îndeplinească mai multe obiective :
- Asigurarea independenţei datelor
- Asigurarea unei redundanţe minime
- Asigurarea unor facilităţi sporite de utilizare a datelor
- Sporirea gradului de securitate a datelor
- Asigurarea partajabilităţii datelor
8
Baze de date SGBD FoxPro

În scopul realizării acestor obiective, un sistem de


gestiune a bazelor de date asigură realizarea mai multor
operaţii grupate pe funcţii. Funcţiile sistemelor de gestiune a
bazelor de date sunt următoarele :
- Funcţia de descriere a datelor - permite definirea
bazelor de date cu ajutorul unui limbaj de definire. Definirea
se poate realiza la un nivel logic, conceptual şi fizic. La
nivelul acestei funcţii se descriu multitudinea atributelor
(câmpurilor), a relaţiilor dintre entităţi sau atributele entităţilor
şi eventual criterii de validare a datelor. Rezultatele acestei
funcţii se concretizează în schema bazei de date memorate în
cod intern
- Funcţia de manipulare a datelor - este cea mai
complexă, aceasta cuprinzând pe lângă elementele de creare a
bazei de date şi elementele de adăugare, ştergere a
înregistrărilor, modificarea valorilor, căutare, sortare, editare
înregistrări, etc. Aceasta se realizează prin intermediul unui
limbaj de manipulare a datelor.
- Funcţia de utilizare asigură mulţimea interfeţelor
necesare pentru comunicarea tuturor utilizatorilor cu baza de
date.
- Funcţia de administrare a bazelor de date este de
competenţa administratorilor de baze de date, care se ocupă de
rezolvarea problemelor care apar şi de integritatea datelor.
În domeniul bazelor de date, modelul relaţional ocupă
un loc central, sistemul de gestiune a bazelor de date
relaţionale dominând de multă vreme lumea bazelor de date.

9
Baze de date SGBD FoxPro

REZUMAT (Cap. I)

Conceptele de bază introduse în literatura de specialitate o


dată cu apariţia bazelor de date sunt :
- entitate
- atribut
- valoare

Structurile de date sunt colecţii de date între care s-au stabilit


o serie de relaţii care conduc la un mecanism de selecţie şi
identificare a componentelor.

Asupra unei structuri de date pot fi efectuate o mulţime de


operaţii, cele mai importante fiind:
- crearea şi memorarea datelor în forma iniţiala pe
suport magnetic
- consultarea (accesul) la componentele structurii în
vederea prelucrării informaţiilor
- actualizarea (schimbarea) stării structurii prin
adăugarea sau ştergerea unor elemente, modificarea valorii
unor elemente, modificarea relaţiilor dintre ele.
- sortarea (aranjarea elementelor unei structuri după
anumite criterii)
- ventilarea (spargerea structurii de date în două sau
mai multe structuri)
- copierea

Toate structurile de date care au aceeaşi structură sunt


supuse aceloraşi operaţii şi formează un tip de structură de
date.

Conceptul de bază de date se defineşte ca una sau mai multe


colecţii de date în interdependenţă, împreună cu descrierea
datelor şi a relaţiilor dintre ele. Conceptul a fost ulterior
dezvoltat şi s-a ajuns la următoarele tipuri de baze de date :
- Baze de date reţea (distribuite)
- Baze de date relaţionale
- Baze de date orientate pe obiecte

10
Baze de date SGBD FoxPro

Un sistem de gestiune a bazelor de date este un sistem


complex de programe care asigură interfaţa între o bază de
date şi utilizatorii acestuia.

Funcţiile sistemelor de gestiune a bazelor de date sunt


următoarele :
- Funcţia de descriere a datelor
- Funcţia de manipulare a datelor
- Funcţia de utilizare
- Funcţia de administrare a bazelor de date

În domeniul bazelor de date, modelul relaţional ocupă un loc


central, sistemul de gestiune a bazelor de date relaţionale
dominând multă vreme lumea bazelor de date.

ÎNTREBĂRI

Ce se înţelege printr-o structură de date?

Care sunt regulile care stau la baza organizării datelor?

Precizaţi ce operaţii pot fi efectuate asupra unei structuri de


date?

Ce este un tip de structură de date?

Ce este o bază de date?

Care sunt cele mai importante tipuri de baze de date?

Definiţi un sistem de gestiune a bazelor de date (SGBD).

Care sunt funcţiile unui sistem de gestiune a bazelor de date?

Care este cel mai utilizat tip de bază de date (din punct de
vedere conceptual)?

11
Baze de date SGBD FoxPro

CAP. II SISTEMUL DE GESTIUNE A


BAZELOR DE DATE (SGBD) FoxPro
Mediul de programare FoxPro este un sistem software
pentru gestiunea bazelor de date, asigurând o interfaţă foarte
eficientă şi prietenoasă între sistemul de operare şi
programator. A fost realizat de firma FoxSoftware şi este
foarte răspândit şi utilizat la noi în ţară, dar şi în străinătate.
Din punct de vedere al limbajului propriu-zis de
programare (comenzi, funcţii) FoxPro este extrem de
asemănător cu dBase. Componenta principală care le
diferenţiază este interfaţa grafică de prezentare şi lucru. De
fapt, este destul de dificil ca, la o simpla studiere a unui
program sursă să se poată preciza dacă acesta a fost scris în
FoxPro sau în dBase.
O lungă perioadă de timp, supremaţia în domeniu a
aparţinut firmei Ashton-Tate cu produsul ei de bază dBase
(III, III+, IV), având ca principali concurenţi firmele Borland
(cu produsele Paradox), Nantucket (Cliper). Spre deosebire de
dBase şi Paradox, FoxPro este un compilator al aplicaţiilor cu
baze de date, asigurând o viteza de lucru mult sporită şi o bună
protecţie a datelor. Unele operaţii executate în FoxPro sunt de
peste 100 de ori mai rapide decât cele ale concurentului direct,
dBase. Obţinerea acestei viteze este data de folosirea unei
tehnologii speciale de optimizare a interogării bazelor de date
(tehnologia Rushmore). De asemenea, este asigurată o
compatibilitate aproape totală cu programele dBase (avantaj
de loc de ignorat, ţinând cont de volumul mare de aplicaţii
scrise deja în acest limbaj). Sunt prevăzute şi o serie de
instrucţiuni SQL.
FoxPro este un sistem de gestiune a bazelor de datelor
relaţional. Prezenta lucrare se opreşte asupra versiunii FoxPro
2.6, care aduce o serie de îmbunătăţiri majore faţă de unele

12
Baze de date SGBD FoxPro

versiuni anterioare (FoxPro 1.0, Foxbase+). Câteva


performanţe de bază ale SGBD-ului FoxPro sunt prezentate în
continuare:
- număr maxim de înregistrări: 1 miliard
- dimensiunea maximă a unei înregistrări: 4000 octeţi
- număr maxim de câmpuri: 255
- suport SQL
- suport Windows
- meniuri pull-down
- tehnici speciale de indexare

2.1 Generalităţi

Structura unei baze de date

Structura unei baze de date se stabileşte la crearea


fişierului bază de date prin definirea fiecărui câmp. Comenzile
utilizate sunt : CREATE, MODIFY STRUCTURE. Câmpul
este cel mai mic element al unei baze de date care poate fi
accesat, definirea câmpului presupunând specificarea
următoarelor elemente :
- numele câmpului care este un identificator de maxim
10 caractere (nu acceptă spaţii ci doar puncte sau liniuţe)
- tipul câmpului (exemple de tipuri : caracter, numeric,
float, date, logic, memo, picture şi generator).
- dimensiunea câmpului - reprezintă numărul de spaţii
alocate pentru scrierea informaţiilor.
La câmpurile de tip memo, logic şi dată calendaristică
nu se poate modifica dimensiunea, aceasta fiind predefinită.

Proiectarea unei baze de date

În proiectarea unei baze de date se va ţine cont de


informaţia care va fi conţinută în câmpurile fişierului bazei de
date, dar şi de prelucrările la care va fi supusă baza de date. Se
va crea o primă structură a fişierului bază de date, pe baza
informaţiilor deţinute, structura putânf fi ulterior îmbunătăţită,
existând metode rapide de modificare a acesteia.
În proiectarea unei baze de date trebuie să se ţină cont şi
de HARD-ul - SOFT-ul calculatorului.
Un articol poate conţine maxim 4 Kocteţi de informaţii.
Numărul maxim de câmpuri este 255 şi iar numărul maxim de
articole poate ajunge până la 1 miliard.
13
Baze de date SGBD FoxPro

Observaţie:
La proiectarea unei baze de date este recomandabil să se
utilizeze metoda interactivă (din aproape în aproape).
Dacă numărul de câmpuri necesar este prea mare, baza
de date poate fi formată din două sau mai multe fişiere care
pot fi relaţionate între ele.

Figura 1. Vedere generală asupra unei aplicaţii FoxPro

14
Baze de date SGBD FoxPro

Tipuri de fişiere în FoxPro (figura2)

1. Fişiere bază de date, cu extensia .dbf - sunt fişiere


care conţin datele structurate pe înregistrări: “prima” pseudo
înregistrare a unui astfel de fişier conţine structura fişierului.
Fişierele baze de date sunt entităţi de bază ale FoxPro, crearea
şi exploatarea lor reprezentând scopul principal. Crearea unui
astfel de fişier se poate face cu ajutorul comenzii CREATE
[<nume_baza>], iar modificarea structurii cu comanda
MODIFY STRUCTURE.
2. Fişiere de comenzi şi proceduri (fişiere program) cu
extensia .prg. Aceste fişiere conţin seturi de instrucţiuni care
sunt memorate ca programe. Ele sunt de fapt fişiere ASCII. Se
creează cu comanda MODIFY COMMAND
[<nume_program>]. Lansarea în execuţie a unui program
(fişier de comenzi sau procedura) se face cu comanda DO
<nume_program>.
3. Fişiere INDEX având extensia .idx sau .cdx - permit
folosirea bazelor de date în ordinea logică dorită a
înregistrărilor (şi nu în ordinea firească a înregistrărilor).
Acest fişiere leagă de fapt numerele înregistrărilor de o cheie.
Atunci când definim o bază de date împreună cu un fişier
index, articolele din bază de date apar în ordinea specificată de
câmpuri cheie. Cheia poate fi formată dintr-un câmp sau mai
multe câmpuri şi este utilizată pentru accesarea înregistrărilor.
Fişierele index se creează cu ajutorul comenzii INDEX.
4. Fişierele tip MEMO - sunt fişiere auxiliare fiind
ataşate unei baze de date şi utilizate pentru memorarea
informaţiilor din câmpurile de tip memo. Fiecare înregistrare a
unei baze de date poate avea până la 255 de câmpuri.
5. Fişiere de tip Format - având extensia .fmt.
Reprezintă nişte machete de ecran (formate de ecran) care pot
fi utilizate la introducerea datelor şi la afişarea acestora. Ele
pot fi create fie cu ajutorul comenzii MODIFY
COMMAND, fie vor fi generate din fişiere de tip SCREEN.
6. Fişiere ecran sau fişiere SCREEN având extensia
.scx. Conţin informaţii referitoare la machetele de ecran şi se
creează cu comenzile CREATE SCREEN sau MODIFY
SCREEN.
7. Fişiere de memorie conţin valorile unor variabile de
memorie (până la 256 de variabile) şi sunt folosite pentru a
salva conţinutul acestora în vederea utilizării lor ulterioare.
Extensia acestor fişier este .mem. Ele se creează cu comanda
15
Baze de date SGBD FoxPro

SAVE, iar comanda care oferă posibilitatea reutilizării


informaţiei (restaurare în memorie a variabilelor) din acel
fişier este comanda RESTORE.
8. Fişiere de interogare (fişiere QUERY)
9. Fişiere pentru macrouri au extensia .fky
10. Fişiere de tip text au extensia .txt
11. Fişiere REPORT - au extensia .std
12. Fişiere LABEL - similar cu fişierele REPORT
13. Fişiere PROJECT
14. Fişiere MENU

Figura 2. Creare fişier (tipuri de fişiere)

Variabile de memorie

Sunt tipuri speciale de variabile care memorează datele


în afara bazelor de date (în memorie). Acestea pot fi folosite
pentru calcule intermediare sau pentru a controla execuţia
programelor. Numele variabilelor pot conţine maxim 10
caractere. Există 4 tipuri de variabile de memorie :
- tipul caracter
- tipul numeric
- tipul logic
- tipul dată calendaristică
Pot exista maxim 256 de variabile de memorie, cu
condiţia ca spaţiul ocupat de ele în memorie să nu depăşească
4 kocteţi.

16
Baze de date SGBD FoxPro

Expresii şi operatori în limbajul FoxPro

O expresie este formată dintr-o combinaţie de câmpuri,


variabile de memorie, constante, funcţii şi operatori.
Operatorii principali care se pot utiliza sunt :
- operatori aritmetici (+, - , *, /)
- operatori relaţionali care generează rezultate logice şi
pot fi folosiţi în expresii cu caractere, cu numere şi cu semne
convenţionale ( <, >, <=, >=, =).
- operatori pentru şiruri de caractere (exemplu: $ -
operator de verificare a includerii unui subşir într-un şir de
caractere).
- operatori logici care determină un rezultat de tip logic
prin aplicarea lor asupra a două expresii logice (sau una):
(.NOT., .AND., .OR.).
Pentru şirul de caractere şi dată calendaristică, se pot
utiliza şi operatorii + sau -.

REZUMAT (Paragraf 2.1)

Mediul de programare FoxPro este un sistem software pentru


gestiunea bazelor de date, asigurând o interfaţa foarte
eficienta şi prietenoasa intre sistemul de operare şi
programator.

Structura unei baze de date se stabileşte la crearea fişierului


bază de date prin definirea fiecărui câmp.

Câmpul este cel mai mic element al unei baze de date care
poate fi accesat, definirea câmpului presupunând specificarea
următoarelor elemente: numele câmpului, tipul câmpului,
dimensiunea câmpului.

Tipuri principale de câmpuri în FoxPro: caracter, numeric,


float, dată calendaristică (date), logic, memo.

Principalele tipuri de fişiere in FoxPro sunt: baze de date,


fişiere program, fişiere index, fişiere memo, fişiere format,
fişiere report, fişiere screen, fişiere de memorie etc.

Variabile de memorie sunt tipuri speciale de variabile care

17
Baze de date SGBD FoxPro

memorează date în afara bazelor de date (în memorie).

Tipuri de variabile de memorie : tipul caracter, tipul


numeric, tipul logic, tipul dată calendaristică
O expresie e formată dintr-o combinaţie de câmpuri, variabile
de memorie, constante, funcţii şi operatori.

Operatorii care se pot utiliza in FoxPro sunt: operatori


aritmetici, operatori relaţionali (care generează rezultate
logice), operatori pentru subşiruri de caractere, operatori
logici (determinând un rezultat de tip logic).

ÎNTREBĂRI

Ce este FoxPro?

Definiţi structura unei baze de date.

Ce este un câmp si care sunt elementele definitorii ale


acestuia?

Ce tipuri de câmpuri cunoaşteţi (în FoxPro)?

În ce situaţie informaţia este stocată în două sau mai multe


fişiere bază de date?

Ce tipuri principale de fişiere FoxPro cunoaşteţi?

Ce este o variabila de memorie?

Ce tipuri de variabile de memorie cunoaşteţi (în FoxPro)?

Ce este o expresie în FoxPro?

Ce tipuri de operatori pot fi utilizaţi în cadrul unei expresii?

18
Baze de date SGBD FoxPro

2.2 Crearea / modificarea structurii unui fişier bază de


date

Comanda utilizată pentru crearea unui nou fişier bază


de date (operaţie care precede de regulă scrierea efectivă a
programului aplicaţie FoxPro) este:

CREATE [<fisier>/?]

unde parametrul <fisier> reprezintă numele fişierului bază de


date (.dbf) care va fi creat. Executarea acestei comenzi, are ca
urmare crearea fişierului bază de date cu numele specificat şi
intrarea într-o fereastră de definire a structurii bazei de date
(figura 3).
Comanda poate fi utilizată şi fără parametrul opţional
(doar CREATE), în acest caz numele fişierului nou creat fiind
cerut imediat după stabilirea structurii fişierului .dbf. Clauza ?
(CREATE ?) afişează toate fişierele existente (o fereastră de
genul Save As), permiţând denumirea fişierului înainte de
crearea structurii acestuia.

Figura 3. Creare structura bază de date

După crearea structurii, faza următoare constă în


introducerea de informaţie (articole efective) în baza de date
(figura 4).

19
Baze de date SGBD FoxPro

Figura 4. Introducere informaţie

Alte posibilităţi de creare a unui fişier bază de date

Comanda CREATE este folosită în etapa de creare a


unei baze de date, premergătoare operaţiei de realizare a
aplicaţiei program propriu-zise. O astfel de comanda nu este
inclusa în cadrul unei secvenţe de program, implicând un
dialog interactiv intre programator şi SGBD pentru definirea
câmpurilor bazei de date.
În situaţia în care este totuşi necesară crearea unor baze
de date on-line (pe parcursul rulării unui program), se
utilizează comenzi specifice, care evita un astfel de dialog de
definire a structurii bazei de date. Aceste metode se folosesc
în cazul în care se creează un fişier dinamic, prin program, ne
mai fiind necesară introducerea structurii de la tastatură.
Astfel, un nou fişier bază de date se poate crea prin
copierea structurii unui fişier bază de date existent. Prin
urmare, un fişier bază de date se poate crea pornind de la un
alt fişier bază de date numit sursă. Structura noului fişier bază
de date conţine fie toate câmpurile fişierului sursă, fie doar o
parte din acestea. Sintaxa comenzii este:

COPY STRUCTURE TO <fişier> [FIELDS


<listă_câmpuri>]

Fişierul sursă este fişierului activ (fişierul deschis în


zona de lucru curentă), iar numele fişierului care se creează
trebuie specificat în comandă (parametrul <fişier>). Fişierul
nou creat va conţine doar structura sursei (nu şi înregistrările).
Clauza FIELDS este opţionala, utilizarea ei permiţând

20
Baze de date SGBD FoxPro

selectarea doar a anumitor câmpuri din structura fişierului


sursă, care vor incluse în structura fişierului nou creat.

Exemplu:
** deschide fişierul sursa.dbf
USE sursa
** creează un nou fişier tinta1.dbf având
** aceeaşi structura cu a fişierului sursa.dbf
COPY STRUCTURE TO tinta1
** creează un nou fişier ţinta2.dbf,
** structura acestuia conţinând doar câmpurile nume şi salar
** din fişierului sursa.dbf (presupunând că şi acesta are
** doua astfel de câmpuri)
COPY STRUCTURE TO tinta2 FIELDS;
nume, salar

Observaţie: Caracterul punct_şi_virgula (;) la finalul unei


linii de cod arată că respectiva comandă (de pe aceea linie) se
continuă şi pe linia următoare.

În cazul în care se doreşte obţinerea unui nou fişier bază


de date care să conţină şi înregistrările fişierului sursă,
comanda adecvata este:

COPY TO <fişier>

O alta modalitate de creare a unui nou fişier .dbf constă


în crearea iniţiala a unui fişier intermediar (tot .dbf) cu
structura fixă, având câmpurile :
FIELD_NAME
FIELD_TYPE
FIELD_LEN
FIELD_DEC

Structura fişierului sursă (fişierul .dbf deschis în zona


de lucru curentă) se copiază în fişierul intermediar cu ajutorul
comenzii:

COPY STRUCTURE EXTENDED TO


<fişier_intermediar>

21
Baze de date SGBD FoxPro

Etapa a doua constă în crearea fişierului ţinta .dbf (care


va fi automat şi deschis), pe baza structurii memorate în
fişierul intermediar:

CREATE <fisier> FROM <fisier_ intermediar>

SGBD –ul FOXPRO dispune de 10 zone de lucru. Într-o


zona de lucru, la un moment dat, poate fi deschisă o singură
bază de date. Deschiderea unei noi baze de date într-o zona de
lucru în care este deschisa deja o baza, conduce automat la
închiderea bazei active, noua bază deschisa fiind cea activa.
Implicit în absenţa comenzii SELECT, la pornirea lucrului în
FoxPro se selectează ca zonă de lucru zona 1. Zona se
specifică fie cu un număr de la 1 la 10 fie cu o literă de la A
până la J, fie cu numele alias.
Comanda prin care se specifică zonă de lucru curentă
are sintaxa :

SELECT <zona_lucru> / <alias>

În general pointerul înregistrării se deplasează numai în


zona de lucru curentă. Excepţia apare când fişierul din zona de
lucru este relaţionat cu unul sau mai multe fişiere, caz în care
relaţia stabilită determină deplasarea pointerului înregistrării şi
în alte zone de lucru. În cazul în care nu s-a specificat zona de
lucru, ea va lua numele bazei de date deschisă în acea zonă.

Funcţii prin care se determina zona de lucru sau numele alias


sau numele bazei de date

- SELECT( ) - returnează numărul zonei de lucru active


- ALIAS ([<expr_numerica>]) - returnează numele
alias al zonei de lucru specificată prin expresia numerică, iar
dacă expresia numerică lipseşte - numele alias al zonei de
lucru curente.
- DBF ([<alias>]) - returnează numele bazei de date
deschisă în zona de lucru specificată prin aliasul său iar dacă
argumentul lipseşte, funcţia returnează numele fişierului activ
în zona de lucru curentă.
Exemplu:
Se presupune existenţa a două fişiere baze de date:
f1.dbf şi f2.dbf, care se doresc a fi deschise simultan în două

22
Baze de date SGBD FoxPro

zone de lucru; pe baza fişierului f1, se va crea un nou fisier


.dbf prin intermediul unui fişier intermediar:

SELECT 1
USE f1
SELECT 2
USE f2
SELECT 1
COPY STRUCTURE EXTENDED TO f3
CREATE nou FROM f3
DISPLAY STRUCTURE
USE
SELECT f2
USE

Observaţie :
Comanda de deschidere a unei baze de date USE
<nume_baza> determină odată cu deschiderea fişierului,
poziţionarea pointerului de înregistrare pe prima înregistrare a
fişierului care se deschide. Fiecare zonă de lucru păstrează
poziţia pointerului pentru fişierul corespunzător, memorând
poziţia în care a rămas în cadrul fişierului în urma unei
operaţii anterioare. Dacă fişierul este indexat, poziţionarea
pointerului în urma deschiderii fişierului, are loc nu pe prima
înregistrare fizica ci pe prima înregistrare logică.

Vizualizarea structurii unei baze de date

Pentru afişarea structurii unui fişier bază de date, se


utilizează comenzile:

DISPLAY STRUCTURE [IN <alias>] [TO PRINTER


/TO FILE <fişier>]

LIST STRUCTURE [IN <alias>][TO PRINTER/


TO FILE <fişier>]

Comenzile afişează structura fişierului bază de date


deschis, locaţia acestuia pe disc, numărul curent de înregistrări
şi data ultimei actualizări. Implicit comanda afişează structura
fişierului din zona de lucru curentă. Dacă se utilizează clauza
IN, se va afişa structura unui fişier din zona de lucru precizata
prin <alias> (<alias> - specifică numele zonei în care se află

23
Baze de date SGBD FoxPro

fişierul bază de date). Opţiunea TO PRINTER dirijează


afişarea spre imprimantă, iar opţiunea TO FILE va trimite
datele spre fişierul al cărui nume s-a specificat.
Diferenţa dintre cele două comenzi este că DISPLAY
afişează structura ecran cu ecran, iar LIST prin defilare.

Modificarea structurii unui fişier bază de date

După crearea unei baze de date şi chiar după începerea


scrierii aplicaţiei program propriu-zise, în foarte multe cazuri
apare necesitatea adăugării unor noi câmpuri sau modificării
datelor de definire a unor câmpuri existente. Cu alte cuvinte,
este necesară o modificare a structurii fişierului bază de date.
Comanda specifica unei astfel de operaţii este:

MODIFY STRUCTURE
Aceasta comanda permite revenirea la ecranul de
proiectare a structurii bazei de date pentru a realiza
modificarea de structură dorită.

REZUMAT (Paragraf 2.2)

Comanda utilizata pentru crearea unui nou fişier bază de date


este: CREATE [<fisier>/?].

Un nou fişier bază de date se poate crea şi prin copierea


structurii unui fişier bază de date deja creat şi deschis:
COPY STRUCTURE TO <fişier> [FIELDS
<listă_câmpuri>]

În cazul în care se doreşte obţinerea unui nou fişier bază de


date care să conţină şi înregistrările fişierului sursă,
comanda utilizată este: COPY TO <fişier>

O alta modalitate de creare a unui fişier .dbf constă în


crearea iniţiala a unui fişier intermediar cu comanda
COPY STRUCTURE EXTENDED TO <fişier_intermediar>
iar pe baza structurii memorate în fişierul intermediar cu
comanda:
CREATE <fisier> FROM <fisier_ intermediar>
se obţine un nou fişier bază de date.

24
Baze de date SGBD FoxPro

SGBD –ul FOXPRO dispune de 10 zone de lucru. Într-o zona


de lucru, la un moment dat, poate fi deschisă o singură bază
de date.

Comanda prin care se specifică zonă de lucru curentă are


sintaxa: SELECT <zona_lucru> / <alias>

Pentru afişarea structurii unui fişier bază de date, se


utilizează comenzile:
DISPLAY STRUCTURE [IN <alias>] [TO PRINTER
/TO FILE <fişier>]
sau
LIST STRUCTURE [IN <alias>][TO PRINTER/
TO FILE <fişier>]
Comenzile afişează structura fişierului bază de date deschis,
locaţia acestuia pe disc, numărul curent de înregistrări şi
data ultimei actualizări.

Modificarea structurii unui fişier bază de date se face cu


comanda MODIFY STRUCTURE.

ÎNTREBĂRI

Ce comenzi pentru crearea unui fişier bază de date


cunoaşteţi?

Ce este o zona de lucru? Câte zone de lucru sunt disponibile?

Ce se întimplă dacă în aceeaşi zonă de lucru sunt deschise


două fişiere bază de date?

Cum se poate vizualiza structura unei baze de date?

Cum se poate tipării (la imprimantă) structura unei baze de


date?

Cum se poate modifica structura unei baze de date?

Cu ce comandă se poate realiza o copie a unui fişier bază de


date?

25
Baze de date SGBD FoxPro

2.3 Activarea (deschiderea) / dezactivarea (închiderea)


unui fişier bază de date

Pentru a utiliza un fişier bază de date existent, el trebuie


activat sau deschis cu ajutorul unei comenzii de tip USE
[<clauze>]. Cu această comandă se poate realiza şi
operaţia de închidere a fişierului bază de date.
Observaţie: După executarea unei comenzi CREATE, deci
după operaţia de creare a unei baze de date, baza de date este
automat deschisă.
Comanda USE permite şi specificarea fişierelor index
corespunzătoare care vor fi deschise, precum şi zona de lucru
în care se va deschide fişierul .dbf. În general, în cazul în
care se lucrează simultan cu mai multe baze de date, zona de
lucru, se specifică anterior deschiderii cu ajutorul unei
comenzi SELECT.
Sintaxa comenzii USE este următoarea:

USE [<fişier>/?] [IN <zona de lucru>] [AGAIN]


[INDEX <lista>/?
[ORDER [<expresie_numerică> |
<fişier index>||[TAG] <nume_tag>
[OF <fişier.cdx>] [ASCENDING |DESCENDING]]]]
[ALIAS <nume_alias>][NOUPDATE][EXCLUSIVE]

USE ? - afişare listă cu fişiere existente pentru selectarea


bazei de date care se doreşte a fi deschisa.
USE <fisier> - deschide baza de date cu numele specificat
(in zona de lucru curenta).
Clauza IN specifică zona de lucru în care se doreşte
deschiderea fişierul bază de date.
Clauza INDEX permite specificarea fişierului index
corespunzător bazei de date care va fi deschis simultan cu
aceasta (sau a unei liste de maxim 10 fişiere din care se va
selecta unul cu opţiunile următoare din sintaxa comenzii). În
cazul absenţei clauzei ORDER, primul fişier din <lista> este
fişier index principal. Clauza ORDER determină fişierul index
principal (unul singur activ la un moment dat), fie prin
precizarea poziţiei acestuia în lista prin <expresie_numerica>
fie prin precizarea efectiva a numelui fişierului din lista
(parametrul <fisier index>). De asemenea prin clauza TAG se

26
Baze de date SGBD FoxPro

poate preciza cheia activă din fişierul index compus structural


sau cheia din fişierul index compus nestructural precizat prin
OF <fisier.cdx>. Opţiunile [ASCENDING |
DESCENDING] stabilesc tipul de ordonare realizată prin
fişierul index activ (valabile doar cu clauza ORDER).
Clauza ALIAS permite specificarea unui nume alias
pentru zona de lucru în care se deschide fişierul (alias poate fi
un nume, un număr sau o literă). Aliasul poate fi folosit în
continuare ca abreviere pentru numele fişierului bazei de date.
Existenţa clauzei NOUPDATE nu permite actualizarea
fişierului ce se deschide, ci doar citirea sa.
Comanda USE fără clauze, determină închiderea
fişierului bază de date deschis în zona de lucru curentă (şi
implicit a eventualelor fişiere index ataşate). Clauza
EXCLUSIVE este folosita pentru lucrul în reţea.

REZUMAT (Paragraf 2.3)

Pentru a utiliza un fişier existent, el trebuie activat sau


deschis cu ajutorul unei comenzii de tip USE [<clauze>].

Cele mai uzuale forme de utilizare sunt:


USE [<fişier>] – deschide baza de date <fişier>
USE – închide baza de date deschisă
USE [<fişier>] INDEX [<fisier_index>] – deschide baza de
date <fişier> cu un fişierul index (simplu) asociat
USE [<fişier>] ORDER [<nume_TAG>] - deschide baza de
date <fişier>, cu un fişierul index (compus - structural)
asociat, având activă eticheta <nume_TAG>

ÎNTREBĂRI

Care este comanda (în forma minimală) pentru deschiderea


unei baze de date?

Care este comanda pentru închiderea unei baze de date.

Care este efectul clauzei NOUPDATE într-o comandă USE?

27
Baze de date SGBD FoxPro

2.4 Adăugarea / ştergerea informaţiei din fişierele bază de


date

2.4.1 Adăugarea înregistrărilor

APPEND [BLANK] - determină adăugarea unei


înregistrări la sfârşitul unui fişier bază de date. Fişierul bază
de date trebuie să fie activ (deschis), ca urmare a introducerii
comenzii fiind deschisă o fereastră de editare a înregistrării
care se completează într-o formă dată. În cazul în care există
un fişier index deschis se actualizează şi acesta. Dacă în
fereastra de editare nu se introduce nimic, înregistrarea nu va
fi adăugată. Clauza BLANK determină adăugarea unei
înregistrări vide (pentru câmpurile de tip caracter se va
completa cu spaţiu, iar pentru câmpurile numerice cu 0). După
adăugarea unei înregistrări, operaţia de adăugare poate
continua într-o nouă fereastră de editare. Comanda APPEND
permite adăugarea de înregistrări într-o singură bază de date.
Dacă dorim să adăugăm date în mai multe fişiere, se poate
crea un fişier format (@…SAY…GET…), fişier format care
conţine câmpurile din mai multe baze de date.

INSERT [BEFORE] [BLANK] - oferă posibilitatea de


a insera o nouă înregistrare într-un fişier bază de date activ.
Inserarea are loc după poziţia curentă a pointer-ului fişierului
deschis. Dacă se foloseşte clauza BEFORE adăugarea de
înregistrări se va face înaintea înregistrării curente. Având în
vedere faptul că inserarea unei înregistrări atrage după sine
rescrierea întregului fişier bază de date, nu este recomandată
folosirea ei pentru fişierele mari.

2.4.2 Ştergerea înregistrărilor

Operaţia de ştergere a înregistrărilor unei baze de date


implică două etape:
- înregistrarea care se doreşte a fi ştearsă este marcată pentru
ştergere cu ajutorul unei comenzi DELETE, fără ca
articolul să fie fizic şters.
Sintaxa comenzii este următoarea:

DELETE [<scope>] [FOR <expresie logica 1>]


[WHILE <expresie logica 2>].

28
Baze de date SGBD FoxPro

Prin clauza <scope> se precizează înregistrările care pot


fi marcate pentru ştergere, clauza putând lua valorile:
ALL – toate articolele
RECORD <expN> - articolul cu numărul <expN> (expN-
un număr)
NEXT<expN> - următoarele <expN> articole începând
din poziţia curentă
REST – toate articolele începând de la articolul curent
Clauza FOR permite marcarea pentru ştergere a
înregistrărilor care îndeplinesc condiţia data de <expresie
logica 1> (deci dacă <expresia logică 1> are valoarea
adevărată), iar clauza WHILE arată că marcarea are loc atâta
timp cât <expresia logică 2> are valoarea adevărată.
- în cazul în care se doreşte o ştergere fizica a înregistrărilor
care au fost marcate cu ajutorul comenzii DELETE, se
foloseşte comanda PACK.
Dacă nu se doreşte o ştergere fizica a înregistrărilor care au
fost marcate pentru ştergere, anularea marcării se face cu
comanda:

RECALL [<scope>] [FOR<expresie_logică 1>]


[WHILE <expresie logică 2>]

Observaţie:
Toate clauzele de tipul <scope>, FOR şi WHILE care
apar în sintaxa oricărei comenzi au aceeaşi semnificaţie ca şi
în cazul comenzii DELETE.

Ştergerea tuturor înregistrărilor dintr-o bază de date


deschisă se poate face utilizând comanda ZAP. După
executarea unei astfel de comenzi (pentru o setare implicită a
FoxPro-ului), SGBD-ul cere o confirmarea suplimentara a
intenţiei de ştergere a întregului conţinut al bazei de date
(lucru care nu se întâmplă la comanda PACK).
Comanda prin care se activează/dezactivează acest
mecanism de siguranţa este SET SAFETY ON/OFF
(implicit este ON).
Dacă comanda SET SAFETY este corespunzător
setată (ON), apare un mesaj care cere confirmarea ştergerii
tuturor înregistrărilor din baza de date.

29
Baze de date SGBD FoxPro

REZUMAT (Paragraf 2.4)

Adăugarea unei înregistrări la sfârşitul unui fişier bază de


date deschisa se face cu comanda: APPEND [BLANK]

Inserarea unei noi înregistrări într-o bază de date activă


(după poziţia curentă a pointer-ului de înregistrare) se face
cu comanda: INSERT [BEFORE] [BLANK]

Operaţia de ştergere a înregistrărilor unei baze de date


implica două etape:
- marcarea înregistrărilor pentru ştergere cu comanda (în
forma cea mai uzuală)
DELETE [<scope>] [FOR <expresie logica 1>]
- ştergere efectiva a înregistrărilor marcate, cu comanda
PACK

Demarcarea unor înregistrari marcate pentru ştergere


se face cu comanda (in forma cea mai uzuală):
RECALL [<scope>] [FOR<expresie_logică 1>]

Ştergerea tuturor înregistrărilor dintr-o bază de date deschisă


se poate face utilizând comanda ZAP.

Comanda prin care se activează/dezactivează mecanismul de


siguranţă la o ştergere a tuturor înregistrărilor este:
SET SAFETY ON/OFF (implicit este ON).

ÎNTREBĂRI

Care sunt etapele si comenzile utilizate pentru ştergerea de


înregistrări dintr-o bază de date?

Care este deosebirea între comenzile PACK si ZAP?

Să se scrie o secvenţă de program care realizează ştergerea


dintr-o baza de date a unor articole selectate după un anumit
criteriu.

Ce valori poate lua clauza <scope> şi ce semnificaţie au


acestea?

30
Baze de date SGBD FoxPro

2.5 Instrucţiuni pentru operaţii de ieşire din baza de date

Comenzi pentru afişarea (neformatată) a înregistrărilor

DISPLAY [<scope>] [[FIELDS] <lista_câmpuri>]


[FOR <expresie_logică 1>]
[WHILE <expresie_logică 2>][OFF]
[TO PRINTER/TO FILE <fişier>]
[ NOCONSOLE] [NOOPTIMIZE]

Clauza FIELDS permite afişarea conţinutului


corespunzător doar pentru anumite câmpuri specificate prin
parametrul <lista_câmpuri>. Mai mult, se poate renunţa
la cuvântul cheie FIELDS, precizându-se doar lista de
câmpuri:
Spre exemplu, comenzile:
DISPLAY FIELDS NUME, PRENUME
DISPLAY NUME, PRENUME
sunt echivalente.
Clauza TO PRINTER sau TO FILE <fisier>
redirecţionează operaţia de ieşire spre o imprimanta sau spre
un fişier text cu numele specificat (simultan cu afişarea şi pe
ecran a informaţiilor). Cele doua opţiuni se exclud reciproc.
Daca nu se mai doreşte şi o ieşire pe ecran a informaţiei se
poate utiliza clauza NOCONSOLE. Opţiunea OFF inhiba
afişarea numărului de ordine fizică pentru înregistrările afişate
(deranjant, spre exemplu, în cazul în care fişierul este şi
indexat).
Comanda DISPLAY (fără nici o altă clauză) afişează
doar înregistrarea curentă. Pentru a afişa toate înregistrările
bazei de date se foloseşte comanda DISPLAY ALL.
Echivalentă cu comanda DISPLAY este comanda
LIST:
LIST [<scope>] [[FIELDS] <lista_câmpuri>]
[FOR <expresie_logică 1>]
[WHILE <expresie_logică 2>][OFF]
[TO PRINTER/TO FILE <fişier>]
[ NOCONSOLE] [NOOPTIMIZE]

Faţă de comanda DISPLAY, comanda LIST prezintă


câteva particularităţi:

31
Baze de date SGBD FoxPro

- DISPLAY ALL afişează toate înregistrările bazei de date


ecran cu ecran, în timp ce LIST realizează o afişare cu
defilare;
- clauza ALL este implicita la LIST.
Celelalte clauze ale comenzii LIST sunt similare cu cele
de la DISPLAY.

REZUMAT (Paragraf 2.5)

Afişarea (neformatată) a înregistrarilor unei baze de date se


poate realiza cu comenzile LIST si DISPLAY.

DISPLAY ALL afişează toate înregistrările bazei de date


ecran cu ecran, în timp ce LIST realizează o afişare cu
defilare.

Cele mai uzuale forme de utilizare a comenzilor LIST si


DISPLAY sunt:
DISPLAY – afişează articolul curent
DISPLAY [<scope>] [[FIELDS] <lista_câmpuri>]
[FOR <expresie_logică 1>] – afişează a selectie de articole,
iar pentru acestea doar informaţia din anumite câmpuri
LIST - afişează toate articolele bazei de date
LIST NOCONSOLE TO PRINTER – afişarea se face doar la
imprimantă

ÎNTREBĂRI

Ce deosebiri există între comenzile LIST şi DISPLAY?

Cum se poate afişa cu LIST doar articolul curent?

Ce clauză se foloseşte pentru direcţionarea informaţiei afişate


spre un fişier? Care comandă – LIST sau DISPLAY- ar fi mai
potrivită?

Care este efectul clauzei NOCONSOLE? Când este utilă o


astfel de clauză?

Ce tip de fişier creează clauza TO FILE?

32
Baze de date SGBD FoxPro

2.6 Actualizarea/modificarea/editarea unui fişier bază de


date. Comenzi pentru calcule

Editarea unui fişier bază de date (operaţie implicând o


actualizare sau modificare a unor articole deja existente într-o
bază de date) se poate face folosind una din comenzile:
1. CHANGE
2. EDIT
3. BROWSE
Toate cele trei comenzi au ca efect principal apariţia
unei ferestre predefinite (figura 4, figura 5) care dă posibilitea
editarii informaţiei din baza de date.
Primele doua comenzi sunt identice, ele fiind diferite de
comanda BROWSE doar prin modul de afişare a câmpurilor
înregistrărilor în fereastra de editare care se deschide în urma
execuţiei comenzii. În cazul primelor două, câmpurile apar
unele sub altele (aranjate pe verticală, vezi figura 4), iar pentru
comanda BROWSE ele sunt înşirate pe orizontală (figura 5).

Figura 5. Fereastra BROWSE

2.6.1. Comanda BROWSE

BROWSE [FIELDS<lista_de_câmpuri>][<scope>]
[FOR<expr_logică1>] [WHILE<expr_logică 2>]
[FREEZE <câmp>] [ KEY <expr_1>, [<expr_2>]] [LAST]
[LEDIT] [REDIT]
[NOAPPEND][NOCLEAR][NODELETE]
[NOEDIT][NOMODIFY]
[PARTITION <expr_num.>][LOCK <expr_num>]

33
Baze de date SGBD FoxPro

[NOLINK] [NOMENU] [NOOPTIMIZE] [NORMAL]


[NOWAIT]
[PREFERENCE <expr._caracter 1>][REST][SAVE]
[TIMEOUT<expr_n1>][TITLE<expr_caracter2>]
[VALID<expr_logica>[:F]<expr_caract_3>
[ERROR<expr_caract.4>]]
[WHEN<expr_logică 3>][WITH<expr_NUM.3>]
[IN [WINDOW]<nume_fereastră/IN SCREEN]
[COLOR SCHEME<expr_N4>/COLOR<expr_c>]

Clauza FIELDS se foloseşte în cazul în care se doreşte


editarea doar a anumitor câmpuri din fişierul bază de date
(câmpurile specificate în lista, în ordinea în care apar în listă).
Această listă conţine o înşiruire de câmpuri ale bazei de date
sau câmpuri calculate. Sintaxa listei de câmpuri este
următoarea:
<câmp I> [:R]
[:V=<expr_1>[:F][:E=<expr_C1>]]
[:P=<expr_C2>]
[:B=<expr_2>,<expr_3>[:F]]
[:H=<expr_C3>]
[:W=expr_L1>]
[,<câmp2>[:R]]…

Clauze:
- clauza :R este folosită atunci când se doreşte doar o citire
(vizualizare) a conţinutului câmpul respectiv (read only)
Exemplu: BROWSE FIELDS nume:R

- clauza :V permite validarea datelor introduse şi modificate


astfel: după modificarea şi ieşirea din editare se evaluează
<expr_1>. În cazul în care <expr_1> este adevărată,
câmpul respectiv este validat. În caz contrar apare un mesaj
de eroare.
- clauza :F determină efectuarea validării, deci efectuarea
calculului <expr_1> doar dacă se trece cu cursorul prin
acel câmp, fără modificarea acestuia.
- clauza :E permite apariţia unui mesaj de eroare dat de
<expr_C1> (expresie caracter) în locul mesajului de eroare
implicit

34
Baze de date SGBD FoxPro

Exemplu:
BROWSE FIELDS virsta:V=virsta>10 :F;
:E=” Virsta prea mica!”

- clauza :P permite specificarea unui şir de caractere de tip


PICTURE
Exemplu: BROWSE FIELDS virsta:P=”99”

- clauza :B permite specificarea unui interval căruia trebuie


să-i aparţină câmpul după editare
Exemplu: BROWSE FIELDS virsta:B=10,100

- clauza :H afişează <expr_C3> în locul numelui câmpului


Exemplu:
BROWSE FIELDS virsta:H=” Virsta;
pacientului”

- clauza :W permite intrarea în editare a câmpului deci


rescrierea lui doar dacă <expresie L1> e adevărată
Exemplu: BROWSE FIELDS virsta:W=virsta>10

În cazul comenzii BROWSE poate apare şi un câmp


calculat având sintaxa <câmp calculat>=<expresie de calcul>.
Clauzele [<scope>],FOR,WHILE specifică
domeniul înregistrărilor care vor fi accesibile
Clauza FREEZE permite editarea doar a câmpului
specificat în această clauză, celelalte câmpuri fiind doar
vizibile şi nu editabile.
Exemplu: BROWSE FREZEE virsta

Clauza [KEY <expr_1>, [<expr_2>]] este


utilizata pentru selectarea înregistrărilor care vor fi afişate în
fereastra de editare, în cazul unei baze de date indexate.
Exemplu:
USE baza
INDEX ON virsta TAG virsta
BROWSE KEY 10,20
** afişează doar articolele cu virsta cuprinsa intre 10…20
BROWSE KEY 10
** afişează doar articolele cu virsta =10
INDEX ON nume TAG nume
BROWSE KEY ‘A’
** afişează doar articolele cu ‘nume’ începând cu ‘A’

35
Baze de date SGBD FoxPro

Clauza [LOCK <expr_num>] stabileşte numărul de


câmpuri care vor fi afişate în partiţia BROWSE din partea
stânga.
Exemplu: BROWSE LOCK 4 REDIT
** afişează 4 câmpuri în partiţia stânga

În mod normal în cazul în care se lucrează cu doua


partiţii, ele sunt legate intre ele (deplasarea cursorului în una
din partiţii implica o deplasare similara şi în cea de a doua).
Clauza NOLINK dezactivează o astfel de legătura (cursoarele
se pot deplasa independent în cele doua partiţii).
Clauza NOAPPEND nu permite adăugarea de înregistrări
pe parcursul executării comenzii.
Clauzele NOEDIT şi NOMODIFY se exclud una pe alta
şi nu permit modificarea înregistrărilor, ci doar vizualizarea
lor (ne influenţând clauza NODELETE).
Clauza NODELETE nu permite ştergerea înregistrărilor
Clauza NOMENU nu permite apariţia opţiunii bara
BROWSE care conţine comenzi specifice ferestrei de editare.
În cazul în care se doreşte salvarea atributelor ferestrei
de editare sub un nume specificat printr-o expresie de tip
caracter se utilizează clauza PREFERENCE
Clauza PARTITION determină împărţirea ferestrei de
editare în două părţi numite partiţii. Fiecare dintre aceasta
poate fi văzute fie în forma CHANGE, fie în BROWSE,
independent una de alta. Expresia numerică care însoţeşte
clauza specifică coloana (numar de caractere) unde se vor
separa cele două partiţii.
Exemplu: BROWSE PARTITION 20 LEDIT

În cazul în care apare clauza LEDIT, partiţia din stânga


este în mod BROWSE, iar în cazul clauzei REDIT partiţia din
dreapta este în mod BROWSE.
Clauza NOWAIT şi TIMEOUT pot fi folosite doar în
cadrul unui program. Clauza TIMEOUT specifică faptul că
fereastra de editare va fi accesibilă pentru introducerea datelor
doar un timp specificat dat de <expr_n1> în secunde.
Clauza NOWAIT permite executarea comenzii BROWSE fără
oprirea afişării pe ecran a ferestrei de editare.
Clauza VALID permite specificarea unei validări a
modificărilor efectuate asupra câmpurilor unei înregistrări.
Exemplu: BROWSE VALID nume=’Ion’

36
Baze de date SGBD FoxPro

(în câmpul nume se poate edita doar Ion)

Clauza WITH este folosită pentru specificarea unei alte


dimensiuni (număr de caractere) pentru afişarea unui câmp
(nu este afectata dimensiunea reala a câmpului din baza de
date, stabilita la crearea bazei de date).
Clauzele NORMAL, WINDOW, IN SCREN se referă la
lucrul cu ferestre.

Observaţie: O fereastră este o porţiune de ecran tratată ca un


element unic, cu anumite caracteristici. Ca şi în cazul unui
meniu (după cum se va vedea într-un alt paragraf) , o fereastra
trebuie iniţial definita (DEFINE WINDOW), pentru a putea fi
vizibila trebuie activata (ACTIVATE WINDOW), spre ea pot fi
apoi direcţionate anumite fluxuri de informaţii (utilizând
clauze de genul IN WINDOW), iar în final poate fi dezactivata
(DEACTIVATE WINDOW) şi ştearsa din memorie (CLEAR
WINDOWS).
Exemplu:
USE baza
** definire fereastra cu coordonatele date şi cu titlul dorit
DEFINE WINDOW fereastra FROM 1,1 TO 20,40;
TITLE "O fereastra"
** activare fereastra
ACTIVATE WINDOW fereastra
** direcţionarea unui flux de informaţie spre fereastra
BROWSE IN WINDOW fereastra
** dezactivare (ştergere de pe ecran)
DEACTIVATE WINDOW fereastra
** ştergere din memorie
CLEAR WINDOWS

Clauza COLOR se referă la culorile fundalului, respectiv


ale textului.
Exemplu: BROWSE COLOR r/g
** afişează cu scris roşu pe fundal verde

Clauza TITLE permite specificarea în locul titlului


implicit (numele bazei de date) al ferestrei de editare a unui
titlu specificat prin şirul de caractere care urmează.
Exemplu: BROWSE TITLE “titlu dorit”

37
Baze de date SGBD FoxPro

O organizare diferită a ferestrei de editare se poate


obţine folosind fie comanda CHANGE, fie comanda EDIT.

2.6.2 Comanda REPLACE

Permite modificarea prin înlocuire a unuia sau mai


multe câmpuri ale unei baze de date. Comanda are inclusiv
proprietatea de a realiza modificarea unui câmp numeric pe
baza unor operaţii de calcul. Sintaxa comenzii este
următoarea:
REPLACE <câmp_1> WITH <expr_1> [ADITIVE]
[<câmp 2> WITH <expr_2> [ADITIVE]…
[<scope>][FOR<expr_L1>]
[WHILE<expr_L2>][NOOPTIMIZE]

Ca urmare a execuţiei comenzii informaţia din


câmpurile specificate (<câmp_1>,<câmp_2>…) este înlocuita
cu valoarea dată de expresiile <expr_1>,<expr_1>... În cazul
în care nu s-a specificat domeniul de lucru cu clauzele
<scope>, FOR sau WHILE, înlocuirea se face pentru articolul
curent
Clauza ADITIVE se aplică numai pentru câmpurile
MEMO, pentru a adaugă informaţia la cea deja existenta în
câmpul MEMO. Dacă nu se foloseşte clauza ADITIVE,
informaţia este suprascrisă.
În cazul în care are loc înlocuirea unui câmp numeric,
iar noua valoare are alte dimensiuni pot să apară transformări
(nedorite) de genul rotunjirilor sau trunchierilor.

Exemple:
** calculează întreg câmpul impozit=salar*0.2
REPLACE ALL impozit WITH salar*0.2
** aceeaşi operaţie, plus înlocuire conţinutului câmpului judeţ
** cu şirul de caractere (textul) Tm pentru un prefix=057
REPLACE ALL impozit WITH salar*0.2,;
judeţ WITH “Tm” FOR prefix=057

2.6.3 Comanda COUNT

Sintaxa:
COUNT [<scope>] [<FOR<expr_logica1>]
[WHILE< expr_logica2>] [TO<variabila>]
[NOOPTIMIZE]
38
Baze de date SGBD FoxPro

Comanda numără înregistrările din domeniul specificat


prin <scope>, ţinând cont de condiţiile impuse de clauzele
FOR şi WHILE (domeniul implicit este ALL), salvând
rezultatul într-o variabila (care va fi creata daca nu exista).
Clauza NOOPTIMIZE inhiba optimizarea Rushmore.

Exemplu:
USE BAZA
COUNT FOR sex=.T. TO nrbăieţi
? ' Numarul de băieţi este:' nrbăieţi
USE

2.6.4 Comanda SUM

Sintaxa:
SUM [<lista_expresii>][<scope>]
[<FOR<expr_logica1>][WHILE< expr_logica2>]
[TO<lista_variabile>/TO ARRAY <masiv>]
[NOOPTIMIZE]

Comanda permite sumarea unor câmpuri numerice ale


bazei de date pentru anumite înregistrări selectate.
Clauza lista_expresii este formata din expresii
care conţin numele câmpurilor numerice, valorile acestor
expresii urmând a fi însumate (pentru toate înregistrările
selectate prin clauzele aferente folosite). Dacă lista lipseşte,
se vor însuma toate câmpurile numerice ale bazei de date.
Rezultatele (sumele) obţinute vor fi depuse fie în
variabile din lista_variabile, fie în elementele tabloului
masiv. Dacă o variabilă nu există sau tabloul nu exista, în
momentul execuţiei comenzii ele sunt create automat.

Exemplu:
** baza de date BANCA.dbf cu câmpurile datorii,
** primiri, sex
USE BANCA
** însumări selective după un câmp
SUM datorii FOR sex=.T. TO dator1
SUM datorii FOR sex=.F. TO dator2
** însumări după o expresie formata din doua câmpuri
SUM primiri-datorii TO plus
** afişare conţinut variabilă
? plus

39
Baze de date SGBD FoxPro

2.6.5 Comanda AVERAGE

Sintaxa:
AVERAGE [<lista_expresii>][<scope>]
[<FOR<expr_logica1>]
[WHILE< expr_logica2>]
[TO<lista_variabile>/
TO ARRAY <masiv>][NOOPTIMIZE]

Comanda AVERAGE este asemănătoare cu SUM, dar ea


calculează media aritmetica a valorilor expresiilor din
<lista_expresii>, pentru înregistrările selectate prin
<scope>, FOR şi WHILE (spre deosebire de SUM care
calculează suma). Semnificaţia clauzelor opţionale şi respectiv
modul de lucru este identic cu cel de la comanda SUM.

2.6.6 Câmpuri MEMO

Încărcarea unor date dintr-un câmp MEMO a unei baze


de date se poate face de către utilizator prin introducerea
caracter cu caracter într-o fereastră de editare, folosind una din
comenzile: CHANGE, EDIT, BROWSE sau APPEND (şi
combinaţia data de tastele Ctrl+PgUp). Există şi o comandă
specială care deschide direct o fereastră de editare pentru
câmpul MEMO specificat. Sintaxa acesteia este:
MODIFY MEMO <nume_câmp >
Comanda de deplasare a prompterului de înregistrare la
un anumit articol este: GO RECORD <număr_articol> (sau
GO <numar_articol>).
O altă posibilitate de încărcare a unui câmp MEMO
(pentru articolul curent) are la bază copierea unui fişier text în
câmpul MEMO, cu ajutorul comenzii:
APPEND MEMO <nume_câmp> FROM <nume_fişier>
[OVERWRITE]

Conţinutul întregului fişier se adaugă sau se scrie peste


(dacă se utilizează clauza OVERWRITE).
Există şi posibilitatea inversă, de a scrie conţinutul unui
câmp MEMO (corespunzător articolului curent) într-un fişier
text (.txt). Comanda are sintaxa:
COPY MEMO <câmp memo> TO <fişier> [ADDITIVE]

40
Baze de date SGBD FoxPro

REZUMAT (Paragraf 2.6)

Editarea unui fişier bază de date (actualizarea sau


modificareaunor articole deja existente într-o bază de date) se
poate face folosind una din comenzile: CHANGE,
EDIT(dispunere pe verticală a câmpurilor), BROWSE
(câmpurile sunt dispuse orizontal).

Cele mai utilizate clauze (cu acţiune globală) ale acestor


comenzi sunt:
[FIELDS<lista_de_câmpuri>][<scope>]
[FOR<expr_logică1>]
[FREEZE<câmp>]
[NOAPPEND][NOCLEAR][NODELETE]
[NOEDIT][NOMODIFY]
[TITLE<expr_caracter2>]
[VALID<expr_logica>[:F]<expr_caract_3>
[ERROR<expr_caract.4>]]

Clauza [FIELDS<lista_de_câmpuri>] se foloseşte în cazul în


care se doreşte editarea doar a anumitor câmpuri din baza de
date, realizând un control la nivel de câmp Sintaxa listei de
câmpuri este următoarea:
<câmp I> [:R]
[:V=<expr_1>[:F][:E=<expr_C1>]]
[:P=<expr_C2>]
[:B=<expr_2>,<expr_3>[:F]]
[:H=<expr_C3>]
[:W=expr_L1>]
[,<câmp2>[:R]]…

O fereastră este o porţiune de ecran tratată ca un element


unic, cu anumite caracteristici.

Comanda REPLACE permite modificarea prin înlocuire a


unuia sau mai multe câmpuri ale unei baze de date. Comanda
are inclusiv proprietatea de a realiza modificarea unui câmp
numeric pe baza unor operaţii de calcul.

Cea mai utilizată formă sintactică a comenzii REPLACE este:


REPLACE <câmp_1> WITH <expr_1> [<scope>]
[FOR<expr_L1>] [ADITIVE]

41
Baze de date SGBD FoxPro

Comanda COUNT numără înregistrările din domeniul


specificat prin <scope>, ţinând cont de condiţiile impuse de
clauzele FOR şi WHILE (domeniul implicit este ALL), salvând
rezultatul într-o variabila (care va fi creata daca nu exista).

Cea mai utilizată formă sintactică a comenzii COUNT este:


COUNT [<scope>] [<FOR<expr_logica>]
[TO<variabila>]

Comanda SUM permite sumarea unor câmpuri numerice ale


bazei de date pentru anumite înregistrări selectate, rezultatele
(sumele) obţinute fiind depuse fie într-o lista de variabile din,
fie în elementele unui tablou.

Sintaxa uzuală a comenzii SUM este:


SUM [<lista_expresii>][<scope>]
[<FOR<expr_logica1>][WHILE< expr_logica2>]
[TO<lista_variabile>/TO ARRAY <masiv>]

Comanda AVERAGE calculeaza media aritmetica a valorilor


unor expresii (în genearal câmpuri numerice ale unei baze de
date), pentru anumite înregistrări selectate, rezultatele
(mediile) obţinute fiind depuse fie într-o listă de variabile din,
fie în elementele unui tablou.

Sintaxa uzuală a comenzii AVERAGE este:


AVERAGE [<lista_expresii>][<scope>]
[<FOR<expr_logica1>] [WHILE< expr_logica2>]
[TO<lista_variabile>/TO ARRAY <masiv>]

Comanda de deplasare a prompterului de înregistrare la un


anumit articol al unei baze de date este:
GO RECORD <număr_articol>
(sau GO <numar_articol>).

Editarea unui câmp de tip MEMO se poate realiza fie


utilizând combinaţia de taste CTRL+PgUp, fie comanda:
MODIFY MEMO <nume_câmp_memo >

Încărcarea unui câmp MEMO dintr-un fişier text se


face cu comanda:

42
Baze de date SGBD FoxPro

APPEND MEMO <nume_câmp> FROM <nume_fişier>


[OVERWRITE]

Operaţia inversă, de copiere a conţinutului unui câmp


MEMO (corespunzător articolului curent) într-un
fişier text este:
COPY MEMO <câmp memo> TO <fişier> [ADDITIVE]

ÎNTREBĂRI

Care este rolul principal al comenzilor BROWSE, EDIT,


CHANGE?

Ce deosebire majoră există între comenzile BROWSE, EDIT,


CHANGE?

Daţi un exemplu de utilizare a comenzii BROWSE cu folosirea


unor clauze restricţionale la nivelul unui câmp.

Care este rolul comenzii REPLACE?

Daţi un exemplu de modificare a valorii unui câmp numeric


pe baza unor calcule, utilizând comanda REPLACE?

Care este deosebirea dintre comenzile SUM şi AVERANGE?

Comentaţi efectul comenziilor următoare:


BROWSE FIELDS spor:V=spor>10 :F;
:E=” Valoare prea mica!”
BROWSE FREZEE virsta

Ce modalităţi de acces la informaţia stocată într-un câmp


MEMO cunoaşteţi?

Cum se poate contoriza numărul de articole dintr-o bază de


date?

Ce clauze trebuie folosite pentru a se afişa o fereastră


BROWSE, fără a se permite modificare sau stergerea
informaţiei din baza de date activă?

Când se foloseşte clauza ADITIVE în comanda REPLACE?

43
Baze de date SGBD FoxPro

2.7 Comenzi de intrare (citire de la tastatură)

2.7.1 Comanda INPUT

Comanda INPUT permite citirea de la tastatura a unei


expresii de orice tip şi memorarea ei într-o variabilă de
memorie. Tipul implicit al expresiei citite este cel numeric.
Sintaxa:

INPUT [prompt_expC] TO var_mem


unde:
[prompt_expC] - este o expresie scrisă sub forma unui
şir de caractere
var_mem - variabila în care se citeşte ceea ce este primit
de la tastatură:
Această variabilă poate să nu fie definită înainte. Dacă
variabila este definita aprioric, prin aceasta instrucţiune i se
poate modifica tipul. Tipul variabilei de memorie este dat
doar de valoarea expresiei citite.

Exemplu:
** Citire tip numeric (tipul implicit pentru INPUT)
INPUT ‘Virsta: ’ TO var1
** de la tastatura de pot introduce numere
** Citire şir de caractere
INPUT ‘Numele: ’ TO var2
** se va forţa introducerea unor caractere prin încadrarea
** între ‘ ‘ ( spre exemplu, se va tasta ‘ION’)
INPUT ‘Data nasterii’ TO var3
** pentru citirea unei date calendaristice,
** informaţia se va încadra intre acolade {}
** spre exemplu: {01/01/99}

2.7.2 Comanda ACCEPT

Comanda ACCEPT permite introducerea unei


constante de tip şir de caractere într-o variabilă (fără a fi
necesară delimitarea şirului de caractere ca şi în cazul
comenzii INPUT):

ACCEPT [prompt] TO var_mem

Comanda poate citi de la tastatura doar date de tip caracter.


44
Baze de date SGBD FoxPro

Exemplu:
** Citire doar şir de caractere
ACCEPT ‘Numele: ’ TO var
** va apare pe ecran textul Numele, şi spre exemplu,
** se va tasta: ION

2.7.3 Comanda WAIT

Comanda WAIT determină trecerea sistemului în stare


de aşteptare până la apăsarea unei taste (sau până la scurgerea
unui interval de timp predefinit). Sintaxa comenzii este:

WAIT [prompt] [TO var_mem]


[TIMEOUT<exprN>]

Comanda prezintă următoarele forme particulare:


WAIT - afişează mesajul "Press any key to continue..."
şi opreşte execuţia
programului până la apăsarea unei taste:
WAIT prompt - afişează expresia de tip caracter
definita prin prompt şi opreşte execuţia programului până la
apăsarea unei taste (exemplu: WAIT “Apasati o tasta
pentru a continua…”);
WAIT ... TO var_mem - atribuie valoarea tastei
apăsate variabilei indicate.
Variabila var_mem va fi de tip caracter, de lungime
unu, iar dacă se răspunde cu un caracter neimprimabil
variabila se iniţializează cu spaţiu.
Clauza [TIMEOUT<exprN>] precizează, în secunde
(<exprN>), timpul cât programul este oprit.

2.7.4 Comenzile @…SAY…GET…READ

Citirea de la tastatura a unor date care vor fi memorate


în variabile (sau chiar direct în câmpurile bazei de date), este
precedată de afişare pe ecran a unor informaţii (texte
explicative) referitoare ce fel de informaţii (date) se aşteptă a
fi tastate, şi deci memorate în variabile. La comenzile anterior
referite (INPUT, ACCEPT, WAIT) textul explicativ era dat
de clauza opţionala prompt.
Comanda care va fi în continuare detaliată (@…SAY
…GET…), prezintă cele mai puternic facilităţi din punct de

45
Baze de date SGBD FoxPro

vedere al unei operaţii de intrare/ieşire în FoxPro. Această


comandă este practic constituită din două comenzi (una pentru
intrare, alta pentru ieşire) care pot opera:
- independent sub forma:
@ …SAY… - ca şi comanda de ieşire, deci pentru
afişarea pe ecran a unor date la coordonate specificate;
@ …GET… - ca şi comanda de intrare, deci pentru
citirea de la tastatura a unor date, introducerea lor realizându-
se în casete cu coordonate bine precizate pe ecran ;
- concatenat (simultan intrare şi ieşire), sub forma
@ … SAY…GET…

Observaţie: Pentru citirea efectivă a unor date, activarea


operaţiei de intrare impune de asemenea şi folosirea comenzii
READ (după una sau mai multe comenzi @ … SAY…GET…),
abia în acest moment prompt-ul de scriere de la tastatura
devenind activ.

Sintaxa completa a comenzii @ … SAY…GET… este


următoarea:
@ <linie,coloana>
[SAY <expresie>
[PICTURE <clauza>] [FUNCTION <lista_functii>]]
[GET <variabila>
[DEFAULT<expresie>]
[[OPEN] WINDOW <nume_fereastra>]
[PICTURE <clauza>]
[FUNCTION <lista_functii>]
[RANGE <[min][,max]>]
[VALID <expr_logica>
[ERROR<expr_caracter>]]
[WHEN <condiţie>]
[MESSAGE <expr_caracter>]]
[COLOR SCHEME <expr_numerica1>/COLOR
<lista perechi culori>]

Pentru o prima exemplificare a modului de folosire a


tripletului de comenzi SAY, GET, READ, se considera un
exemplu simplu, şi anume un program care solicita
operatorului introducerea unui nume de persoana de la
tastatura, acesta fiind memorat într-o variabilă având
denumirea nume:

46
Baze de date SGBD FoxPro

** ştergere ecran
CLEAR
** declararea unei valori iniţiale implicite pentru
** variabila nume de tip şir de caractere
nume=' '
** afişare mesaj şi caseta pentru scriere, începând cu
** linia 10 şi coloana 10
@10, 10 SAY 'Introduceti numele ;
persoanei'GET nume
** activare prompter de scriere de la tastatura
READ

O rescriere a aceluiaşi program într-o forma echivalenta


este următoarea:
CLEAR
** afişare mesaj ' Introduceti….' începând cu linia
** 10 şi coloana 10
@10, 10 SAY 'Introduceti numele persoanei'
** afişarea unei casete având lăţimea de 15 caractere vide
** (spaţii), pe aceeaşi linie, începând de la coloana 20
** (utilizând clauza DEFAULT nu mai este
** necesara o iniţializare prealabila a variabilei nume
@10,20 GET nume DEFAULT SPACE(15)
READ

Comanda @ … SAY … este folosita pentru operaţii de


ieşire (afişare pe ecran sau la un alt periferic), iar privita ca de
sine stătătoare are sintaxa:

@ <linie,coloana> SAY <expresie>


[PICTURE <clauza>] [FUNCTION <lista_functii>]
[COLOR SCHEME <expr_numerica1>/COLOR
<lista perchi culori>]

Comanda @ …GET…, folosită pentru operaţii de intrare,


are (ca entitate individuala) următoarea sintaxă:

@ <linie,coloana> GET <variabila>


[DEFAULT<expresie>]
[[OPEN] WINDOW <nume_fereastra>]
[PICTURE <clauza>]
[FUNCTION <lista_functii>]
[RANGE <[min][,max]>]

47
Baze de date SGBD FoxPro

[VALID expr_logica>
[ERROR<expr_caracter>]]
[WHEN <conditie>]
[MESSAGE <expr_caracter>]
[COLOR SCHEME <expr_numerica1>/COLOR <lista
perechi culori>]

După cum s-a putut observa şi din exemplul program


anterior, cuplul de parametrii <linie, coloana> precizează linia
respectiv coloana, raportate la coltul din stânga sus al
ecranului, începând de la care se face afişarea pe ecran.
Observaţie: Fluxul de date poate fi direcţionat spre ecran
(implicit), spre o imprimanta sau spre un fişier, folosind
comanda :

SET DEVICE TO SCREEN / TO PRINTER /


TO FILE <nume_fisier>

Opţiunile PICTURE <clauza> şi FUNCTION


<lista_functii> stabilesc formatul de afişare şi citire. Formatul
de afişare sau de citire reprezintă o descriere simbolica a
modului în care o dată (numerică, şir de caractere etc.) este
afişată pe ecran (imprimantă sau la alte dispozitive periferice
de ieşire) sau citită de la tastatură (sau de la alte dispozitive de
intrare).
Lista codurilor PICTURE şi a codurilor FUNCTION
este dată în Tabelul 1, respectiv în Tabelul 2.
La afişarea valorii unei expresii (folosind comanda
SAY) sau la citire (folosind GET), formatul poate fi specificat
folosind clauzele PICTURE şi/sau FUNCTION. Fiecare dintre
cele doua clauze este urmata de un şir de caractere care conţin
codurile corespunzătoare modului de afişare:
- codurile PICTURE - acţionează doar asupra unui anumit
caracter din formatul de afişare/citire, şi anume asupra
acelui având aceeaşi poziţie cu cea a codului (in şirul de
caractere al clauzei);
- codurile FUNCTION - acţionează asupra tuturor
caracterelor din formatul de afişare/citire.

Exemplu:
** afişare pe patru caractere: pentru primul caracter se
** permite orice caracter alfabetic (codul A, Tabelul 2), iar
** pentru următoarele trei sunt permise sunt permise
48
Baze de date SGBD FoxPro

** doar cifre
PICTURE 'A999'
** şirul format din cele 4 caractere este centrat, şi toate
** caracterele sunt convertite în majuscule
FUNCTION 'i!'

Tabel 1
Cod SEMNIFICAŢIE
FUNCTION
A Permite numai caractere alfabetice
Aliniază la stânga datele numerice în interiorul
B
câmpului de ieşire
După un număr pozitiv se afişează CR. Se
C foloseşte doar pentru SAY şi pentru date
numerice
Foloseşte formatul de dată calendaristică curent,
D
stabilit prin comanda SET DATE
Editează date calendaristice cu formatul
E
European
I Centrează textul în interiorul câmpului
J Aliniază la dreapta textul de ieşire din câmp
Selectează întregul câmp pentru editare când se
K
mută cursorul în acest câmp
Afişează zerouri în faţa punctului zecimal (în
L locul spaţiilor)în ieşirile numerice. Se foloseşte
doar pentru date numerice.
Permite selectarea unui element al listei ca
valoare pentru variabila citită cu comanda GET.
Elementele listei sunt separate prin virgulă şi
pot fi parcurse (în timpul citirii câmpului
respectiv) folosind tasta SPACE sau tastând
M<lista>
prima literă a elementului de selectat.
Terminarea editării câmpului este semnalată
prin apăsarea tastei Enter. Se foloseşte doar
pentru comanda GET, la citirea şirurilor de
caractere.
La utilizarea unui şir de caractere conţinând şi
alte caractere decât coduri PICTURE, acestea
R vor fi afişate pe ecran, dar nu vor fi depozitate
în variabila de citit. Se folosesc doar pentru date
de tip şir de caractere.
S<n> Limitează lăţimea de afişare la <n> caractere,

49
Baze de date SGBD FoxPro

chiar dacă lăţimea câmpului de editat este mai


mare. În acest caz prin deplasarea cursorului în
interiorul câmpului de editat se pot vedea şi
porţiuni ascunse ale acestuia.
T Elimină blancurile de început şi de sfârşit
Se afişează DB după numerele negative. Se
X
foloseşte cu SAY, pentru câmpuri numerice
Dacă valoarea câmpului este 0, se vor afişa
Z numai blancuri. Se foloseşte doar pentru date
numerice.
Numerele negative sunt incluse între paranteze.
(
Se foloseşte doar cu SAY, pentru date numerice
Toate caracterele alfabetice sunt trecute la
! majuscule. Se foloseşte doar pentru şiruri de
caractere.

Tabel 2
Cod (clauza)
SEMNIFICAŢIE
PICTURE
Permite introducerea doar a caracterelor
A
alfabetice
W Permite doar date de tip logic
N Permite doar litere şi cifre
X Permite orice caractere
Permite doar caracterele Y, y, N, n (de la “Yes”
Y
şi “No”) trecându-le la majuscule
Cu date de tip şir de caractere permite doar cifre
9
iar cu date numerice permite cifre şi semne.
# Permite cifre, blancuri şi semne
Afişează simbolul monetar curent definit cu
$ comanda SET CURRENCY. La fel ca la codul
FUNCTION corespunzător.
* Se afişează asteriscuri în faţa valorilor numerice
Converteşte literele în majuscule, neafectând
!
alte caractere
. Specifică poziţia punctului zecimal

Lăţimea câmpului de afişare/citire este data de lungimea


şirului de caractere din clauza PICTURE. Codurile
FUNCTION pot fi incluse în şirul de caractere al clauzei
PICTURE dacă: - sunt precedate de @ ;

50
Baze de date SGBD FoxPro

- se afla la începutul şirului;


- sunt separate printr-un blanc de
codurile PICTURE.
Exemplu:
** comenzi echivalente (permiţând scrierea/citirea a 5
** caractere alfabetice, toate fiind convertite automat în
** majuscule)
PICTURE 'aaaaa' FUNCTION '!'
PICTURE '@! aaaaa'
PICTURE '@a !!!!!'

Revenind la celelalte clauze opţionale utilizate,


semnificaţia lor este următoarea:
[OPEN] WINDOW <nume_fereastra> - deschide
o fereastra anterior definita pentru editarea unui câmp memo.
Daca se include şi clauza OPEN, fereastra de editare a
câmpului memo va fi deschisa implicit.
RANGE <[min][,max]> - defineşte valoarea
minima şi maxima pentru o data introdusa, de tip numeric sau
data calendaristica. Dacă una dintre limite nu este precizată,
valoarea câmpului GET nu mai este limitata în direcţia
respectiva (inferior sau superior). Cele doua limite nu pot fi
omise simultan.
În cazul în care valoarea introdusă nu se găseşte în
domeniul specificat, apare un mesaj de eroare, iar cursorul
rămâne în acel câmp GET până la introducere unei valori
corecte.

Exemplu:
@ 1,1 SAY 'Virsta persoanei: ' GET virsta;
DEFAULT 0 PICTURE '999' RANGE 0,100
READ

VALID <expr_logica> - defineşte o condiţie care


trebuie satisfăcuta înainte ca data (informaţia) sa fie acceptata
în câmpul GET. Spre deosebire de clauza RANGE, care
testează doar intervalul în care trebuie sa se afle valoare
introdusa (numai daca câmpul respectiv a fost modificat),
clauza VALID realizează la ieşirea din câmpul GET o testare a
condiţiei impuse, indiferent daca acesta a fost sau nu
modificat.
Observaţie: Setul de comenzi GET, READ permite
citirea de la tastatura a unor date (informaţii) fie în variabile

51
Baze de date SGBD FoxPro

de memorie (caz în care acestea trebuie fie iniţializate anterior


printr-o declaraţie variabila=expresie, fie folosind
clauza DEFAULT), fie direct în câmpurile unei baze de date.
În acest ultim caz, numele variabilei este acelaşi cu al
câmpului bazei de date, iar informaţia va fi plasata în acel
câmp, la poziţia curenta a indicatorului de înregistrare. Cu alte
cuvinte, în aceasta situaţie, câmpul GET este sinonim cu
câmpul bazei de date. Folosirea clauzei VALID în acest caz,
permite o verificare a informaţiei existente deja într-un câmp
al bazei de date.
ERROR <expr_caracter> - stabileşte ce mesaj de
tip caracter se va afişa, în cazul în care prin introducerea unei
date nu este respectată clauza VALID.

Exemplu:
** câmpul GET virsta este un câmp al bazei de date active
@ 1,1 SAY 'Virsta persoanei: ' GET virsta;
DEFAULT 0 PICTURE '999' VALID virsta>0;
ERROR ' Virsta NEGATIVA!'
READ

WHEN <conditie> - dacă condiţia este îndeplinită -


cursorul se muta în câmpul GET, iar dacă condiţia este falsă -
nu se face editarea datei.

Exemplu:
var1=0
@ 1,1 SAY 'introduce-ti datele: '
@ 2,1 GET var1 PICTURE '999'
** citirea şi memorare în var2 se face doar daca valoarea
** citita şi memorat în var1 este diferita de zero
@ 3,1 GET var2 DEFAULT 0 PICTURE '999';
WHEN var1<>0
** un singur READ pentru ambele SAY (citire multipla)
READ

MESSAGE <expr_caracter> - afişează expresia


caracter în linia de mesaje (linia 24).
După cum se poate observa şi din ultimul exemplu, nu
este necesara câte o comanda de citire READ pentru fiecare
SAY. Un singur READ va activa toate comenzile SAY de citire,
neactivate până în acel moment.

52
Baze de date SGBD FoxPro

Exemplul următor prezintă o modalitate de adăugare a


unor date noi într-o bază de date, cu realizarea unor verificări
prealabile asupra corectitudinii acestora (operaţie care nu se
poate efectua cu un simplu APPEND):

Exemplu:
** fie baza de date BAZA cu câmpurile NUME, VIRSTA,
** DATA (calendaristica)
USE BAZA
** adăugare articol vid şi mutare pointer înregistrare pe
** acest ultim articol
APPEND BLANK
** citirea unui nume de max. 10 caractere majuscule
@1,1 SAY 'Introdu numele' GET NUME;
PICTURE '!!!!!!!!!!'
** citire virsta valida
@2,1 SAY 'Introdu virsta' GET VIRSTA;
PICTURE '99' VALID VIRSTA>0;
ERROR 'Virsta negativa! '
** citire data naşterii valida (funcţia DATE() returnează
** data curentă)
@3,1 SAY 'Introdu data nasterii' GET DATA;
VALID data<DATE()ERROR 'Data din viitor! '
** activare citire multipla pe toate cele trei SAY
READ

Dacă datele respective erau introduse nu direct în


câmpurile unei baze de date, ci în nişte variabile de memorie
(nume, virsta, data), secvenţa de program trebuia rescrisă
astfel:
** Şterge ecran
CLEAR
** citire nume (funcţia SPACE(10) generează o valoare
** de tip şir de caractere (10 caractere)
@1,1 SAY 'Introdu numele' GET NUME;
DEFAULT SPACE(10)PICTURE '!!!!!!!!!!'
** citire virsta valida (cu valoare iniţiala zero)
@2,1 SAY 'Introdu virsta' GET VIRSTA;
DEFAULT 0 ;
PICTURE '99' VALID VIRSTA>0;
ERROR 'Virsta negativa! '
** citire data naşterii valida (funcţia DATE() returnează
** data curentă), cu iniţializare pe dată vidă
@3,1 SAY 'Introdu data nasterii' GET DATA;

53
Baze de date SGBD FoxPro

DEFAULT {//} VALID data<DATE();


ERROR 'Data din viitor! '
** activare citire multipla pe toate cele trei SAY
READ

Observaţie: Tipologia (formatul) unei variabile de tip


dată_calendaristică se stabileşte cu ajutorul comenzii:
SET DATE [TO] AMERICAN / ANSI / BRITISH
/ FRENCH /GERMAN / ITALIAN / JAPAN / USA /
MDY / DMY / YDM
Spre exemplu: AMERICAN - ll/zz/aa
BRITSH - zz/ll/aa
GERMAN - zz.ll.aa (folosit şi
în România)
DMY - zz/ll/aa etc.
unde zz- ziua, ll- luna, aa - an.
Pentru afişarea sau inhibarea afişării secolului, se va
folosi comanda de setare: SET CENTURY ON/OFF
Exemplu:
** afişarea datei curente în format german (şi cu afişarea
** secolului)
SET DATE TO GERMAN
SET CENTURY ON
? DATE()

Clauzele COLOR SCHEME <expr_numerica1> sau


COLOR <lista perechi culori>
determină culorile folosite pentru afişarea câmpului GET sau
SAY pe ecranul monitorului.
Clauza COLOR SCHEME <expr_numerica1>
permite setarea unei scheme de culori predefinite dintr-un set
de 10 (expr_numerica1 putând lua valori de la 1…10, implicit
fiind 1). Clauza COLOR <lista perechi culori>
permite specificarea culorii pentru caracterul propriu-zis
(culoarea cernelii) şi respectiv pentru fondul pe care se
afişează caracterul (culoarea hârtiei sau culoarea de fondsau
fundal). Cele doua culori se grupează într-o "pereche de
culori", formatul lor de scriere fiind:
<culoare cerneala / culoare fond>
Exemple:
** afisare text Nume cu verde (Green) pe fundal alb (White)
** citire de la tastatura cu coloare roşie (Red) pe fond
** albastru (Bleu)

54
Baze de date SGBD FoxPro

var=' '
@ 1,1 SAY ‘Nume’GET var COLOR g/w, R/B
READ
** sau folosind comanda SET COLOR TO
** citire de la tastatura cu coloare alba (White) pe fond Negru
SET COLOR TO g/w,W/N
@ 1,2 GET var
READ
** citire 'parola' (scriere cu aceeaşi culoare ca a fundalului
** (roşu), deci caracterele introduse de la tastatura nu vor fi
** vizibile)
@ 5,2 SAY 'Parola: ' GET parola;
DEFAULT SPACE(20) COLOR G/W,R/R
READ

2.7.5 Comenzile ? /??

O comandă des folosita pentru o simpla afişare a unor


informaţii pe ecran este comanda ?/??. Spre deosebire de
comanda SAY care afişa date la coordonate specificate
explicit, noua comanda calculează poziţia de afişare în funcţie
de poziţia curentă a cursorului. Sintaxa acestei comenzi este:

?/?? [<expresie_1>] [PICTURE <expr_caracter_1>]


[FUNCTION <lista_functii>]
[AT <expr_numerica>]
[,<expresie_2>…]

Clauzele acestei comenzi au următoarele semnificaţii:


? <expresie_1> - se executa salt la linia următoare
înaintea afişării, afişându-se expresie_1 (un şir de caractere)
sau conţinutul expresie_1 (daca aceasta este numele unei
variabile)
?? <expresie_1> - afişarea (cu aceleaşi specificaţii ca
înainte) se face începând de la poziţia curentă a cursorului sau
a imprimantei.
? fără argumente - afişează o linie goală
Clauza AT<expr_numerica> indică prin
<expr_numerica> coloana unde va fi afişată data
respectivă (folosită în special la afişarea tabelelor pentru
alinierea strictă a coloanelor).

55
Baze de date SGBD FoxPro

Exemple:
** salt la linia următoare şi afişarea unui mesaj
? 'mesaj de test'
** afişare începând din poziţia curentă a rezultatului evaluării
** expresiei (9)
?? 3+6
** afişarea conţinutului unei variabile var (Ion)
var='Ion'
? var
** afişarea datei curente
? DATE()

Observaţie: Dacă informaţia se doreşte a fi redirectată de la


ecran şi/sau spre o imprimanta (valabil la orice comandă de
ieşire) se pot folosi comenzile de setare:
SET PRINTER ON/OFF
** afişare la imprimanta (implicit OFF)
SET CONSOLE ON/OFF
** afişare pe ecran (implicit -ON)

2.7.6 Comenzile pentru salvarea, restaurarea şi ştergerea


variabilelor de memorie

- Comanda SAVE TO salvează într-un fişier toate


variabilele de memorie şi elementele de tablou active, sau
parte dintre acestea, selectate printr-o mască. Masca este o
combinaţie de caractere în care intra şi codurile: * - orice
combinaţie de caractere (folosit pentru substituţia unui şir de
caractere), ? - orice caracter (folosit pentru substituţia unui
caracter). Sintaxa:

SAVE TO <fisier> [ALL LIKE /


EXCEPT <masca>]

- Comanda RESTORE recheamă variabilele de memorie


şi elementele de tablou dintr-un fişier de memorie şi le
activează:
RESTORE FROM <fisier> [ADDITIVE]

Folosită fără opţiunea ADDITIVE, această comandă


şterge toate variabilele de memorie active înainte de
restaurare, încărcând în memorie variabilele salvate în fişier.
Pentru a păstra variabilele de memorie deja active se foloseşte

56
Baze de date SGBD FoxPro

opţiunea ADDITIVE. Toate variabilele de memorie care au


acelaşi nume cu variabilele restaurate sunt distruse.

- Ştergerea tuturor variabilelor de memorie sau doar a


unora dintre ele în timpul execuţiei programului, în vederea
eliberării spaţiului de memorie ocupat de acestea, se face cu
comanda RELEASE:
RELEASE ALL [LIKE/EXCEPT <masca>]
sau
RELEASE lista_variabile_memorie

Variabilele declarate publice nu sunt şterse automat


decât la terminarea sesiunii de lucru. Dacă se doreşte şi
ştergerea acestora, se foloseşte una din comenzile:
CLEAR MEMORY
CLEAR ALL
RELEASE lista_var_publice

REZUMAT (Paragraf 2.7)

Comanda INPUT [prompt_expC] TO var_mem permite


citirea de la tastatura a unei expresii de orice tip şi
memorarea ei într-o variabila de memorie. Tipul implicit al
expresiei citite este cel numeric.

Comanda ACCEPT [prompt] TO var_mem permite


introducerea unei constante de tip şir de caractere într-o
variabilă (fără a fi necesară delimitarea şirului de caractere
ca şi în cazul comenzii INPUT).

Comanda WAIT [prompt] [TO var_mem]


[TIMEOUT<exprN>] determina trecerea sistemului în stare
de aşteptare până la apăsarea unei taste (sau până la
scurgerea unui interval de timp predefinit). Caracterul tastat
poate fi eventual memorat într-o variabilă.

Comanda (într-o sintaxă restrânsă)


@ <linie,coloana> SAY <expresie>
este o comandă de ieşire, permiţând afişarea pe ecran a unor
date la coordonate specificate;

57
Baze de date SGBD FoxPro

Setul de comenzi (într-o sintaxă restrânsă)


@ <linie,coloana> GET <variabila> [DEFAULT<expresie>]
READ
acţionează ca şi o comandă unitară pentru o operaţie de
intrare, deci pentru citirea de la tastatură a unor date,
introducerea lor realizându-se într-o casetă cu coordonate
bine precizate pe ecran .
De regulă, comenzile SAY, GET, READ conlucrează într-o
configuraţie unitară (minimă, putând avea şi alte clauze) de
forma:
@ <linie,coloana> SAY <expresie> GET <variabila> ;
[DEFAULT<expresie>] [PICTURE <clauza>]..
READ

Opţiunile PICTURE <clauza> şi FUNCTION <lista_functii>


stabilesc formatul de afişare şi citire.

Codurile PICTURE - acţionează doar asupra unui anumit


caracter din formatul de afişare/citire, şi anume asupra acelui
având aceeaşi poziţie cu cea a codului (in şirul de caractere
al clauzei), iar codurile FUNCTION - acţionează asupra
tuturor caracterelor din formatul de afişare/citire.

Comenzile ? [<expresie>] şi ?? [<expresie>] afisează


<expresie> pe ecran, calculând poziţia de afişare în funcţie
de poziţia curentă a cursorului.

Comanda SAVE TO <fisier> [ALL LIKE / EXCEPT


<masca>] salvează într-un fişier toate variabilele de
memorie şi elementele de tablou active, sau parte dintre
acestea, selectate printr-o mască.

Comanda RESTORE FROM <fisier> [ADDITIVE]


restaurează variabilele de memorie şi elementele de tablou
dintr-un fişier de memorie şi le activează în memorie.

Ştergerea tuturor variabilelor de memorie sau doar a unora


dintre ele se poate face cu una din comenzile:
CLEAR MEMORY
CLEAR ALL
RELEASE lista_var_publice

58
Baze de date SGBD FoxPro

Setarea corespunzătoare a modului de afişare a datei


calendaristice în sistemul românesc se face cu comanda:
SET DATE TO GERMAN

ÎNTREBĂRI

Ce comenzi pentru intrare (citire de la tastatură) cunoaşteţi?

Care este deosebirea între comenzile INPUT şi ACCEPT?

Care este rolul unui set de comenzi @…SAY…GET, READ?

Comentaţi setul următor de comenzi:


@1,1 SAY 'Introdu numele' GET NUME;
DEFAULT SPACE(10) PICTURE '!!!!!!!!!!'
@ 3,1 GET var1 DEFAULT 0 PICTURE '999'
READ

Ce comandă se utlizează pentru salvarea variabilelor de


memorie într-un fişier? Dar pentru restaurarea lor dintr-un
fişier?

Ce comandă a-ţi folosi pentru stergerea tuturor variabilelor


din memorie?

Explicaţi diferenţa dintre codurile PICTURE respectiv


FUNCTION folosite în cadrul unei comenzi GET.

Care este efectul clauzei COLOR într-o comandă


@ ..SAY…GET? Exemplificaţi.

Comentaţi secvenţa următoare, analizând cazul în care Nume


şi Virsta sunt variabile sau câmpuri ale unei baze de date
active:
@ 1,1 SAY ‘Nume’GET var COLOR w/g, b/n
@2,1 SAY 'Introdu virsta' GET VIRSTA;
PICTURE '99' VALID VIRSTA>0
READ

Ce efect are comanda SET CENTURY ON?

59
Baze de date SGBD FoxPro

2.8 Instrucţiuni repetitive şi condiţionale specifice


programării structurate

Rezolvarea problemelor de complexitate mai mare nu se


poate face întotdeauna prin executarea secvenţială a
instrucţiunilor. Apare necesitatea unor comenzi şi funcţii care
să schimbe această ordine de executare. Acest gen de comenzi
şi funcţii, implementând operaţii specifice programării
structurate, realizează acţiuni de ciclare (executarea unui grup
de instrucţiuni de mai multe ori), precum şi de executare
condiţionată a unor instrucţiuni, în funcţie de rezultatul
evaluării unei expresii logice
Primul tip de comenzi, care determină executarea
repetată a uneia sau mai multor instrucţiuni, alcătuiesc aşa
numitele “bucle” şi este reprezentat de comenzile:
FOR…ENDFOR, DO WHILE… ENDDO şi SCAN…
ENDSCAN.
Al doilea tip, condiţionând executarea unor instrucţiuni
de rezultatele evaluării unor expresii logice, este reprezentat
de instrucţiunile condiţionale, de decizie, având componenţa:
IF…ENDIF,IIF(),DO CASE…ENDCASE.

2.8.1 Comanda IF…ENDIF

Această comandă are două forme, care vor permite:


- executarea unor instrucţiuni numai dacă este respectată o
condiţie dată (ramura IF-ENDIF).
- executarea fie a unui grup de instrucţiuni, fie a unui alt
grup de instrucţiuni, în funcţie de rezultatul evaluării unei
expresii logice (ramurile IF-ELSE-ENDIF).
Comanda are următoarea sintaxă:

IF<expL>
<instrucţiuni1>
[ELSE]
<instrucţiuni2>
ENDIF

La începutul execuţiei comenzii se va evalua expresia


logică <expL> şi, în funcţie de rezultatul evaluării, apar
următoarele posibilităţi:

60
Baze de date SGBD FoxPro

- dacă <expL> este .T. se va executa grupul de instrucţiuni


<instrucţiuni1>, după care execuţia comenzii se va
termina;
- în cazul valorii .F. a expresiei logice apar două cazuri:
- dacă există clauza ELSE în comandă, se vor executa
instrucţiunile din grupul <instrucţiuni2>, după care
execuţia se termină;
- în absenţa clauzei ELSE nu se execută nici o
instrucţiune, comanda terminându-se imediat.

Exemplu:
SET TALK OFF
CLEAR
a=0
b=0
@4,10 SAY `Primul număr` GET a;
PICTURE `9999`
@5,10 SAY `Al doilea număr` GET b;
PICTURE `9999`
READ
IF a> b
? `Primul număr este mai mare '
** se execută când a>b
ELSE
? `Al doilea număr este mai mare sau numerele sunt egale`
** a<b
ENDIF
?
IF b<> 0
** se execută doar daca b este diferit de 0
?a,':',b,'=',a/b
ENDIF

2.8.2 Funcţia IIF(…)

Un efect asemănător, de selecţie dintre două variante, se


obţine prin funcţia IIF(), având sintaxa:

IIF(<expL>, <expr1>, <expr2>)

Această funcţie evaluează expresia logică <expL>, şi, în


funcţie de rezultatul obţinut, returnează valoarea uneia din
expresiile <expr1> şi <expr2> astfel:

61
Baze de date SGBD FoxPro

- returnează valoarea obţinută prin evaluarea expresiei


<expr1> dacă <expL> este evaluată la .T. (adevărat)
- returnează rezultatul evaluării expresiei <expr2> daca
<expL> este evaluată la .F. (fals)
Cele două expresii, <expr1> şi <expr2> nu trebuie neapărat
să aibă acelaşi tip ( putând fi de tip şir de caractere, dată
calendaristică, logic sau numeric).

Exemplu:
SET TALK OFF
CLEAR
a=0
b=0
@1,10 SAY `Primul număr:` GET a;
PICTURE `9999`
@2,10 SAY `Al doilea număr:` GET b;
PICTURE `9999`
READ
şir1=`Primul număr este mai mare`
şir2=`Al doilea număr este mai mare sau;
numerele sunt egale`
? IIF (a>b, şir1, şir2)

Mai multe comenzi IF … ENDIF pot fi imbricate,


incluse una în alta, obţinându-se condiţionarea unui grup de
instrucţiuni prin mai multe expresii logice, sau obţinându-se
selecţii diverse între mai multe grupuri de instrucţiuni.

Exemplu:
SET TALK OFF
CLEAR
a=0
b=0
@1,10 SAY `Primul număr:` GET a;
PICTURE `9999`
@2,10 SAY `Al doilea număr:` GET b;
PICTURE `9999`
READ
şir1=`Primul număr este mai mare`
şir2=`Al doilea număr este mai mare `
şir3=`Numerele sunt egale `
IF a>b
? şir1 ** a> b
ELSE
IF a<b

62
Baze de date SGBD FoxPro

? şir2 ** a <b
ELSE
? şir3 ** a = b
ENDIF
ENDIF

În acest exemplu structura de comenzi IF…ENDIF


poate fi înlocuită cu:
? IIF (a>b, şir1,IIF( a<b, şir2, şir3)).
Se pot observa două apeluri imbricate (incluse unul în altul)
ale funcţiei IIF().

2.8.3 Comanda DO CASE… ENDCASE

Un tip de selecţie între mai multe grupuri de instrucţiuni


este dat de comanda DO CASE … ENDCASE, având
următoarea sintaxă:

DO CASE
CASE <expL1>
<instrucţiuni1>
[CASE <expL2>
<instrucţiuni2>

CASE <expLn>
<instrucţiuniN>]
[OTHERWISE
<instrucţiuni>]
ENDCASE

Comanda determina execuţia grupului de instrucţiuni


pentru care expresia logică corespunzătoare are valoarea .T..
Execuţia comenzii va decurge în modul următor: se evaluează
prima expresie logică <expL1> iar dacă valoarea obţinută este
.T. se execută grupul de instrucţiuni <instrucţiuni1>. Dacă
expresia logică <expL1> are valoarea .F. se trece la evaluarea
următoarei expresii logice.
După găsirea primei expresii logice cu valoarea .T. şi
executarea grupului de instrucţiuni corespunzător, execuţia
comenzii se încheie, programul continuând cu prima comandă
de după ENDCASE.
Dacă nici una dintre expresiile <expL1>, <expL2>…
<expLn>, nu are valoarea .T., pot apare două cazuri:
63
Baze de date SGBD FoxPro

- când nu există clauza OTHERWISE, execuţia comenzii se


încheie;
- în prezenţa clauzei OTHERWISE, se va executa grupul de
instrucţiuni <instrucţiuni>, după care se trece la prima
comandă de după ENDCASE.
Numai unul dintre grupurile de instrucţiuni
<instrucţiuni1>, …<instrucţiuni N> şi <instrucţiuni> va fi
executat şi anume acela pentru care expresia logică este .T..

Exemplu:
SET TALK OFF
CLEAR
** declarare şir cu 4 elemente
DIMENSION a[4]
a[1] = `Primăvară`
a[2] = `Vară`
a[3] = `Toamnă`
a[4] = `Iarnă`
@ 1,1 SAY 'Anotimp' GET Anotimp;
DEFAULT SPACE(15)
READ
? 'anotimpul '+Anotimp+' conţine lunile: '
DO CASE
CASE anotimp == `Primăvară`
??`Martie, Aprilie, Mai`
CASE anotimp == `Vară`
??`Iunie, Iulie, August`
CASE anotimp == `Toamnă`
??`Septembrie,Octombrie,Noiembrie`
OTHERWISE
??`Decembrie,Ianuarie, Februarie`
ENDCASE

Executarea repetată a unui grup de instrucţiuni


reprezintă unul dintre principalele avantaje ale elaborării de
programe, fără de care multe dintre programe nu ar putea fi
elaborate, sau dezvoltarea lor ar fi foarte greu de realizat.
Comenzile FoxPro care realizează “buclele din teoria
programării structurate sunt FOR … ENDFOR, DO WHILE
… ENDDO şi SCAN … ENDSCAN, acestea împărţindu-se,
la rândul lor în două grupe:
- comenzi pentru bucle cu un număr dat de paşi, în care un
grup de instrucţiuni se execută de un număr dat de ori:
FOR, SCAN

64
Baze de date SGBD FoxPro

- comenzi folosite pentru bucle cu un număr nedefinit de


paşi, în care numărul de executări a grupului de instrucţiuni
este variabil, fiind dependent de o condiţie asociată
comenzii: DO WHILE.

2.8.4 Comanda FOR … ENDFOR

Sintaxa:
FOR <var> = <exp N1> TO <expN2> [STEP <expN3>]
<instrucţiuni>
[EXIT]
[LOOP]
ENDFOR │ NEXT

determină executarea repetată a grupului de instrucţiuni


<instrucţiuni>, contorizarea acestor paşi fiind făcută printr-o
variabilă <var>.
Valoarea iniţială a variabilei contor va fi dată de
evaluarea expresiei <expN1>. După fiecare execuţie a
grupului de instrucţiuni <instrucţiuni> variabila va fi
incrementată sau decrementată, cu o valoare constantă, dată de
evaluarea expresiei <expN3>, dacă este prezentă clauza
STEP, sau 1 când STEP lipseşte (absenţa clauzei STEP este
echivalentă cu construcţia STEP 1).
Deci la prima execuţie a grupului de instrucţiuni, <var>
va avea valoarea <expN1>, la a doua execuţie <expN1> +
<expN3>, la a treia execuţie <expN1> + <expN3> + <expN3>
şi aşa mai departe. De regula pasul de incrementare al
contorului este 1, clauza STEP lipsind.
Când valoarea variabilei <var> creşte peste valoarea
expresiei <expN2> (strict mai mare), în cazul unei valori
pozitive a lui <expN3>, sau scade sub valoarea expresiei
<expN2> (strict mai mică), pentru o valoare negativă a
expresiei <expN3>, se va ieşi din buclă, programul
continuând cu următoarea comandă după ENDFOR.

Exemplu: comanda
FOR i = 1 TO 4
? i
ENDFOR

este echivalentă cu grupul de comenzi


? 1

65
Baze de date SGBD FoxPro

? 2
? 3
? 4
În exemplul de mai sus i este variabila contor, 1 este
valoarea iniţială a variabilei, iar 4 este valoarea finală a
acesteia. La fiecare execuţie a lui ENDFOR variabila i va fi
incrementată cu 1.
La ultima execuţie a comenzii ? i valoarea lui i va fi 4.
Execuţia lui ENDFOR are ca efect creşterea lui i cu 1, deci
valoarea lui i va fi 5, care depăşeşte valoarea finală (4).
Programul va continua cu prima instrucţie de după ENDFOR.
Comanda:
FOR i = 4 TO 1 STEP –2
? i
ENDFOR

este echivalentă cu grupul:


? 4
? 2

Observaţie: Cele trei expresii numerice, <expN1>, <expN2>


şi <expN3> sunt evaluate doar la intrarea în bucla FOR,
modificarea acestora în cadrul buclei ne având nici un efect
asupra numărului de executări ale instrucţiunilor.

Exemplu:
a = 3
FOR i = 1 TO a
a=10
? i*3
ENDFOR

În acest exemplu comenzile a = 3 şi ? i*3 vor fi


executate de trei ori (i va lua pe rând valorile 1, 2 şi 3), chiar
dacă la prima execuţie a acestora o nouă evaluare a lui <exp2>
ar duce la o nouă valoare finală a contorului (această evaluare
nu mai are loc).
În schimb, modificarea valorii contorului în interiorul
buclei va influenţa numărul de execuţii a grupului de
instrucţiuni, testarea variabilei contor făcându-se la fiecare
nouă execuţie a <instrucţiuni>

Exemplu:
FOR i = 1 TO 10
66
Baze de date SGBD FoxPro

? i
i = 15
ENDFOR

Comanda ? i va fi executat o singură dată (pentru i = 1),


după care, datorită valorii 15 a contorului, care depăşeşte
valoarea finală 10, se va ieşi din buclă continuându-se cu
prima instrucţiune de după ENDFOR.
Două clauze speciale pot fi folosite în interiorul unei
bucle FOR … ENDFOR:
- clauza EXIT determină ieşirea forţată din buclă şi
continuarea execuţiei programului cu prima comandă care
urmează după ENDFOR, indiferent de valoarea variabilei
contor;
- clauza LOOP determină saltul peste următoarele
instrucţiuni ale buclei (dintre LOOP şi ENDFOR),
incrementarea sau decrementarea contorului şi trecerea la o
nouă executare a grupului de instrucţiuni, dacă se respectă
condiţia de rămânere în buclă.

Exemplu:
Sumă = 0
FOR i = 1 TO 15
sumă = sumă + 1
IF i = 5
EXIT
ENDIF
ENDFOR

Următorul program este identic, ca rezultat cu cel


precedent:
Sumă = 0
FOR i = 1 TO 15
IF i= 5
LOOP
ENDIF
Sumă = Sumă + 1
ENDFOR

Primul program din acest exemplu funcţionează astfel:


se execută comanda sumă = sumă + 1 de cinci ori, pentru i =
1, 2, 3, 4 şi 5. La i = 5 este respectată condiţia comenzii IF şi
deci va fi executată comanda EXIT care determină saltul la
ultima instrucţie a programului (care afişează rezultatul).
67
Baze de date SGBD FoxPro

Cel de-al doilea program din exemplul anterior are


următoarea funcţionare: se execută comanda sumă = sumă + 1
de cinci ori, pentru i = 1, 2, 3, 4 şi 5, atâta timp cât nu este
respectată condiţia comenzii IF. Când această condiţie devine
adevărată, pentru i = 6, 7, 8, 9 … 15 se va executa comanda
LOOP care determină ignorarea comenzilor următoare din
buclă, deci a comenzii sumă = sumă + 1. Se va ieşi din buclă
în mod normal, când i = 16.

Observaţie: ENDFOR poate fi înlocuit cu NEXT, cu aceeaşi


semnificaţie.

2.8.5 Comanda SCAN…ENDSCAN

Un tip special de buclă, foarte asemănătoare cu FOR …


ENDFOR, dar specializată în lucrul pe o bază de date, este
reprezentată de comanda SCAN … ENDSCAN, cu sintaxa de
forma:

SCAN [ NOOPTIMIZE]
[<domeniu>][FOR <expL1>][WHILE <expL2>]
[<instrucţiuni>]
[LOOP]
[EXIT]
ENDSCAN

Această comandă realizează parcurgerea bazei de date


curente şi executarea grupului de instrucţiuni <instrucţiuni>,
pentru fiecare înregistrare care aparţine domeniului specificat
prin <domeniu>, FOR sau WHILE.
Clauzele LOOP şi EXIT au acelaşi efect ca în cazul
comenzii FOR … ENDFOR, iar clauza NOOPTIMIZE inhibă
optimizarea RUSHMORE.

Exemplu:
SCAN
<instrucţiuni>
ENDSCAN

are acelaşi efect cu


** funcţia RECCOUNT() returnează numărul de articole
** din baza de date
FOR i = 1 to RECCOUNT()

68
Baze de date SGBD FoxPro

** salt la articolul cu numărul de ordine fizica i


GOTO i
<instrucţiuni>
ENDFOR

2.8.6 Comanda DO WHILE…ENDDO

Cel de-al doilea tip de buclă, cu număr nedefinit de


paşi, este implementat în FoxPro prin comanda DO WHILE
… ENDDO, având sintaxa:
DO WHILE <expL>
<instrucţiuni>
[LOOP]
[EXIT]
ENDDO

Această comandă determină execuţia repetată a grupului


<instrucţiuni>, atâta timp cât valoarea expresiei logice este
.T..
Execuţia comenzii se va desfăşura astfel: se evaluează
expresia <expL> şi, dacă aceasta are valoarea .F., execuţia
comenzii se încheie. Dacă valoarea acesteia este .T. se vor
executa instrucţiunile din <instrucţiuni>. La întâlnirea lui
ENDDO se sare la linia conţinând DO WHILE şi expresia
<expL> este reevaluată.
Acest ciclu se continuă până când o evaluare a expresiei
logice <expL> va conduce la valoarea .F., când execuţia
comenzii DO WHILE … ENDDO se încheie, programul
continuând cu prima instrucţie de după ENDDO.
Clauzele LOOP şi EXIT au aceeaşi semnificaţie ca şi la
comanda FOR, prima determinând ignorarea restului de
comenzi şi reevaluarea lui <expL>, iar cea de-a doua
determinând ieşirea forţată din buclă, indiferent de valoarea
expresiei logice <expL>.

Exemplu:
sumă = 0
nr = 1
DO WHILE sumă 1000
sumă = sumă + p
nr = nr + 1
ENDDO
sumă = sumă + nr

69
Baze de date SGBD FoxPro

a = nr – 1
? ` S-au adunat primele` , a,`nr. natural`
?` S-a obţinut suma de`, sumă

Acest program calculează suma a nr numere naturale, nr


fiind numărul maxim de asemenea numere astfel încât suma
lor să nu depăşească 1000.

REZUMAT (Paragraf 2.8)

Comanda
IF<expL><instrucţiuni1>
[ELSE]<instrucţiuni2>
ENDIF
permite executarea fie a unui grup de instrucţiuni, fie
(opţional) a unui alt grup de instrucţiuni, în funcţie de
rezultatul evaluării unei expresii logice.

Funcţia IIF(<expL>, <expr1>, <expr2>), evaluează expresia


logică <expL>, şi, în funcţie de rezultatul logic obţinut,
returnează valoarea uneia din expresiile: <expr1> (pentru
adevărat) sau <expr2> (pentru fals).

Comanda determina execuţia grupului de instrucţiuni


corespunzător pentru care este găsită prima expresie logică
cu valoarea .T..Sintaxă:
DO CASE
CASE <expL1>
<instrucţiuni1>

CASE <expLn>
<instrucţiuniN>]
[OTHERWISE
<instrucţiuni>]
ENDCASE

Comanda (într-o formă sintactică uzual folosită)


FOR <var> = <exp N1> TO <expN2>
<instrucţiuni>
ENDFOR,
determină executarea repetată a grupului de instrucţiuni
<instrucţiuni>, contorizarea acestor paşi fiind făcută printr-o
variabilă <var>.

70
Baze de date SGBD FoxPro

Comanda (într-o formă sintactică uzual folosită)


SCAN [<domeniu>][FOR <expL1>][WHILE <expL2>]
[<instrucţiuni>]
ENDSCAN
realizează parcurgerea bazei de date curente şi executarea
grupului de instrucţiuni <instrucţiuni>, pentru fiecare
înregistrare care aparţine domeniului specificat prin
<domeniu>, FOR sau WHILE.

Comanda (într-o formă sintactică uzual folosită


DO WHILE <expL>
<instrucţiuni>
ENDDO
Determină execuţia repetată a grupului <instrucţiuni>, atâta
timp cât valoarea expresiei logice este .T..

ÎNTREBĂRI

Ce comenzi condiţionale cunoaşteţi?Dar funcţii?

Ce comenzi de "buclare" cunoaşteţi?

Explicaţi modul de funcţionare al unei comenzi


IF…ELSE…ENDIF.

Care este deosebirea între comanda IF şi funcţia IIF?

Care este deosebirea majoră între DO WHILE şi SCAN?

În ce situaţii este adecvată folosirea comenzii DO CASE?

Scrieţi o secvenţă de program care să calculeze şi să afişeze


pe ecran produsul primelor 100 de numere naturale.

Care este efectul clauzei OTHERWISE în cadrul unei comenzi


DO CASE?

Comentaţi următoarea secvenţă de program (a şi b fiind


variabile în memorie):
? a>b
? IIF (a>b, “şir1”, “şir2”)

71
Baze de date SGBD FoxPro

2.9 Căutarea înregistrărilor într-o bază de date

Aflarea numărului de telefon al unei anumite persoane


presupune într-o primă fază găsirea numelui persoanei din
agendă, după care se citeşte numărul de telefon corespunzător.
Identificarea unei persoane după datele personale presupune
căutarea într-un tabel a acelei persoane care corespunde
datelor respective. Având un calendar în care sunt trecute
toate zilele de naştere ale cunoştinţelor, aflarea zilei
onomastice a unui cunoscut presupune căutarea în calendar a
acelei date care corespunde condiţiei noastre.
Acestea sunt trei probleme practice în care intervine
căutarea unei anumite poziţii într-o lista (agenda, tabel,
calendar), în funcţie de o condiţie ce trebuie îndeplinita.
În plan informatic, transformând listele respective în
baze de date, aceste trei situaţii se reduc la găsirea unei
înregistrări care respecta o condiţie dată, într-o bază de date.
În FoxPro aceasta problema se poate rezolva cu ajutorul
comenzii LOCATE.

2.9.1 Comanda LOCATE

Sintaxa:
LOCATE FOR <expL1> [<domeniu>]
[WHILE <expL2>]
[NOOPTIMIZE]

Comanda caută prima înregistrare care respectă condiţia


< expL1 > în baza de date activă. Domeniul înregistrărilor
care se testează este dat de clauzele, <domeniu> şi WHILE,
domeniu implicit fiind ALL
În caz de reuşită, adică la găsirea unei înregistrări care
respectă condiţia logică < expL 1 >, indicatorul de înregistrări
se va poziţiona pe înregistrarea respectiva, iar funcţia
FOUND() va returna valoarea adevărat .T ., iar funcţia EOF( )
va returna valoarea F (EOF( ) - funcţie pentru verificarea
ajungerii indicatorului de înregistrare la sfârşitul bazei de
date).
În caz contrar, indicatorul de înregistrări va fi poziţionat
după ultima înregistrare (numărul total de înregistrări +1),
funcţia FOUND( ) va returna valoarea fals .F. iar EOF( ) va
returna valoarea .T..
Clauza NOOPTIMIZE inhiba optimizarea Rushmore.
72
Baze de date SGBD FoxPro

Exemplu:
USE BAZA
** caută primul articol care corespunde condiţiei şi muta pe el
** indicatorul de înregistrare
LOCATE FOR virsta>25
** afişează acel articol (simplă vizualizare)
DISPLAY
** afişează tabela cu indicatorul de înregistrare pe articolul
** găsit în vederea unei vizualizări sau modificări a acestuia
CHANGE

Într-o bază de date pot exista mai multe înregistrări care


respectă o condiţie dată. Prima dintre acestea va fi găsita
folosind comanda LOCATE (această comandă realizând tot
timpul o căutare de la începutul bazei de date). Următoarele
vor fi găsite folosind comanda CONTINUE (precedata tot
timpul în cadrul programului de o comanda LOCATE), cu o
sintaxa de forma:
CONTINUE

Comanda găseşte următoarea înregistrare care respectă


condiţia specificata în ultima comanda LOCATE aplicată
bazei de date active.

Exemplu:
USE baza
** Observaţie: funcţia FOUND() referită va fi
** tratată în continuarea paragrafului
** citeşte numele de la tastatura
ACCEPT “Numele: : TO var
** caută prima înregistrare
LOCATE FOR nume=var
** verificarea reuşitei căutării
IF FOUND()=.T.
DISPLAY
ELSE
WAIT “ Nu exista”
ENDIF
** caută până la finalul bazei de date
** EOF() returnează .T. dacă s-a ajuns la finalul bazei de date,
** altfel returneaza .F. (End Of File)
DO WHILE NOT(EOF())
CONTINUE
73
Baze de date SGBD FoxPro

IF FOUND()
DISPLAY
ENDIF
ENDDO
USE

2.9.2 Funcţia FOUND( )

Testarea reuşitei sau nereuşitei unei cautări se realizează


cu funcţia FOUND(). De ajutor este în acest caz şi funcţia
EOF() (End Of File) care semnalează, prin returnare valorii
logice .T. ajungerea la finalul bazei de date (deci practic
căutarea s-a realizat în toată baza de date).
Sintaxa completa a funcţiei FOUND() este:

FOUND([<expN> / <expC>])

este folosită pentru testarea rezultatului unei căutări într-o


bază de date, returnând valoarea adevărat în cazul unei căutări
cu succes, şi valoarea fals, în cazul unei căutări nereuşite.
Parametrul <expN> sau <expC> identifică baza de date la care
se referă funcţia (fie prin zona de lucru fie prin aliasul/numele
bazei de date).Dacă nu se utilizează acest parametru, se
consideră baza de date activă.

Exemplu:
**să se găsească primii doi băieţi din baza de date
AGENDA.DBF
** închide toate fişierele din zona curenta de lucru
CLOSE ALL
USE agenda
** caută şi muta indicatorul de înregistrare
LOCATE FOR sex=.T.
? FOUND() ** returnează .T. pentru primul articol găsit
? EOF () ** este sfârşit de fişier?
DISPLAY ** afişează primul articol găsit
** caută al doilea articol şi muta indicatorul de înregistrare
CONTINUE
** funcţia RECNO() returnează numărul de ordine al
** articolului curent (în exemplul de faţă, numarul celui de-al
** doilea articol găsit)
? RECNO()
DISPLAY ** afişează al doilea articol găsit

74
Baze de date SGBD FoxPro

Dintre funcţiile auxiliare utilizabile într-o operaţie de


căutare (dar şi în cadrul altor operaţii) sunt enumerate:
LOWER(expr_caracter) - converteşte literele mari la litere
mici
UPPER(expr_caracter) - converteşte literele mici la litere
mari
LTRIM(expr_caracter) - şterge blankurile nesemnificative
de la începutul argumentului reducând lungimea sa cu
numărul de spatii eliminate
RTRIM(expr_caracter) - şterge blankurile nesemnificative
de la sfârşitul argumentului
ALLTRIM(expr_caracter) - şterge blankurile
nesemnificative de la începutul şi sfârşitul argumentului

Funcţiile anterior prezentate pot fi foarte utile în cazul


unor operaţii de căutare (şi nu numai). Astfel, în situaţia unei
căutări a unei informaţii într-o baza de date, în care singura
deosebire între cheia de căutare şi conţinutul bazei de date o
reprezintă scrierea cu caractere mici sau majuscule, este utilă o
scriere a comenzii de căutarea utilizând funcţiile UPPER sau
LOWER .

Exemplu:
**citeşte de la tastatura un nume într-o variabila var
INPUT 'nume' TO var
LOCATE FOR NUME=var
** dacă conţinutul variabile diferă de cel al câmpului nume
** doar prin modul de
** scriere cu litere mici sau mari, căutarea va eşua
? FOUND () ** va returna fals
** folosirea funcţiei UPPER va conduce la o căutare reuşita
LOCATE FOR upper(NUME)=upper(var)
** o soluţie deseori utilă o constituie comanda
LOCATE FOR upper(NUME)=ALLTRIM(upper(var))

Comanda SET EXACT ON/OFF, prin modul ei de


setarea, stabileşte: ON - se va face (printr-o comandă de
căutare efectiva, de exemplu LOCATE) o căutare exactă, OFF
- o căutare aproximativă. Spre exemplu, în cazul unei căutări
exacte într-un câmp NUME a persoanei 'Ion', căutarea va
conduce la localizarea doar a articolelor care conţin expresia
'Ion' în câmpul NUME. În cazul unei căutări aproximative
(SET EXACT OFF), vor fi localizate şi articole care în
75
Baze de date SGBD FoxPro

câmpul NUME conţine informaţii de genul 'Ionescu', 'Ionica'


etc.

2.9.3 Comanda SEEK

Căutarea (mai rapidă) a unei anumite înregistrări într-o


bază de date indexata se face cu comanda SEEK sau cu
funcţia SEEK().
Comanda SEEK, cu sintaxa

SEEK <expr>

caută în baza de date activă, indexată obligatoriu după câmpul


în care se face căutarea, prima înregistrare pentru care cheia
de index are valoarea < expr> .
Dacă este găsită o asemenea înregistrare, indicatorul de
înregistrări se va poziţiona pe aceasta, funcţia FOUND() va
returna valoarea adevărat (.T.) iar funcţia EOF() va returna
valoarea fals (.F.).
În caz contrar, indicatorul de înregistrări se va poziţiona
după ultima înregistrare, FOUND() va returna valoarea fals iar
EOF() va returna adevărat.
Funcţia este influenţată de comanda SET NEAR
ON/OFF (setarea unei căutări aproximative): dacă aceasta este
în starea ON, indicatorul de înregistrări, în caz de căutare
eşuata a comenzi SEEK, se va poziţiona imediat după cea mai
apropiată înregistrare (din punctul de vedere al potrivirii cheii
index cu expresia).
În acest caz, indiferent dacă căutarea s-a terminat cu
succes sau nu, funcţia RECNO() va returna numărul
înregistrării celei mai potrivite.

Exemplu:
CLOSE ALL
** daca exista un fişier index agenda.cdx
USE agenda INDEX agenda ORDER nume
** daca nu exista, se deschide baza şi se face indexarea
USE agenda
INDEX ON nume TAG nume
** caută şi mută indicatorul de înregistrare
SEEK 'Popescu'
** returnează pe ecran adevărat .T. în caz de căutare reuşită
?FOUND()
76
Baze de date SGBD FoxPro

** returneaza pe ecran adevărat .F. în caz de căutare reuşită


? EOF()
** afişează numărul de ordine al articolului găsit
? RECNO()
** afişează articolul găsit
DISPLAY
** Afişează o fereastra BROWSE cu indicatorul de
** înregistrare pe articolul găsit
** Daca exista şi alte articole cu acelaşi nume, ele vor apare
** succesiv după articolul curent (primul găsit), baza fiind
** indexată după câmpul nume
BROWSE
USE

Funcţia SEEK() are sintaxa:


SEEK(<expr>,[<expN> / <expC>])

returnând o valoare logică, ca rezultat al căutării unei


înregistrări într-o bază de date indexată.
Prin <expN> sau <expC> se specifică baza de date în care se
face căutarea (prin zona de lucru sau alias), daca aceasta este
diferita de cea activa.

2.9.4 Funcţia LOOKUP

Un alt tip de căutare într-o bază de date, este realizat cu


funcţia LOOKUP(). Aceasta caută într-o bază de date prima
apariţie a unei expresii date. În caz de reuşită, indicatorul de
înregistrări se poziţionează pe înregistrarea în care a fost
găsită expresia, funcţia returnând un anumit câmp (conţinutul
acestuia) corespunzător înregistrării respective. În caz de
nereuşită, indicatorul de înregistrări se poziţionează după
ultima înregistrare a bazei de date, iar funcţia va returna şirul
vid.
Sintaxa funcţiei este:

LOOKUP ( <câmp1 >, <expr>, <câmp2> [, <expC> ])


în care:
< câmp 1 > reprezintă câmpul a cărui valoare va fi returnată de
funcţie, în caz de căutare nereuşita.
<expr> specifica expresia de căutat în baza de date
<câmp2> se foloseşte pentru a realiza căutarea expresiei
numai în acest câmp.

77
Baze de date SGBD FoxPro

<expC> se foloseşte pentru baze de date indexate,


Rezultatul este de tip de caracter, numeric, logic sau
dată calendaristică, în funcţie de tipul câmpului returnat.
Exemplu:
**Sa se afişeze numele primei fete din baza de date agenda
CLOSE ALL
USE agenda
** caută în câmpul sex valoarea .F. şi returnează informaţia
** din câmpul nume
? LOOKUP (nume,.F.,sex)
USE

2.9.5 Comanda FIND

Comanda FIND se utilizează în tabelele indexate


realizând o căutare rapidă. De exemplu, la o tabela mare
accesul la date prin intermediul comenzii SEEK sau FIND
durează mai puţin de 2 secunde, spre deosebire de cazul în
care se utilizează comanda LOCATE, când timpul de acces este
mult mai mare.
Sintaxa:
FIND <sir de caractere>
unde:
<sir de caractere> este un grup de caractere căutat (în câmpul
după care s-a făcut indexarea) şi poate fi pus între ghilimele
sau nu. Dacă şirul de caractere este memorat anterior într-o
variabilă de memorie, în comanda FIND numele variabilei
apare precedat de caracterul &.

** caută în câmpul după care s-a făcut indexarea


** conţinutul variabilei var
FIND &var

O metodă de "căutare" într-o bază de date, prin care se


permite accesul doar la anumite înregistrări, este dată de
comanda de filtrare:

SET FILTER TO [<expresie logica>]

Fără o condiţie impusă (doar SET FILTER TO, stare


de altfel implicită), comanda face ca toate articolele bazei de
date să poată fi accesate.

78
Baze de date SGBD FoxPro

Exemplu:
USE personal
** filtru pentru accesarea tuturor articolelor la
** care salar>1000000
SET FILTER TO salar>1000000
** afişare doar a articolelor care îndeplinesc condiţia
** de filtrare
DISPLAY ALL
** înlăturarea condiţiei de filtrare
SET FILTER TO
** afişarea tuturor articolelor bazei de date
BROWSE

REZUMAT (Paragraf 2.9)

Comanda LOCATE FOR <expL1> [<domeniu>]


[WHILE <expL2>] caută prima înregistrare care respectă
condiţia < expL1 > în baza de date activă (ţinând cont şi de
restricţiile impuse de celelalte clauze).

Următoarele înregistrări fi găsite folosind comanda


CONTINUE (precedată tot timpul în cadrul programului de o
comandă LOCATE), cu o sintaxa de forma: CONTINUE

Funcţia FOUND([<expN> / <expC>]) este folosită pentru


testarea rezultatului unei căutări într-o bază de date,
returnând valoarea adevărat în cazul unei căutări cu succes,
şi valoarea fals, în cazul unei căutări nereuşite.

Funcţia EOF() returnează .T. dacă s-a ajuns la finalul bazei


de date, altfel va returna .F.

LOWER(expr_caracter) - converteşte literele mari la litere


mici
UPPER(expr_caracter) - converteşte literele mici la litere
mari
LTRIM(expr_caracter) - şterge blankurile nesemnificative de
la începutul
Argumentului reducând lungimea sa cu nr. de spatii eliminate
RTRIM(expr_caracter) – şterge blankurile nesemnificative de
la sfârşitul
Argumentului
ALLTRIM(expr_caracter) – şterge blankurile nesemnificative
79
Baze de date SGBD FoxPro

de la începutul şi sfârşitul argumentului

Comenzile
SEEK <expr> şi
FIND <sir de caractere>
caută în baza de date activă, indexată (neapărat după câmpul
în care se face căutarea) prima înregistrare pentru care
cheia de index are valoarea <expr> (sau <şir de caractere>).

Funcţia SEEK(<expr>,[<expN> / <expC>]) returnează o


valoare logică, ca rezultat al căutării unei înregistrări într-o
bază de date indexată.

Comanda SET EXACT ON/OFF prin modul ei de setarea


stabileşte: ON - se va face o căutare exactă, OFF - o căutare
aproximativă.

O metoda de "căutare" într-o bază de date, prin care se


permite accesul doar la anumite înregistrări, este data prin
comanda de filtrare: SET FILTER TO [<expresie logica>]

Funcţia
LOOKUP ( <câmp1 >, <expr>, <câmp2> [, <expC> ]) caută
într-o bază de date prima apariţie a unei expresii date. În caz
de reuşită, indicatorul de înregistrări se poziţionează pe
înregistrarea în care a fost găsită expresia, funcţia returnând
un anumit câmp al înregistrării respective. În caz de nereuşită
indicatorul de înregistrări se poziţionează după ultima
înregistrare a bazei de date, iar funcţia va returna şirul vid.

ÎNTREBĂRI

Enumeraţi trei comenzi principale de căutare într-o bază de


date.

Care este utilitatea comenzii CONTINUE? De ce altă


comandă trebuie precedată?

Care este deosebirea majoră între comanda LOCATE şi


comanda SEEK?

Care este diferenţa între comenzile SEEK şi FIND?

80
Baze de date SGBD FoxPro

Să se scrie o secvenţă de program care să realizeze căutarea


succesivă (după două presupuse câmpuri NUME şi SALAR),
în vederea unor modificări, a tuturor articolelor care
corespund datelor introduse de la tastatură (Nume, respectiv
Salar).

Comentaţi secvenţa următoare de program:


USE baza
ACCEPT “Identitate: ” TO variab
GO 1
INDEX ON nume TO fisier
FIND &variab
IF FOUND()
BROWSE
ELSE
@ 10,10 SAY “Nu exista!”
ENDIF
USE

Care este rolul funcţiilor EOF() respectiv FOUND()?

Să se scrie o secvenţă de program care să realizeze o filtrare


a unor articole a unei baze de date, în vederea modificării lor.

Care este diferenţa între comanda SEEK şi funcţia SEEK()?

Care este efectul funcţiilor UPPER(…), respectiv LTRIM(…)?

Poate fi utilizată comanda LOCATE fără perechea ei,


comanda CONTINUE?

În ce situaţii este utilă folosirea comenzii SET EXACT ON-


OFF?

Care este efectul secvenţei de comenzi(var fiind o variabilă de


memorie):
LOCATE FOR ALLTRIM(UPPER(NUME))=UPPER(var)
IF EOF( )
? “Cautare nereusita”
ENDIF

Care este efectul vizibil pe ecran al comenzilor de căutare


LOCATE, FIND şi SEEK ?
81
Baze de date SGBD FoxPro

2.10 Import/export dintr-o bază de date

SGDB-ul FoxPro oferă posibilitatea transferării de


informaţii între o bază de date şi alte elemente:
- în memorie: masive/tablouri, variabile;
- pe harddisk: fişiere de tip bază de date (in formate
specifice altor SGBD-uri) sau de alte tipuri (text, etc.).

2.10.1 Comenzi de import/export din/spre alte tipuri de fişiere

APPEND FROM <fişier>/?[FIELDS<lista _câmpuri>]


[FOR<expr_logică>]
[[TYPE][DELIMITED[WITH TAB
/WITH<delimitator_caracter>/WITH BLANK]]
/DIF/FW2/MOD/PDOX/RPD/SDF/SYLK/WK1/
WK3/WKS/WR1/ WRK/XLS]

Comanda permite adăugarea (importul) de înregistrări la


sfârşitul unei bazei de date deschise. Aceste înregistrări sunt
preluate dintr-un fişier bază de date de alt tip. Tipul acestui
fişier este specificat prin clauza TYPE, urmată de una dintre
parametrii opţionali cuprinşi în ultima listă. Spre exemplu:
PDOX – fişier de tip Paradox, XLS – fişier Excel, WK1 –
fişier Lotus 1-2-3, MOD – fişier Microsoft Multiplan etc.
Clauza DELIMITED este folosită pentru importul de
date într-un fişier de tip text (.txt), prin ea fiind specificat tipul
de delimitare care separă câmpurile între ele (BLANK, TAB,
caracter separator).
Transferul invers (exportul) de la o bază de date FoxPro
spre un nou fişier de alt tip se realizează cu comanda:

COPY TO <fişier>
[FIELDS <lista_câmp>][<scope>]
[FOR<expr_logică1>] [WHILE<expr_logică2>]
[[WITH] CDX]/[[WITH]PRODUCTION]
[DELIMITED][WITH TAB/
WITH<delimitator_caracter> /WITH BLANK]
[[TYPE] FOXPLUS/DIF/MOD/SDF/SYLK/WK1/
WKS/WR1/WRK/XLS]

Comanda copiază conţinutul bazei de date active într-un


nou fişier. Clauzele [[WITH] CDX] sau
[[WITH]PRODUCTION] sunt echivalente, permiţând crearea
82
Baze de date SGBD FoxPro

unui fişier index structural şi pentru noua bază de date, dacă


baza de date sursă are un astfel de fişier (deci practic creează o
copie şi pentru fişierul index structural). Celelalte clauze sunt
similare cu cele ale comenzii de import.
Alte doua comenzi utilizate pentru transferul din/spre
un fişier bază de date FoxPro sunt:
- comanda IMPORT FROM (importă datele dintr-un
fişier bază de date cu alt format, într-un nou fişier bază de date
în format FoxPro).

IMPORT FROM <fişier>[TYPE]FW2/MOD/PDOX/


RPD/WK1/WK3/WKS/WKR/XLS

- comanda EXPORT TO (exportă date dintr-un fişier


bază de date FoxPro activ, într-un nou fişier bază de date cu
alt format).

EXPORT TO <fişier> [FIELDS<lista_câmpuri>][<scope>]


[FOR <expr_logica1>][WHILE <expr_logica2>]
[TYPE]FW2/MOD/PDOX/RPD/WK1/WK3/WKS/
WKR/XLS

2.10.2 Comenzi de import/export din/spre alte tipuri de date


(variabile, masive)

Masive (tablouri) şi şiruri

Pentru a folosi un tablou, acesta trebuie anterior


declarat şi creat în vederea alocării unui spaţiu de memorie.
Există două comenzi echivalente pentru crearea (declararea)
unuia sau mai multor masive:

DIMENSION<nume_masiv1>
(<expr_numerică1>[,<expr_numerică2>])
[,<nume_masiv2>(<expr_numerică3>
[,<expr_numerică4>])]…

83
Baze de date SGBD FoxPro

sau:

DECLARE
<nume_masiv1>(<expr_numerică1>[,<expr_numerică2>])
[,<nume_masiv2>(<expr_numerică3>
[,<expr_numerică4>])]…

Exemple:
**creează un masiv unidimensional (şir) cu 10 elemente
DECLARE Alfa(10)
**declara un masiv bidimensional (matrice) cu 2 linii şi 4
coloane
DIMENSION Alfa1(2,4)

Modul în care un element al unui masiv poate fi referit


şi utilizat, este ilustrat prin exemplele următoare:

? Alfa(1)
** afişează pe ecran elementul 1 al masivului şir Alfa
? Alfa1(2,2)
** afişează pe ecran elementul de pe linia 2, coloana 2

O comanda pentru încărcarea unui masiv cu elemente


ale bazei de date este COPY TO ARRAY, având următoarea
sintaxă:

COPY TO ARRAY <nume_masiv>


[FIELDS<lista_câmpuri>][<scope>]
[FOR<expr_logica1>][WHILE<expr_logica2>]

Exemplu:
USE baza
DECLARE alfa(20,3) ** nu este necesară
** copiază în masivul alfa (având 20 de linii şi 3 coloane),
** informaţia din câmpurile nume,virsta, salar
** corespunzătoare primelor 20 de articole ale bazei de date
COPY TO ARRAY alfa FIELDS nume, virsta,;
salar
** afişează conţinutul elementului de pe linia 2,
** coloana 3 (deci practic informaţia corespunzătoare
** câmpului salar al celui de-al doilea articol al bazei de date)
? alfa(2,3)

84
Baze de date SGBD FoxPro

Masivul nu trebuie definit înainte, prin comanda COPY


TO ARRAY, realizându-se şi crearea masivului şi copierea
informaţie dorite. Dacă masivul a fost creat înainte (cu o
comanda DIMENSION sau DECLARE), pot apărea câteva
situaţii particulare: în cazul în care dimensiunea masivului
este mai mica decât dimensiunea informaţie care urmează a fi
copiata, elementele masivului vor fi toate umplute iar restul de
informaţie este ignorata; în caz contrar (dimensiunea
masivului este mai mare decât cantitatea de informaţie
copiata), elementele masivului ramase libere vor fi iniţializate
implicit cu .F. (false). Informaţia din câmpurile MEMO este
ignorată.
Comanda inversă, pentru adăugarea într-o bază de date
a unor informaţii stocate într-un masiv are sintaxa:

APPEND FROM ARRAY <nume_masiv>


[FIELDS<lista_câmpuri>]
[FOR<expr_logica1>]

Pentru fiecare linie a masivului este adăugat câte un nou


articol. Informaţia din câmpurile MEMO este ignorată. Dacă
baza de date are mai multe câmpuri decât numărul de coloane
ale masivului, câmpurile respective vor fi completate cu:
spaţiu (pentru tipul caracter), 0 (pentru tipul numeric), data
vida ({} pentru tipul caracter, .F. (pentru tipul logic). Dacă
masivul are mai multe coloane decât numărul de câmpuri ale
bazei de date, coloanele suplimentare sunt ignorate.
Pentru transferul de date între variabile sau masivi şi
baze de date se pot folosi şi comenzile SCATTER şi GATHER.
Deosebirile fata de comenzile anterioare consta în faptul ca
SCATTER şi GATHER lucrează la nivelul unui articol, în
timp ce COPY TO ARRAY şi APPEND FROM ARRAY
lucrează la nivelul mai multor articole.
Comanda SCATTER copiază câmpurile înregistrării
curente din baza de date activă într-un masiv sau în variabile
de memorie.
Comanda are următoarea sintaxă:

SCATTER [FIELDS<listă_câmpuri>][MEMO]
TO <masiv>/ TO <masiv> BLANK/MEMVAR/
MEMVAR BLANK

în care:
85
Baze de date SGBD FoxPro

FIELDS specifică câmpurile din înregistrarea curentă


care se vor copia (cele din lista care urmează clauzei). Dacă nu
se specifică această clauza se vor copia toate câmpurile.
<masiv> reprezintă numele masivului în care se vor
copia câmpurile înregistrării curente, astfel: primul câmp în
primul element al masivului, cel de al doilea câmp în al doilea
element al masivului, şi aşa mai departe până la epuizarea
câmpurilor sau a elementelor masivului. Dacă masivul nu
există, atunci se va crea unul înainte de realizarea copierii.
Dacă printre câmpurile ce se vor copia există şi unul de tip
memo trebuie să se includă clauza [MEMO], altfel acesta va fi
ignorat.
Ultima parte a sintaxei acestei comenzi prezintă patru
alternative:
- prima (TO<masiv>) realizează copierea după
tehnica prezentată anterior.
- a doua alternativă (TO<masiv>BLANK) este
identică cu prima, cu deosebirea că toate câmpurile
masivului vor fi ‘vide’ (adică iniţializate cu blanc
pentru şiruri de caractere, 0 pentru numere, false
pentru elemente logice şi dată vidă pentru elemente
de tip dată calendaristică).
- în cazul celei de-a treia alternative (MEMVAR)
copierea nu se va mai face într-un masiv, ci într-un
set de variabile care poartă acelaşi nume cu
câmpurile corespunzătoare. Dacă acestea nu există,
se vor crea înainte de copiere.
- ultima alternativă (MEMVAR BLANK) este
asemănătoare cu cea precedentă, dar variabilele vor
fi iniţializate implicit cu valori vide.

Opusă comenzii SCATTER este comanda GATHER cu


următoarea sintaxă:

GATHER FROM<masiv>/MEMVAR
[FIELDS <listă_câmpuri>][MEMO]

Comanda copiază conţinutul masivului <masiv> sau a


unor variabile (MEMVAR) în înregistrarea curentă a bazei de
date active.
Dacă se specifică clauza FIELDS, se vor copia doar
câmpurile din lista care urmează acestei clauze.

86
Baze de date SGBD FoxPro

Copierea se va face în felul următor: primul element al


masivului va fi copiat în primul câmp (eventual din lista de
câmpuri) al înregistrării curente din baza de date activă, al
doilea element în al doilea câmp şi aşa mai departe, până când
se termină elementele masivului sau câmpurile înregistrării
curente.
Specificarea clauzei MEMVAR în loc de <masiv> are
ca efect copierea în înregistrarea curentă a bazei de date activă
a variabilelor de memorie cu acelaşi nume cu al câmpurilor
care se vor copia. Dacă una sau mai multe variabile de acest
tip nu există, câmpul va rămâne neschimbat.
Dacă printre câmpurile de copiat se află şi unul de tip
memo, atunci se va include în comandă clauza MEMO.

Exemplu:
Se consideră baza de date arhiva.dbf, în care se doreşte
schimbarea între ele a înregistrărilor cu numerele 2 şi 4.
La această interschimbare se va folosi ca intermediar un
set de variabile, care poartă acelaşi nume cu câmpurile
corespunzătoare şi respectiv un masiv cu numele sir.
Tehnica de schimbare este dată în următoarea figura
următoare:

INREGISTRAREA 2
1-SCATTER
4 GATHER

MASIV SET VARIABILE


2-SCATTER
3-GATHER
INREGISTRAREA 4

Programul care realizează această sarcină este următorul:

USE arhiva
** listează articolele 2 şi 4 (funcţia RECNO()
** returnează numărul articolului curent
LIST FOR RECNO ()=2 .AND. RECNO()=4
GO TO 2
** operaţia 1: copierea înregistrării 2 în setul de variabile
SCATTER MEMVAR MEMO
GO TO 4
** operaţia 2: copierea înregistrării 4 în masivul şir

87
Baze de date SGBD FoxPro

SCATTER TO sir MEMO


** operaţia 3: copierea setului de variabile în înregistrarea 4
GATHER MEMVAR MEMO
GO TO 2
** operaţia 4: copierea masivului în înregistrarea 2
GATHER FROM sir MEMO
LIST FOR RECNO ()=2 .AND. RECNO()=4
USE
RELEASE ALL ** şterge masivul şi variabilele de memorie

REZUMAT (Paragraf 2.10)

SGDB-ul FoxPro oferă posibilitatea transferării de informaţii


între o bază de date şi alte elemente: masive/tablouri,
variabile, fişiere de tip bază de date (in formate specifice
altor SGBD-uri) sau fişiere de alte tipuri (text, etc.).

Comanda
APPEND FROM <fişier>/?[FIELDS<lista _câmpuri>]
[FOR<expr_logică>]
[[TYPE][DELIMITED[WITH TAB
/WITH<delimitator_caracter>/WITH BLANK]]
/DIF/FW2/MOD/PDOX/RPD/SDF/SYLK/WK1/
WK3/WKS/WR1/ WRK/XLS]
permite adăugarea (importul) de înregistrări, dintr-un fişier
bază de date de alt tip, la sfârşitul bazei de date FoxPro
deschise.

Transferul invers (exportul) de la o bază de date FoxPro spre


un nou fişier de alt tip se realizează cu comanda:
COPY TO <fişier>
[FIELDS <lista_câmp>][<scope>]
[FOR<expr_logică1>] [WHILE<expr_logică2>]
[[WITH] CDX]/[[WITH]PRODUCTION]
[DELIMITED][WITH TAB/
WITH<delimitator_caracter> /WITH BLANK]
[[TYPE] FOXPLUS/DIF/MOD/SDF/SYLK/WK1/
WKS/WR1/WRK/XLS]

Comanda
IMPORT FROM <fişier>[TYPE]FW2/MOD/PDOX/
RPD/WK1/WK3/WKS/WKR/XLS

88
Baze de date SGBD FoxPro

importă datele dintr-un fişier bază de date cu alt format, într-


un nou fişier bază de date în format FoxPro.

Comanda
EXPORT TO <fişier> [FIELDS<lista_câmpuri>][<scope>]
[FOR <expr_logica1>][WHILE <expr_logica2>]
[TYPE]FW2/MOD/PDOX/RPD/WK1/WK3/WKS/
WKR/XLS
exportă date dintr-un fişier bază de date FoxPro activ, într-un
nou fişier bază de date cu alt format.

Pentru a folosi un tablou, acesta trebuie anterior declarat şi


creat în vederea alocării unui spaţiu de memorie.

Există două comenzi echivalente pentru crearea (declararea)


masivelor (aici prezentate cu sintaxa pentru cazul declararii
unui singur masiv):
DIMENSION<nume_masiv1>
(<expr_numerică1>[,<expr_numerică2>])
DECLARE<nume_masiv1>
(<expr_numerică1>[,<expr_numerică2>])

Comanda pentru încărcarea unui masiv cu elemente ale bazei


de date active este:
COPY TO ARRAY <nume_masiv>
[FIELDS<lista_câmpuri>][<scope>]
[FOR<expr_logica1>][WHILE<expr_logica2>]

Comanda inversă, pentru adăugarea într-o bază de date a


unor informaţii stocate într-un masiv este:
APPEND FROM ARRAY <nume_masiv>
[FIELDS<lista_câmpuri>]
[FOR<expr_logica1>]

Comanda SCATTER copiază câmpurile înregistrării curente


din baza de date activă într-un masiv sau în variabile de
memorie:
SCATTER [FIELDS<listă_câmpuri>][MEMO]
TO <masiv>/ TO <masiv> BLANK/MEMVAR/
MEMVAR BLANK

Opusă comenzii SCATTER este comanda GATHER care


copiază conţinutul masivului <masiv> sau a unor variabile

89
Baze de date SGBD FoxPro

(MEMVAR) în înregistrarea curentă a bazei de date active:


GATHER FROM<masiv>/MEMVAR
[FIELDS <listă_câmpuri>][MEMO]

Comenzile SCATTER şi GATHER lucrează la nivelul unui


articol, în timp ce COPY TO ARRAY şi APPEND FROM
ARRAY lucrează la nivelul mai multor articole.

ÎNTREBĂRI

Ce comenzi pentru importul/exportul informaţiei dintr-o bază


de date de un anumit tip spre o alăa bază de date specifică
unui alt SGBD cunoaşteţi?

Să se scrie o secvenţă de program care să permită:


- importul într-o bază de date FoxPro a întregii informaţii
dintr-o primă bază de date Paradox (cu numele sursă),
- adăugarea în baza FoxPro a unor informaţii dintr-un fişier
Excel

Cum se poate declara un masiv bidemensional?

Copiaţi întreg conţinutul unei baze de date într-un masiv.


Care sunt dimensiunile masivului astfel creat?

Copiaţi conţinutul articolului curent al unie baze de date


active într-un masiv. Care sunt dimensiunile masivului astfel
creat?

Să se scrie un program care să permită schimbarea între două


baze de date a conţinutului primului articol.

Care este deosebirea între o comandă APPEND FROM


ARRAY <nume_masiv> şi GATHER FROM<nume_masiv>?

Comentaţi secvenţa de program următoare:


USE Baza
SCATTER MEMVAR MEMO
GO 10
GATHER MEMVAR MEMO

90
Baze de date SGBD FoxPro

2.11 Ordonarea unei baze de date

Ordonarea unei baze de date reprezintă operaţia de


rearanjare a articolelor unei baze de date într-o anumită ordine
dorită: alfabetică, numerică crescătoare/descrescătoare,
cronologică etc. Tipul informaţiei conţinută în câmpurile bazei
de date (caracter, numeric, data calendaristica etc.) determină
tipul ordonării. În FoxPro se pot distinge două modalităţi de
ordonare a articolelor unei baze de date:
1) Sortare
2) Indexare

Din punct de vedere al accesului la informaţie,


rezultatele sunt similare atât în cazul unei sortări cât şi în cel
al unei indexări: articolele din bazele de date par a fi
reordonate în funcţie de criteriul dorit. Totuşi, între cele două
metode de ordonare există o diferenţa semnificativă.
Sortarea creează o nouă bază de date (pornind de la
baza de date activă), printr-o rearanjare fizică a articolelor.
Noua bază de date astfel creata conţine practic articole (o
selecţie sau toate) ale bazei de date sursă (activă) a căror
poziţie fizică este dictată de criteriul (cheia) de sortare
folosit. Se poate deduce uşor că, în acest caz, se realizează o
duplicare (totală sau parţială) a informaţiei. Se poate crea
chiar o copie a bazei de date active, deosebirea faţă de aceasta
fiind doar modul de aranjare fizică a articolelor.
În cazul unei indexări se creează un nou fişier numit
fişier index (şi nu o nouă bază de date ca în cazul sortării),
acesta conţinând cheia de ordonare şi respectiv valorile
ordonate ale numerele de ordine corespunzătoare
înregistrărilor bazei de date. În acest caz nu se produce nici o
rearanjare fizică a înregistrărilor, acest fişier index ataşat
bazei de date asigurând o ordonare logică a articolelor. Prin
ordonare logică se înţelege că poziţia fizica a articolelor în
baza de date nu s-a modificat, dar din punct de vedere al
accesului la informaţie acestea apar ca fiind ordonate funcţie
de cheia de ordonare.
Cheia de ordonare, este de regulă, numele câmpului
după care se face ordonarea sau o expresie în care apar unul
sau mai multe câmpuri.
O diferenţiere figurativa între o operaţie de sortare
respectiv indexare este prezentata mai jos în tabelele
următoare:
91
Baze de date SGBD FoxPro

Baza de date sursa Baza de date destinaţie


(baza1.dbf) (baza2.dbf)
Nume Sortare Nume
1 Ion Æ 2 Alexandru
2 Alexandru USE baza1 3 Dan
SORT TO baza2 ON Nume
3 Dan 1 Ion
Fisier
index (fis.idx)
Nume Indexare
1 Ion Æ Nume
2 Alexandru USE baza1 (cheie indexare)
INDEX ON Nume TO fis
3 Dan 2
3
1

Se poate uşor observa ca prin sortare se realizează o


ordonare propriu-zisă a bazei de date, prin schimbarea fizica a
poziţiilor înregistrărilor, după un anumit algoritm, până când
acestea sunt în ordinea dorită. În acest caz, se obţine o nouă
bază de date (baza2.dbf – baza destinaţie) care conţine
aceleaşi înregistrări ca şi cea de la care s-a pornit (baza1.dbf –
baza sursa), dar în ordinea dorită.
Prin indexarea bazei de date se creează un nou fişier
(numit fişier index) care conţine informaţiile privitoare la
ordinea înregistrărilor bazei de date, respectiv cheia de
indexare. Acest fişier nu conţine înregistrările fizice ale bazei
de date, memorând numai ordinea acestora.
Pe lângă posibilitatea unei aranjări a articolelor unei
baze de date într-o anumita succesiune dorită, o astfel de
ordonare oferă şi posibilitatea căutării şi găsirii rapide a unei
anumite informaţii în baza de date. Un exemplu elocvent în
acest sens îl reprezintă o carte de telefon în care abonaţii sunt
înregistraţi în ordine alfabetică. O astfel de ordonare permite
găsirea cu uşurinţă a numărului de telefon a unui anumit
abonat (pentru care este cunoscut numele). Exemplu oferit
este destul de elocvent pentru justificarea necesitaţii ordonării
informaţiilor după anumite criterii (deci a ordonării bazelor de
date care conţin informaţiile respective).

92
Baze de date SGBD FoxPro

2.11.1 Sortarea unei baze de date

Comanda SORT are următoarea sintaxă:

SORT TO <nume_fişier> ON <câmp_1>[/A | /D][/C]


[,<câmp_2> [/A | /D][/C]….][ASCENDING |
DESCENDING][<scope>]
[FOR <exp_L1>]
[WHILE <exp_L2>][FIELDS <listă_de_cămpuri>]
[NOOPTIMIZE]

Comanda sortează baza de date activă, creând o nouă


bază de date, în care sunt copiate (parţial sau în totalitate)
înregistrările selectate în ordinea specificată. Baza de date
nouă va conţine câmpurile specificate la clauza FIELDS, sau
toate câmpurile, în cazul când această clauză lipseşte. Noua
bază de date va purta numele <nume_fişier>. De remarcat
faptul ca utilizarea noi baze de date, imediat după creare,
implica obligatoriu deschiderea ei (deci o comanda USE
<nume_fisier>).

Exemplu:
USE baza1
** sortare ascendenta după câmpul nume, fără a ţine
** seama de caractere mari sau mici
SORT TO baza2 ON nume/AC
LIST ** listează articolele din baza1.dbf
USE baza 2
LIST ** listează articolele din baza2.dbf

Cheia de ordonare este dată de câmpurile <câmp_1>,


<câmp_2>, … specificate după clauza ON a comenzii. Spre
exemplu, în situaţia în care se doreşte o ordonare după
‘nume’ şi ‘prenume’ (considerate ca fiind câmpuri ale bazei de
date), comanda este:
SORT TO baza2 ON nume, prenume
Iniţial se face o sortare după ‘nume’, iar pentru nume
identice se face şi o sortare după ‘prenume’. Dacă s-ar face
doar o sortare după ‘nume’, pentru articolele cu ‘nume’ identic
s-ar păstra ordinea existenta în baza primara.
Clauzele ASCENDING şi DESCENDING sunt similare
clauzelor /A şi /D, numai că se referă la toate câmpurile din
listă. În lipsa acestor clauze, ordinea implicită este crescătoare,
93
Baze de date SGBD FoxPro

deci ASCENDING. Clauzele asociate câmpurilor, /A şi /D, au


prioritate faţă de clauzele ASCENDING şi DESCENDING.
<scope>, FOR şi WHILE selectează înregistrările care
se vor ordona şi vor fi copiate în noua bază de date. Clauza
NOOPTIMIZE inhibă optimizarea Rushmore.

Exemplu:
USE student.dbf
** sortează descrescător după data naşterii; pentru date
** identice, sortează ascendent după ‘prenume’; se copiază
** în noua bază de date doar articolele ordonate pentru care
** câmpul sex=.F.
SORT TO studentf ON născut /D, prenume;
ASCENDING FOR sex=.F.
USE studentf
LIST
USE
Observaţie: Scrierea unei comenzi pe mai multe rânduri
necesită caracterul “;”. Acesta arată că respectiva comandă se
continua şi pe linia următoare.

2.11.2 Indexarea

Reprezintă o alternativă mai rapidă pentru sortarea


informaţiei având efectul sortării din punct de vedere al
accesului la informaţie. Indexarea poate fi specificată chiar la
crearea fişierului original, deci chiar la crearea structurii
acestuia.
Fişierele index care pot fi asociate unei baze de date
sunt de două tipuri :
- fişierele index simple – extensia .idx (Single Entry
Index File)– care conţin o singură cheie de ordonare
- fişierele index compuse – extensia .cdx (Compound
Index File) – care memorează mai multe chei de
ordonare, o singură cheie fiind activă la un moment
dat. La rândul lor, fişierele index compuse pot fi de
doua tipuri: nestructurale şi structurale (se vor oferi
mai multe informaţii asupra acestora în continuare).
O bază de date poate avea mai multe fişiere index
asociate dar numai unul poate fi activ la un moment dat.
Ordinea după care se face accesul la informaţia din baza de
date este dată de fişierul index activ.

94
Baze de date SGBD FoxPro

Comanda pentru crearea unui fişier index are


următoarea sintaxă:

INDEX ON <expresie> TO <fişier.idx/TAG <etichetă>


[OF <fişier.cdx>]
[FOR <expresie_logica>]
[COMPACT] [ASCENDING/DESCENDING]
[UNIQUE] [ADDITIVE]

Cheia de ordonare (indexare) va fi specificată prin


parametrul <expresie>, aceasta conţinând nume de câmpuri
ale bazei de date (un câmp sau combinaţii de câmpuri de
genul: <câmp1> + <câmp2> +…). Nu sunt admise câmpuri de
tip MEMO.
Fişierul index creat va avea numele specificat prin
<fişier.idx> în cazul în care este vorba despre un fişier index
simplu.

Exemple:
** Se creează un fişier index simplu (fisier1.idx),
** cheia de indexare fiind câmpul ‘nume’
INDEX ON nume TO fisier1
** Se creează un fişier index simplu (fisier2.idx),
** cheia de indexare fiind expresia ‘nume+prenume’
INDEX ON nume+virsta TO fisier2

În cazul unui fişier index compus nestructural, numele


acestui este precizat prin <fişier.cdx>, iar în cazul unui fişier
structural acesta va avea numele bazei de date (şi extensia
.cdx).
Fişierele index structurale sunt deschise şi asociate
automat fişierului bază de date odată cu deschiderea acestuia
(comanda USE…). Aceste fişiere au acelaşi nume cu baza de
date şi sunt create folosind clauza TAG <etichetă> (fără
specificarea unui nume în clauza ON). Parametrul <eticheta>
din clauza TAG este practic numele dat expresiei (cheii) după
care se face indexarea (lungime maxima 10 caractere). În
cazul în care aceasta expresie este practic un singur câmp al
bazei de date, de regula numele dat chei de indexare este
acelaşi cu numele câmpului. Acest tip de fişiere index este cel
mai recomandat a fi utilizat.

95
Baze de date SGBD FoxPro

Exemple:
USE baza
** Se creează un fişier index compus structural (având numele
** baza.cdx), cheia de indexare fiind botezată ‘nume’
** (indexarea facându-se după câmpul nume)
INDEX ON nume TAG nume
** Se adaugă o nouă cheie de indexare botezata ‘identitate’
** (indexarea făcându-se după expresia ‘nume+prenume’) în
** fişierul index compus structural (baza.cdx)
INDEX ON nume+prenume TAG identitate

Fişierele index compuse nestructurale nu sunt


deschide automat odată cu baza de date, ele purtând alt nume
decât al bazei de date, nume specificat prin clauza OF
<fişier.cdx>.
Dacă fişierul index compus nestructural este creat
anterior (deci el există), eticheta specificată se adaugă la
celelalte etichete ale fişierului index.
Exemplu:
USE baza
** Se creează un fişier index compus nestructural (fisier.cdx),
** cheia de indexare fiind botezata ‘nume’ (indexarea
** făcându-se după câmpul nume)
INDEX ON nume TAG nume OF fisier
** Se adaugă o nouă cheie de indexare botezată ‘identitate’
** (indexarea făcându-se după expresia ‘nume+prenume’) în
** fişierul index compus nestructural (fisier.cdx)
INDEX ON nume+prenume TAG identitate OF
fisier

Clauza COMPACT – determină crearea unui fişier index


simplu care va beneficia de o tehnică mai rapidă de accesare a
informaţiilor. Fişierele index compuse sunt întotdeauna
compacte (deci nu este necesara folosirea în cazul lor a
clauzei COMPACT).
În cazul în care există mai multe înregistrări cu aceeaşi
valoare a cheii de indexare (spre exemplu cu acelaşi ‘nume’,
cu aceeaşi ‘vârsta’), utilizarea clauzei UNIQUE permite
accesarea doar a unei înregistrări (prima din lista de
înregistrări astfel ordonata).
Clauzele ASCENDING/DESCENDING stabilesc
ordinea dorita a indexării.

96
Baze de date SGBD FoxPro

La deschiderea unei baze de date, în comanda USE se


pot specifica fişierele index asociate care se vor deschide
odată cu fişierul bază de date (vezi comanda USE …)

Exemplu:
USE baza
INDEX ON nume TO fisier ** creează fisier.idx
INDEX ON nume TAG nume ** creează baza.cdx
** creează fisier.cdx (ultimul fişier index fiind cel activ)
INDEX ON virsta TAG virsta OF fisier
CLOSE ALL ** se închid toate fişierele din zona 1
** deschide baza de date, având fişierul index simplu
** fisier.idx activ
USE baza INDEX fisier
** deschide baza de date având activă cheia nume din fişierul
** index compus structural (baza.cdx)
USE baza ORDER nume
** deschide baza de date având activă cheia virsta din fişierul
** index compus
** nestructural (fisier.cdx)
USE baza ORDER virsta OF fisier

Pe parcursul lucrului cu o bază de date este posibilă


deschiderea unor fişiere index asociate care nu au fost
specificate în comanda USE. Pentru aceasta se poate folosi
comanda următoare :

SET INDEX TO <listă_fişiere_index>/?


[ORDER<expresie_numerică><fişier.idx>TAG<etichetă>
[OF<fişier.cdx>]
[ASCENDING/DESCENDING][ADDITIVE]

Comanda deschide toate fişierele index specificate în


<lista_fişier_index>. Fişierul index simplu activ sau eticheta
activă dintr-un fişier index compus se va specifica pin clauza
[ORDER].
Noua listă se va adăuga la lista fişierelor deschise dacă
se specifică clauza ADDITIVE în caz contrar o va înlocui.
SET INDEX TO fără alte clauze va închide toate
fişierele index din zona de lucru excepţie făcând fişierele
index.

97
Baze de date SGBD FoxPro

Având deschise cu bază de date mai multe fişiere index,


pentru a selecta alt fişier sau altă etichetă activă se va folosi
comanda :

SET ORDER TO <expresie_numerică1>/<fişier.idx>/


TAG <etichetă>
[OF <fişier.cdx>][IN <expresie_numerică2>]
[ASCENDING/DESCENDING]

Pentru specificarea fişierului index simplu activ sau


etichetei active, se foloseşte fie expresia numerică care
specifică poziţia în lista fişierelor deschise, fie prin
specificarea numelui fişierului index simplu sau a etichetei
corespunzătoare unui fişier index compus. Clauza [IN] este
folosită pentru a indica o altă zonă de lucru (alta decât zona
curentă) în care va acţiona comanda.

REZUMAT (Paragraf 2.11)

În FoxPro se pot distinge două modalităţi de ordonare a


articolelor unei baze de date:
1.Sortare
2.Indexare

Sortarea creează o nouă bază de date (pornind de la baza de


date activă), printr-o rearanjare fizică a articolelor:
SORT TO <nume_fişier> ON <câmp_1>[/A | /D][/C]
[,<câmp_2> [/A | /D][/C]….][ASCENDING |
DESCENDING][<scope>]
[FOR <exp_L1>]
[WHILE <exp_L2>][FIELDS <listă_de_cămpuri>]

Prin indexare se creează un nou fişier numit fişier index (şi nu


o nouă bază de date ca în cazul sortării), acesta conţinând
cheia de ordonare şi respectiv valorile ordonate ale numerele
de ordine corespunzătoare înregistrărilor bazei de date:
INDEX ON <expresie> TO <fişier.idx./TAG <etichetă>
[OF <fişier.cdx>]
[FOR <expresie_logica>]
[COMPACT] [ASCENDING/DESCENDING]
[UNIQUE] [ADDITIVE]

98
Baze de date SGBD FoxPro

Un fişier index nu conţine înregistrări fizice ale bazei de date,


memorând numai ordinea acestora.

Cheia de ordonare (indexare sau sortare), este de regulă,


numele câmpului după care se face ordonarea sau o expresie
în care apar unul sau mai multe câmpuri.

La deschiderea unei baze de date cu un fişier index activ,


articolele bazei de date vor fi accesibile utilizator în ordinea
stabilită de fişierul index (ordinea după care se face accesul
la informaţia din baza de date este dată de fişierul index
activ).

O bază de date poate avea mai multe fişiere index asociate,


dar numai unul poate fi activ la un moment dat

Fişierele index care pot fi asociate unei baze de date sunt de


două tipuri :
• fişierele index simple (idx), cu o singură cheie de
ordonare:
INDEX ON <expresie> TO <fişier.idx>
• fişierele index compuse (cdx), cu mai multe chei de
ordonare,acestea putând fi la rândul lor:
- nestructurale:
INDEX ON <expresie>TAG <etichetă>OF <fişier.cdx>
- structurale:
INDEX ON <expresie>TAG <etichetă>

Pentru deschiderea unor fişiere index asociate care nu au fost


specificate în comanda USE… se poate folosi comanda:
SET INDEX TO <listă_fişiere_index>/?
[ORDER<expresie_numerică><fişier.idx>TAG<etichetă>
[OF<fişier.cdx>]
[ASCENDING/DESCENDING][ADDITIVE]

Având deschise cu bază de date mai multe fişiere index,


pentru a selecta alt fişier sau altă etichetă activă se va folosi
comanda :
SET ORDER TO <expresie_numerică1>/<fişier.idx>/
TAG <etichetă>
[OF <fişier.cdx>][IN <expresie_numerică2>]
[ASCENDING/DESCENDING]

99
Baze de date SGBD FoxPro

ÎNTREBĂRI

Definiţi operaţiile de sortare respectiv indexare. Ce diferenţe


majore există între acestea?

Ce este o cheie de ordonare? Care este diferenţa de contrucţie


sintactică între o cheie de sortare, respectiv o cheie de
indexare?

Să se scrie o secvenţă de program prin care să se realizeze


sortarea conţinutului unei baze de date, după două presupuse
câmpuri existente – nume şi prenume-.

Să se scrie o secvenţă de program prin care să se realizeze


indexarea conţinutului unei baze de date (creându-se un fişier
index simplu), după două presupuse câmpuri existente –
nume şi prenume-.

Ce tipuri de fişiere index (în FoxPro) cunoaşteţi?

Care este diferenţe între un fişier index structural, respectiv


nestructural?

Să se scrie o secvenţă de program prin care să se realizeze


operaţii succesive de indexare pentru crearea celor 3 tipuri de
fişiere index permise în FoxPro.

Comentaţi acţiunea comenzii SET INDEX TO <nume-fisier>.

Câte fişiere index asociate unei baze de date pot fi active la


un moment dat?

Precizaţi o operaţie (sau comandă) care trebuie obligatoriu


precedată de o indexare.

Comentaţi secvenţa următoare:


USE baza ORDER virsta OF fisier
SORT TO nou ON virsta /D
LIST OFF

100
Baze de date SGBD FoxPro

2.12 Relaţionarea fişierelor

Din mai multe motive printre care şi minimizarea


redundanţei informaţiei, în numeroase aplicaţii, este necesară
gruparea informaţiei utilizate în mai multe fişiere baze de date,
cu toate că informaţia conţinută în diferitele fişiere este legată
logic. A relaţiona două fişiere înseamnă a defini o relaţie între
acestea astfel încât identificarea unuia (sau a mai multor)
articole din primul fişier să determine identificarea unor
articole sau a mai multor articole din fişierul relaţionat.
Fişierul pe care se defineşte relaţia este fişierul părinte, iar
fişierul în care se defineşte relaţia este fişierul copil. Stabilirea
unei relaţii între două sau mai multe baze de date, se face în
FoxPro cu ajutorul comenzii SET RELATION TO, având
sintaxa:

SET RELATION TO [<exp1> INTO <expN1>/<expC1>]


[,<exp2> INTO <expN2>/<expC2>…]
[ADDITIVE]

Din start se precizează că realizarea unei relaţionări


între două baze de date, implica existenta cel puţin a unui
câmp comun celor doua baze de date (câmp după care se va
realiza relaţionarea, deci stabilirea unei relaţii de legătura).
<exp1>, <exp2> - reprezintă cheile relaţiei, adică
criteriul după care o înregistrare din baza de date copil
corespunde unei înregistrări din baza de date părinte. În
general aceste expresii reprezintă un câmp comun al bazei de
date părinte şi a celei copil, şi de asemenea reprezintă cheia de
indexare a bazei de date copil (obligatoriu indexata). În cazul
în care aceste expresii sunt simple expresii numerice,
indicatorul din baza de date copil va fi mutată pe înregistrarea
cu un număr egal cu valoarea expresiei.
<exp1>, <exp2> - sunt evaluate pe rând şi în funcţie de
valorile acestor expresii, indicatorii de înregistrări ai bazei de
date copil vor fi poziţionaţi corespunzător înregistrărilor
părinte.
<expC1>, <expC2> - specifică aliasul bazelor de date
copil sau prin <expN1>, <expN2> - specifică zonele de lucru
corespunzătoare fişierelor baze de date copil (zonele în care
aceste baze copil sunt deschise).

101
Baze de date SGBD FoxPro

Fişierul bază de date părinte reprezintă fişierul bază de


date curent.
Clauza ADDITIVE face ca relaţiile existente pentru
baza de date activa să nu fie şterse şi la acesta să se adauge
noua relaţie definită.
Comanda SET RELATION TO fără clauze determină
înlăturarea tuturor relaţiilor bazei de date curente definite.
Etapele (paşii) care trebuie urmaţi pentru realizarea unei
relaţionări între doua baze de date (părinte şi copil) sunt
următoarele:
Pasul 1 – Se deschide baza de date părinte (implicit în zona 1
de lucru)
Pasul 2 – Se deschide baza de date copil în zona de lucru 2
Pasul 3 – Se indexează baza de date copil după câmpul comun
Pasul 4 – Se revine în zona de lucru a bazei părinte
Pasul 4 – Se face legătura între ele, deci se realizează
relaţionarea

Exemplu:
Se considera bazele de date PERSONAL şi
SALARIAT, având ambele câmpul NUME:
Baza date PĂRINTE (zona 1) Baza date COPIL (zona 2)
Personal.dbf Salariat.dbf
având câmpurile:
NUME NUME
PRENUME VARSTA
TELEFON SALAR
ADRESA

Se doreşte afişarea pe ecran pentru fiecare persoana a


tuturor informaţiilor despre ea (informaţii defalcate în cele
două baze de date).

** se închid toate fişierele deschise


CLOSE ALL
** se deschide baza de date părinte în zona implicita 1
USE Personal
** se deschide baza de date copil în zona 2
SELECT 2
USE Salariat
** se indexează baza copil după câmpul comun
INDEX ON nume TO Salariat
** se revine în zona de lucru a bazei părinte
102
Baze de date SGBD FoxPro

SELECT 1
** se realizează relaţionarea după câmpul comun
SET RELATION TO nume INTO 2
** se listează corelat informaţiile din ambele baze de date
LIST Nume, Prenume, Telefon, Adresa,;
B->Vârstă, B.Salar
** se închid bazele de date
USE ** sau CLOSE
ALL
SELECT 2
USE

Se remarca modul de apelare ca parametru a unui câmp


dintr-o bază de date deschisa în alta zona decât cea curentă:
B->Virsta, B.Salar sau
2->Virsta, 2.Salar (prefixul urmat de -> sau .
indicând zona de lucru unde trebuie căutat acel câmp - în
cazul de faţă zona 2).
Dacă se doreşte o căutare a informaţiilor despre o
anumita persoana (cu date stocate în ambele baze de date),
secvenţa de program corespunzătoare este următoarea:

USE Personal
SELECT 2
USE Salariat
INDEX ON nume TO Salariat
SELECT 1
SET RELATION TO nume INTO 2
** citire de la tastatura a numelui celui căutat
@ 1,1 SAY "numele: " get variabila;
DEFAULT SPACE(20)
READ
** căutare
LOCATE ALL FOR nume=variabila
** afişare date dacă există persoana căutata
IF FOUND()
DISPLAY Nume, Prenume, Telefon, Adresa,;
B->Vârstă, B.Salar
ELSE
** afişare mesaj de căutare nereuşita
@ 5,5 SAY "Persoana nu exista"
ENDIF
CLOSE ALL

103
Baze de date SGBD FoxPro

Comanda SET RELATION face ca fiecărei înregistrări


din baza de date părinte să-i corespunda o înregistrare în baza
de date copil, saltul pointer-ului de înregistrare în cea de-a
doua bază de date făcându-se automat. Dacă unei anumite
înregistrări din baza părinte nu-i corespunde nici un articol în
baza copil, comanda LIST din exemplul anterior nu va afişa
pentru acel articol nici o informaţie corespunzătoare
câmpurilor Vârsta şi Salar
Se pune problema: ce se întâmplă când unei înregistrări
din baza părinte îi corespund mai multe înregistrări în baza
copil. În acest caz (exemplificat prin secvenţele anterioare de
program) comanda SET RELATION determina găsirea numai
a primei dintre aceste înregistrări. Se vorbeşte în aceasta
situaţie de o relaţie de tipul "una-la-una".
Pentru ca printr-o relaţie să poată fi găsite mai multe
înregistrări ale bazei de date copil, este necesara crearea unei
relaţii "una-la-mai-multe". În acest scop se foloseşte comanda
SET SKIP având sintaxa:
SET SKIP TO [<alias1>[,<alias2]…]
Aceasta comandă transformă relaţiile dintre baza de
date curenta şi bazele identificate prin alias1, alias2…, din
relaţii “una-la-una”, în relaţii de genul “una-la-mai-multe”.
Practic comanda SET SKIP precizează în care zone de
lucru, deci în care baze de date se vor efectua salturi relative,
folosind comanda:
SKIP [<expr_numerica]
Comanda SKIP realizează o deplasare relativă (pornind
de la poziţia curentă) a indicatorului de înregistrare,
expr_numerica reprezentând numărul de înregistrări peste care
se sare.
Fără parametrii, SKIP este echivalent cu SKIP 1.
Funcţionarea relaţiilor de tip una-la-mai-multe prezintă
următorii paşi:
- poziţionare indicatorului de înregistrare pe un articol
al bazei părinte (printr-o comanda GOTO,
LOCATE, FIND, SEEK etc) conduce la o
deplasare corespunzătoare a indicatorului de
înregistrare şi în baza copil, şi anume pe primul
articol din baza copil care corespunde înregistrării
părinte (conform relaţiei stabilite) ;
- făcând salturi în baza de date copil, folosind
comanda SKIP (şi având setate salturi relative în
zona de lucru a bazei copil), indicatorul de
104
Baze de date SGBD FoxPro

înregistrare se va poziţiona pe rând în aceasta, pe


următoarele înregistrări care se potrivesc, la cheie,
cu înregistrarea părinte.

Exemplu:
USE Personal
SELECT 2
USE Salariat
INDEX ON nume TO Salariat
SELECT 1
SET RELATION TO nume INTO 2
SET SKIP TO 2
** du-te la articolul 1 din baza părinte
GOTO 1
** afişează prima relaţie găsita
DISPLAY Nume, Prenume, Telefon, Adresa,;
B->Vârstă, B.Salar
** salt relativ (condiţionat de relaţia existenta)
SKIP
** afişează a doua relaţie găsita
DISPLAY Nume, Prenume, Telefon, Adresa,;
B->Vârstă, B.Salar

Observaţie: O bază de date nu poate fi în acelaşi timp şi


părinte şi copil, dar o aceeaşi bază părinte poate avea simultan
mai multe baze copil.

REZUMAT (Paragraf 2.12)

A relaţiona două fişiere baze de date înseamnă a defini o


relaţie între acestea astfel încât identificarea unuia (sau a mai
multor) articole din primul fişier să determine identificarea
unor articole sau a mai multor articole din fişierul relaţionat.

Fişierul pe care se defineşte relaţia este fişierul părinte, iar


fişierul în care se defineşte relaţia este fişierul copil

Stabilirea unei relaţii între două sau mai multe baze de date,
se face în FoxPro cu ajutorul comenzii:
SET RELATION TO [<exp1> INTO <expN1>/<expC1>]
[,<exp2> INTO <expN2>/<expC2>…] [ADDITIVE]

Etapele pentru realizarea unei relaţionări între două baze de


105
Baze de date SGBD FoxPro

date sunt următoarele:


– Se deschide baza de date părinte
– Se deschide baza de date copil într-o altă zonă de lucru
– Se indexează baza de date copil după câmpul comun
– Se revine în zona de lucru a bazei părinte
– Se face legătura între ele, deci se realizează relaţionarea

Există două tipuri de relaţii:


- relaţie de tip "una-la-una"
- relaţie de tip "una-la-mai-multe"

Comanda SET SKIP TO [<alias1>[,<alias2]…] precizează


în care zone de lucru, deci în care baze de date se vor
efectua salturi relative (cu SKIP [<expr_num]). Comanda
transformă relaţiile dintre baza de date curentă şi bazele
identificate prin alias1, alias2…, din relaţii una-la-una, în
relaţii de genul una-la-mai-multe.

ÎNTREBĂRI

Ce este o operaţie de relaţionare a două fişiere baze de date?

Care este diferenţa între un fişier “părinte” şi un fişier


“copil”?

Care sunt etapele pentru realizarea unei relaţionări între


două baze de date?

Ce tipuri de relaţionări cunoaşteţi?

Care este rolul clauzei ADITIVE într-o comandă de


relaţionare?

Care este rolul unei comenzi SKIP?

Să se scrie o secvenţă de program care să realizeze


relaţionarea unei baze părinte cu două baze de date copil?

Care este rolul comenzii SET SKIP TO [<alias1>]?

106
Baze de date SGBD FoxPro

2.13 Introducerea şi extragerea informaţiilor din baze de


date

Sistemul de gestiune FoxPro furnizează ecrane speciale


pentru introducerea rapidă a datelor, permiţând totodată
obţinerea diverselor informaţii legate de conţinutul bazelor de
date, în raport cu formatul specificat, precum şi crearea unor
ecrane utilizator proprii pentru introducerea/extragerea
datelor.

2.13.1 Formate ecran

Introducerea datelor în bazele de date se poate realiza


cu ajutorul unor formate ecran standard (furnizate de sistem,
precum fereastra APPEND, BROWSE, EDIT etc), putându-
se însă crea şi formate ecran proprii utilizatorului, formate
care pot fi accesate de comenzile de introducere a datelor
(APPEND, INSERT). Proiectarea unor astfel de formate
necesită ştergerea unei porţiuni de ecran, a întregului ecran,
afişarea pe ecran a unor texte specifice şi fixarea unor poziţii
pe ecran, în care utilizatorul va putea introduce anumite date
care vor fi apoi salvate în baza de date.

Figura 6. Meniul Screen

Un format ecran se poate crea fie utilizând comanda


CREATE/MODIFY SCREEN (figura 6), situaţie în care se
procedează la o proiectare şi descriere interactiv-vizuala a
acestuia, fie creând un fişier de comenzi (scrise textual de la
tastatura, şi conţinând în special seturi de comenzi SAY,
GET, READ), acest ultim mod de lucru fiind mult mai

107
Baze de date SGBD FoxPro

ineficient şi mai greu de folosit. Extensia specifica fişierelor


format ecran este .SCX (respectiv .SPR pentru fişierul cod
generat).
Fişierele format grupează comenzile necesare pentru a
crea formatul de ecran. Versiunea sa compilată va fi un fişier
format obiect. Fişierele format (.FMT) sunt practic preluate
din SGBD-ul dBase pentru compatibilitate. Fişierul format
.FMT este un fişier ASCII, deci el poate fi creat şi (ca oricare
fişier program) utilizând comenzile: MODIFY COMMAND sau
MODIFY FILE.
Practic un fişier format .fmt poate fi obţinut din fişierul
cod .spr, printr-o simpla modificare a extensiei acestuia. Un
fişier format poate fi activat utilizând comanda : SET
FORMAT TO <nume fişier fmt>.
Noul fişier .fmt astfel obţinut poate fi utilizat ca format
de intrare, pentru operaţia de adăugare într-o bază de date de
exemplu, printr-o secvenţa de program de genul:

USE baza
SET FORMAT TO fisier.fmt
APPEND

Avantajul creării formatelor ecran: pot conţine doar o


parte din câmpurile fişierului bază de date activa; pot avea
formă mai completă (explicită, familiară). După activarea
unui fişier format cu comanda SET FORMAT TO <nume
fişier>, orice comandă de tip APPEND/INSERT va utiliza
acest fişier ca format activ.
Dezactivarea (şi deci revenirea la formatul implicit) se
face cu comanda : SET FORMAT TO.
Observaţie: Un fişier screen/format este legat de structura
unei baze de date. În consecinţa poate fi utilizat doar pentru
formatarea intrărilor în baza de date pentru care a fost creat.
Pentru obţinerea unui fişier format (.fmt), calea cea mai
simplu de urmat conţine următoarele etape:
- deschiderea bazei de date: USE BAZA
- crearea fişierului screen: CREATE SCREEN
<fisier>
- in meniul SCREEN care apare (figura 6) se alege
opţiunea Quick Screen, creându-se un ecran special
cu un format ales (fisier.scx)
- din meniul Program se alege opţiunea GENERATE
şi se generează codul sursa într-un fisier.spr
108
Baze de date SGBD FoxPro

- se schimba extensia fişierului cod sursa .spr în .fmt,


rezultând fişierul format fisier.fmt
- se activează noul formatul: SET FORMAT TO
fisier.fmt

2.13.2 Rapoarte (fişiere REPORT)

FoxPro permite proiectarea diverselor combinaţii de


formate de extragere a datelor (informaţiilor) din bazele de
date. Acestea sunt memorate în fişierul format de ieşire de tip
raport (.FRM) sau fişiere etichete de tip LABEL (.LBL).
Editarea rapoartelor poate fi făcută:
- fie utilizând comanda
CREATE/MODIFY REPORT <nume fişier>

- fie creând un fişier de comenzi de tip @…SAY (cale deloc


recomandată).
Editorul de rapoarte pune la dispoziţia utilizatorului un
ecran de proiectare a rapoartelor, permiţându-se un mod de
lucru interactiv.
Două tipuri de rapoarte pot fi remarcate (obţinute
automat prin selecţia opţiunii Quick Report din meniul Report
- figura 7):
Rapoarte de tip coloană (Column Layout) : Toate
înregistrările bazei de date sunt incluse în raport, numele
câmpurilor se plasează automat în antetul de pagină ca nume
de coloană, putând fi apoi modificate sau şterse (figura 8).
Rapoarte de tip format de ieşire (Form Layout):
Plasează toate câmpurile bazei de date în stânga paginii,
conţinutul câmpului tipărindu-se în dreapta numelui câmpului.

Figura 7. Ecran proiectare fişier REPORT

109
Baze de date SGBD FoxPro

Figura 8. Fişier REPORT

Rapoartele odată proiectate şi salvate vor putea fi


utilizate pentru afişarea informaţiilor din baza de date
utilizând comanda :
REPORT FORM <nume fişier>/ ?
[<scope>][FOR<expr_logica1>]
[WHILE<expr_logica2>]
[PREVIEW][NOCONSOLE]
[TO PRINTER / TO FILE <fisier2>]

<nume fisier> - este numele fişierului raport ( opţiunea ?


permite selectarea numelui fişierului dintr-o lista care apare).
Daca este folosita doar aceasta clauza, raportul va fi trimis
spre ecran în mod scroll, doar ultimul ecran afişat rămânând
vizibil.
PREVIEW - permite afişarea raportului în mod preview, ecran
cu ecran
NOCONSOLE - inhibă afişare pe ecran a raportului (folosita
mai ales când raportul este direcţionat doar spre o imprimanta
sau spre un alt fişier)
TO PRINTER - fişierul raport este trimis la imprimanta
(tipărire directa), dar şi spre ecran daca nu este folosita clauza
NOCONSOLE
TO FILE <fisier2> - raportul (conţinutul lui) este trimis
(salvat) spre un text fisier2.txt

Exemplu:
USE BAZA
** afişare ecran cu ecran
REPORT FORM fis_rap PREVIEW
110
Baze de date SGBD FoxPro

** tipărire, fără afişare pe ecran


REPORT FORM fis_rap TO PRINTER NOCONSOLE

REZUMAT (Paragraf 2.12)

FoxPro furnizează ecrane speciale pentru introducerea


rapidă a datelor, permiţând totodată obţinerea diverselor
informaţii legate de conţinutul bazelor de date, în raport cu
formatul specificat, precum şi crearea unor ecrane utilizator
proprii pentru introducerea/extragerea datelor

Un format ecran se poate crea fie utilizând comanda


CREATE/MODIFY SCREEN, situaţie în care se procedează
la o proiectare şi descriere interactiv-vizuală a acestuia, fie
creând un fişier de comenzi (comenzi SAY, GET, READ)

Un fişier format poate fi activat utilizând comanda:


SET FORMAT TO <nume fişier fmt>

FoxPro permite proiectarea diverselor combinaţii de formate


de extragere a datelor (informaţiilor) din bazele de date
(fişiere REPORT sau LABEL).

Utilizarea unui REPORT în cadrul unui program, pentru


afişarea informaţiilor din baza de date, presupune utilizarea
comenzii :
REPORT FORM <nume fişier>/ ? [<scope>]
[FOR<expr_logica1>][WHILE<expr_logica2>]
[PREVIEW][NOCONSOLE] [TO PRINTER / TO FILE
<fisier2>]

ÎNTREBĂRI

Ce este un fişier FORMAT? Dar un fişier REPORT?

Ce comenzi se folosesc pentru utilizarea în cadrul unui


program a unor fişiere FORMAT, respectiv REPORT?

Comentaţi efectul comenzilor:


REPORT FORM fis_rap PREVIEW
REPORT FORM fis_rap TO PRINTER NOCONSOLE
2.14 Meniuri în FoxPro
111
Baze de date SGBD FoxPro

Meniul reprezintă sistemul de selecţie al funcţionării


unui program sau al unei aplicaţii. Meniul oferă utilizatorului
posibilitatea de a selecta anumite opţiuni (dintr-o listă fixă de
opţiuni), urmând ca în funcţie de opţiunea aleasă să se execute
o serie de instrucţiuni (una sau mai multe, în acest ultim caz,
instrucţiunile fiind grupate într-o procedură). Un exemplu de
meniu este chiar cel al mediului FoxPro, numit “meniu
sistem”. Pe lângă meniul sistem, FoxPro-ul oferă utilizatorului
posibilitatea de a-şi crea meniuri proprii (meniuri utilizator)
incluse în programele aplicaţie.
Un meniu (complet) cuprinde următoarele componente:
- bara meniului, care conţine la rândul ei mai multe
opţiuni (numite opţiuni bara);
- fiecărei opţiuni bara i se poate ataşa câte un
submeniu, la rândul lui format din alte opţiuni.

Cu alte cuvinte, FoxPro-ul permite meniuri cu 2 tipuri :


- meniu bară orizontală (de regula) sau verticală
(format doar din bara meniului şi opţiunile bară ale acesteia,
funcţionând de sine stătător şi permiţând selectarea unor
acţiuni specifice fiecărei opţiuni);
- meniu cu derulare (practic un submeniu cu
opţiunile specifice, putând funcţiona şi independent, fără a fi
ataşat de un meniu bara).
De regulă un meniu proiectat adecvat (meniu complet)
cuprinde, într-un tot unitar, ambele tipuri de meniuri anterior
referite.

Meniul de tip bară are un număr fix de elemente /


opţiuni (de tip verticală sau orizontală). Pentru meniul de tip
bară opţiunile sunt definite de utilizator iar elementele
meniului trebuie şi ele definite înaintea selectării lor.
La definirea unui meniu de tip bară se rezervă un spaţiu
de memorie care conţine numele şi caracteristicile meniului.
Alocarea spaţiului de memorie corespunzător se face în zona
alocată variabilelor de memorie. La un moment dat poate fi
activ un singur meniu.
Meniurile cu derulare sunt meniuri de tip POPUP. În
acest caz, opţiunile meniului pot fi derulate cu săgeţile pentru
a putea fi selectate de către utilizator (opţiunile putând
reprezenta chiar nume de câmpuri sau date conţinute într-un
câmp al unui fişier bază de date deschis, etc.).
112
Baze de date SGBD FoxPro

2.14.1 Comenzi pentru meniuri de tip bară (MENU, PAD)

Definirea meniului -sintaxă:

DEFINE MENU <nume_meniu>


[BAR [AT LINE <exprN1]]
[IN WINDOW <nume>/ IN SCREEN]
[KEY <etichetă_tastă.]
[MARK <exprC1]
[MESSAGE <exprC2>]
[NO MARGIN]
[COLOR <listă_perechi_culori>/COLOR SCHEME
<exprN2>]

Comanda DEFINE MENU defineşte numele meniului


tip bară (<nume_meniu>).
Clauza BAR – se foloseşte pentru a prelua pentru noua
bară de meniuri caracteristicile barei meniului sistem FoxPro:
bara meniu acoperă o singura linie, de la un capăt la altul al
ecranului sau ferestrei; selectarea unei opţiuni bara conduce la
dezactivarea meniului; poziţia pe ecran este stabilita automat
de FoxPro.
Clauza AT LINE - determină afişarea meniului pe linia
cu numărul specificat prin <exprN1>(relativ la fereastră sau la
ecran)
Clauza IN WINDOW – specifică fereastra în care se va
plasa meniul (fereastră anterior definită). În mod implicit dacă
nu există această clauză meniul va fi plasat în fereastra
deschisă curentă iar dacă nu există o fereastră activă meniul va
fi plasat pe ecran. Prezenţa clauzei IN SCREEN specifică
plasarea pe ecran indiferent dacă există sau nu o fereastră
activă.
Clauza KEY - specifică prin desemnarea unei etichete
tastă (spre exemplu CTRL_H) combinaţie de taste care
activează meniul.
Clauza MARK - poate fixa pentru marcarea opţiunilor
meniului un anumit caracter.
Clauza MESSAGE - afişează un text pe ultima linie a
ecranului atât timp cât meniul este activat.
Clauza NO MARGIN - determină eliminarea blank-
urilor dintre opţiunile meniului (în cazul în care la definirea
opţiunilor nu se specifică poziţia acestora). În mod implicit,
113
Baze de date SGBD FoxPro

opţiunile bara meniu vor fi afişate una după alta, separate prin
blank-uri.
Clauzele COLOR <listă_perechi_culori>/COLOR
SCHEME <exprN2> au fost deja tratate.
Observaţie: Definirea meniului rămâne în memorie până la
ştergerea acestuia cu una din comenzile RELEASE MENUS,
CLEAR MENUS, asupra cărora se va reveni.

Pentru a defini opţiunile unui meniu de tip bară se


foloseşte comanda următoare DEFINE PAD cu sintaxa
următoare:

DEFINE PAD <nume_opţiune_bară>


OF <nume_meniu_principal>
PROMPT <expresieC1>
[AT <linie> <coloană>]
[BEFORE <opţiune_bară2>/
AFTER <opţiune_bară3>]
[KEY <etichetă> [,<expresieC2]]
[MARK <expresieC3>
[SKIP [FOR <expresie_logică1>]]
[MESSAGE <expresieC4>]
[COLOR <listă_perechi_culori>/
COLOR SCHEME <exprN2>]

Comanda defineşte numele opţiunii meniului bară şi


textul care se afişează pentru opţiunea respectivă, prin şirul de
caractere care urmează după clauza PROMPT
(<expresieC1>).

Exemplu:
DEFINE MENU principal
DEFINE PAD opţiune1 OF principal PROMPT;
“Editare”
DEFINE PAD opţiune2 OF principal PROMPT;
“Tipărire”; KEY CTRL+T, ‘^T’
DEFINE PAD opţiune3 OF principal PROMPT;
“Căutare” BEFORE opţiune2
** sau AFTER opţiune1
ACTIVATE MENU principal

114
Baze de date SGBD FoxPro

Figura 9. Meniu realizat

În figura 9 este prezentat meniul bara care va fi afişat pe


ecran prin execuţia secvenţei de program anterioara ( asupra
comenzii ACTIVATE MENU principal se va reveni).
Clauza PROMPT – permite şi fixarea unei taste diferite
de selectare a opţiunii bară prin utilizarea caracterului ‘\<’ în
şirul de caractere care urmează opţiunii PROMPT, înaintea
caracterului care va desemna opţiunea :
‘\<Editare’ (tastă ‘caldă’ E) ‘E\<ditare’ (tastă ‘caldă’ d)

Clauza AT <linie, coloană> – precizează coordonate de


afişare a testului (PROMPT-ului) aferent opţiunii bară.
Dacă lipseşte AT opţiunile vor fi afişate pe o bară
orizontală, începând cu colţul stânga sus al ecranului , ordinea
de apariţie a opţiunii meniului de tip bară fiind dată de ordinea
de definire a acestora. În cazul în care se doreşte inversarea
unei opţiuni în cele anterior definite se foloseşte una din
clauzele BEFORE sau AFTER (vezi exemplul anterior).
Clauza KEY – specifică, prin desemnarea unei etichete
tastă, combinaţia de taste care activează direct opţiunea
meniu. Şirul de caractere “<expC2> specifică un text care va
fi pus în dreapta textului PROMPT al opţiunii bara, precizând
combinaţia de taste prin care se asigura o cale directa de
selectare a acesteia.
Clauza SKIP – permite obţinerea unei condiţii de
accesare a unei anumite opţiuni folosind [<expr_logică1>]. În
cazul în care lipseşte clauza FOR dar este prezentă clauza
SKIP respectiva opţiune nu poate fi accesată.
Celelalte opţiuni sunt similare ca semnificaţie cu cele deja
tratate la comanda DEFINE MENU.

Exemplu :
115
Baze de date SGBD FoxPro

Se consideră următoarea bară de meniuri :

Actualizare Stergere * Adăugare ^N Listarea Vizualizare Ieşire^x

DEFINE MENU principal


DEFINE PAD actual OF principal PROMPT;
‘/<Actualizare’;
MESSAGE “Permite modificarea datelor”;
DEFINE PAD adăugare OF principal PROMPT;
/<Adăugare’,’MARK ‘*’ KEY CTRL+N, ‘^N’
DEFINE PAD stergere OF principal PROMPT;
‘ştergere’SKIP BEFORE adăugare
DEFINE PAD listare OF principal PROMPT;
‘\<Listare’
DEFINE PAD vizualizare OF principal;
PROMPT ‘\<Vizualizare’
DEFINE PAD ieşire OF acţiune;
PROMPT’\<Ieşire’ KEY CTRL+X, ‘^x’

Rularea secvenţei de program de mai sus nu produce


nici un rezultat vizibil pe ecran, toate comenzile realizând
doar definirea (în memorie) a meniului (inclusiv elementele
constitutive). Anticipând, pentru a afişa meniul pe ecran şi
pentru a ataşa nişte acţiuni concrete opţiunilor acestuia este
necesara completarea codului cu următoarea secvenţa de
comenzi (in condiţiile existentei unei baze de date deschise):

** apel comenzi prin selecţie opţiune


ON SELECTION PAD actual OF principal
BROWSE
ON SELECTION PAD adăugare OF principal
APPEND
** apel procedura prin selectie optiune
ON SELECTION PAD listare OF principal;
DO LISTARE
ON SELECTION PAD vizualizare OF principal;
LIST
** iesire din meniu
ON SELECTION PAD iesire OF principal;
DEACTIVATE MENU
** activare meniu
ACTIVATE MENU principal
** stergere meniu din memorie
CLEAR MENUS

116
Baze de date SGBD FoxPro

Pentru precizarea unei anumite acţiuni, fixată prin


selecţia unei opţiuni de tip bară, se utilizează o comandă de
tipul ON SELECTION PAD. Acţiunea fixată poate să fie o
comandă oarecare, fie o comandă de activare a altui meniu.
Sintaxa comenzii este următoarea:

ON SELECTION PAD <nume_opţiune>


OF <nume_meniu principal>
[<instructiune>]
Instrucţiunea poate fi la rândul ei un apel de proceduri
(vezi exemplul anterior). În lipsa clauzei <instrucţiune>, la
selecţia opţiuni PAD respective nu se va executa nimic.
Comanda ACTIVATE MENU are sintaxa:

ACTIVATE MENU <nume_meniu> [NOWAIT]


[PAD <nume_optiune_bara>]

Efectul unei astfel de comenzi (plasata după o serie de


comenzi de genul DEFINE şi ON SELECTION) consta în
afişarea şi activarea bare de meniu <nume_meniu> (cu
opţiunile bara PAD aferente, ataşate acesteia), selectând iniţial
prima opţiune bara. Daca se doreşte selectarea iniţiala a altei
opţiuni bara, se foloseşte clauza PAD pentru specificarea
explicita a numelui acesteia (prin parametrul
<nume_optiune_bara>).
Clauza NOWAIT permite continuarea execuţiei
programului după afişarea meniului (in mod normal,
programul se opreşte aşteptând selectarea unei opţiuni). Într-
un astfel de caz, bara de meniu va rămâne activată,
utilizatorului avînd posibilitatea selectării unei opţiuni bară ori
de câte ori programul aşteaptă introducerea unor date de la
tastatură.
După execuţia unei comenzi ACTIVATE MENU,
programul nu trece la execuţia comenzii imediat următoare,
aşa cum ar presupune o parcurgere secvenţiala a
instrucţiunilor din program. În acel moment, controlul este
predat comenzilor ON SELECTION care, în funcţie de
opţiunile selectate, vor lansa în execuţie alte comenzi sau
proceduri. Se poate privi o secţiune de program cuprinsa intre
o comanda DEFINE MENU… şi ACTIVATE MENU…, ca un
program principal din care sunt lansate diferite operaţii,
revenirea din acestea făcându-se tot timpul cu repredare

117
Baze de date SGBD FoxPro

controlului în meniu. Ieşirea din acest circuit este asigurata de


o comanda DEACTIVATE MENU <nume_meniu>.

O formă specifică de definire a unei acţiuni la


‘selectarea’ unei bare de meniu (PAD) este cea prin care se
activează un alt meniu (MENU) sau submeniu (POPUP). O
astfel de acţiune se realizează cu comanda:

ON PAD <nume_opţiune>
OF <nume_meniu principal>
[ACTIVATE POPUP <nume_submeniu>]
[ACTIVATE MENU <nume_meniu_secundar>]

Practic în acest caz nu se realizează o selecţie efectiva a


opţiunii bara (prin tastare ENTER pe aceea opţiune bara PAD),
submeniul sau meniul secundar fiind activat la o simpla
deplasare sau trecere a prompter-ului deasupra acelei opţiuni
PAD.

O comanda de genul ON [SELECTION] se plasează


într-un program intre comenzile de definire DEFINE şi
comanda de activare a meniului ACTIVATE.
Celelalte comenzile de tip ON SELECTION sunt
următoarele:

ON SELECTION MENU <nume_meniu>/ALL


[<instructiune>]

La alegerea oricărei opţiuni bara din bara de meniu


<nume_meniu> (sau a oricărei bare de meniu definita când se
foloseşte clauza ALL) se va executa <instructiune>.

ON SELECTION POPUP <nume_submeniu> / ALL


[<instructiune>]

ON SELECTION BAR <expN>> OF <nume_submeniu>


[<instructiune>]

Asupra acestor doua comenzi se va revenii cu explicaţii


în paragraful de tratare a meniurilor cu derulare.
Comanda de dezactivare a unui meniu de tip bară este :

118
Baze de date SGBD FoxPro

DEACTIVATE MENU

Comanda DEACTIVATE MENU nu şterge meniului din


memorie, realizând doar o ştergere a acestuia de pe ecran
(dezactivarea acestuia). Meniul poate fi oricând reactivat cu o
comanda ACTIVATE MENU <nume_meniu>, ne mai fiind
necesara o definire a acestuia.
Comanda DEACTIVATE MENU nu are nici un alt
parametru, ne fiind necesara precizarea meniului care va fi
dezactivat deoarece, la un moment dat poate fi activ un singur
meniu (MENU). În momentul execuţie unei astfel de comenzi,
se iese din execuţia ‘buclei’ meniu şi se va executa prima
comanda care urmează după comanda de activare a meniului
(ACTIVATE MENU <nume_meniu>). De aceea, de regula,
la selectarea opţiunii IESIRE dintr-un program (prevăzut cu
un meniu) se foloseşte o comanda de genul:

ON SELECTION PAD iesire OF principal;


DEACTIVATE MENU

Ţinând cont de cele precizate, după o comandă de


activare meniu (ACTIVATE MENU) vor urma comenzi
specifice de încheiere a aplicaţiei: ştergerea meniului din
memorie, închiderea bazelor de date etc.
După cum s-a mai precizat, ştergerea definitivă a
meniului (din memorie) se face cu una din comenzile:
CLEAR MENUS
RELEASED MENUS [<lista meniri>][EXTENDED]

Înainte de utilizarea unei comenzi de ştergere de acest


tip, meniul trebuie dezactivat. Comanda CLEAR MENUS
elimină toate meniurile tip bară din memorie. În cazul
comenzii RELEASED MENUS, clauza <lista meniuri>
permite ştergerea mai multor meniuri ale căror definiţii sunt în
memorie (dintre acestea doar unul fiind activ), iar clauza
EXTENDED se foloseşte pentru înlăturarea, pe lângă bara
meniu, şi a elementelor ataşate acesteia: opţiuni bara,
submeniuri etc.
În multe situaţii, la selectarea unei anumite opţiuni bara
se doreşte şi o “ascundere” a meniului pe parcursul execuţiei
unei anumite acţiuni (date de o comanda sau o procedura),
urmând ca la terminarea acţiunii, meniul sa fie reafişat pe
119
Baze de date SGBD FoxPro

ecran. Comenzile utilizate pentru “mascarea” (ascunderea),


respectiv reafişarea pe ecran a unui meniu sunt următoarele:

HIDE MENU <nume_meniu1>[,<nume_meniu2>…]


/ ALL [SAVE]

SHOW MENU <nume_meniu1>[,nume_meniu2>…]


/ALL [PAD <nume_opţiune_bară>] [SAVE]

Comanda HIDE MENU ascunde barele de meniu


specificate în lista (de regula, o bara de meniu) sau toate
barele de meniu definite (clauza ALL). Cu alte cuvinte,
înlătura aceste meniuri de pe ecran, fără a le elimina din
memorie. Clauza SAVE se foloseşte pentru a păstra totuşi o
simpla imagine a barei de meniu pe ecran şi după ascunderea
acesteia, ştergerea imaginii (inactive) făcându-se cu CLEAR.
Ascunderea unui meniu nu are aceeaşi semnificaţie cu
dezactivarea lui. Un meniu ascuns, rămâne rezident în
memorie şi poate fi oricând reafişat cu ajutorul comenzii
SHOW MENU.
Cele doua comenzi HIDE MENU şi SHOW MENU au o
acţiune complementară: ascunderea meniului, respectiv
reafişarea lui.
Opţiunea suplimentară:
[PAD<nume_opţiune_bară>]
permite afişarea unei opţiuni bară ca fiind selectate în
momentul afişării meniului. Clauza SAVE aferentă comenzii
SHOW MENU, permite reţinerea pe ecran a unei imagini a
meniului, fără activarea acestuia.

Exemplu:
set talk off
USE baza
CLEAR
** definire meniu
DEFINE MENU meniu1 MESSAGE "Meniu ;
principal"
DEFINE PAD optiune1 OF meniu1;
PROMPT "CAUTARE"
DEFINE PAD optiune2 OF meniu1;
PROMPT "TIPARIRE";
MESSAGE "Tiparire - porniti imprimanta !"
DEFINE PAD optiune3 OF meniu1;
PROMPT "SFIRSIT"
120
Baze de date SGBD FoxPro

** precizare acţiuni
ON SELECTION pad optiune1 OF meniu1;
DO proc1
ON SELECTION pad optiune2 OF meniu1; DO
proc2
ON SELECTION pad optiune3 OF meniu1
DEACTIVATE MENU
** activare meniu
ACTIVATE MENU meniu1
** aici se sare la execuţia comenzii DEACTIVATE MENU
** (Ieşire din program) ştergere meniu şi
** închidere bază de date
CLEAR MENUS
USE
RETURN

** proceduri specifice acţiunilor selectate

** procedura căutare (cu ascundere meniu)


PROCEDURE proc1
HIDE MENU meniu1
@ 1,1 SAY "Numele: " GET var;
DEFAULT SPACE(20)
READ
LOCATE FOR UPPER(NUME)=UPPER(var)
DISPLAY
CLEAR
SHOW MENU meniu1
RETURN

** procedură tipărire
PROCEDURE proc2
LIST TO PRINTER
WAIT "Tiparire terminata. Apasa o tasta… "
RETURN

2.14.2 Comenzi pentru meniuri cu derulare (POPUP, BAR)

Meniurile POPUP sunt meniuri verticale, ale căror


elemente-opţiuni pot fi: elemente definite de utilizator,
informaţii conţinute în înregistrările unui fişier bază de date,
denumiri de fişiere conţinute pe disc, câmpurile din structura
unui fişier bază de date. Un meniu POPUP poate funcţiona ca
meniu vertical independente, de sine stătător, sau poate fi

121
Baze de date SGBD FoxPro

ataşat unei opţiuni bară (PAD) aferente unui meniu bară


(MENU - meniu principal), caz în care îndeplineşte rolul unui
submeniu. Acest din urma caz este cel mai frecvent întâlnit.
Sintaxa comenzii de definire a unui submeniu POPUP:

DEFINE POPUP <nume_popup>


[FROM <linie1>, <col1>] [TO<linie2>,<col2>]
[IN [WINDOW] <nume_fereastra>/ IN SCREEN]
[FOOTER <expC1>] [TITLE <expC2>]
[KEY <etichet_tasta>]
[MARGIN][MARK <exprC3>]
[MESSAGE <exprC4>][MOVER] [MULTI]
[PROMPT FIELD <expr > / PROMPT FILES
[LIKE <mască>]/
PROMPT STRUCTURE]
[RELATIVE]
[SCROLL]
[SHADOW]
[COLOR <listă_perechi_culori>
| COLOR SCHEME <expN1]

Numele submeniului este dat de parametrul


<nume_popup>.
Clauzele FROM şi TO, definesc poziţia şi practic
dimensiunea meniului (FROM defineşte poziţia colţului din
stânga sus, iar TO - poziţia colţului din dreapta jos. Dacă
clauza FROM lipseşte, submeniul va fi plasat în coltul din
stânga sus, de coordonate 0,0. Dacă clauza TO lipseşte,
dimensiunea submeniului va fi calculata automat.
Clauza IN [WINDOW] stabileşte fereastra în care va fi
amplasat submeniul. Clauza IN SCREEN este implicită,
arătând că ieşirea (afişarea submeniului) este direcţionată spre
ecran.
Clauza MARGIN specifică separarea opţiunilor de
chenar printr-un spaţiu suplimentar, spaţiu în care, la stânga
vor fi afişate marcaje, iar la dreapta se va afişa (când este
cazul) o săgeata indicând ieşirea spre un alt submeniu.
Clauza MOVER permite rearanjarea opţiunilor într-un
meniu POPUP, când acesta este activat. În prezenţa acestei
clauze, opţiunile submeniului sunt însoţite în dreapta lor de
caracterul '|', care specifică posibilitatea de mutare a lor.

122
Baze de date SGBD FoxPro

Mutarea unei opţiuni se face cu mouse-ul sau cu combinaţia


de taste CTRL+|.
Clauza MULTI permite selectarea mai multor opţiuni
(utilizând combinaţia SHIFT+ENTER, apoi apăsând SHIFT şi
prin deplasare cu săgeţile direcţionale, se pot selecta mai
multe opţiuni).
Clauzele MULTI şi PROMPT nu pot fi utilizate simultan.
Clauza PROMPT determină tipul opţiunilor meniului
POPUP şi anume:
- PROMPT FIELD <expr> - elementele meniului
sunt informaţii din înregistrările unui fişier bază de date, unde
<expr> specifică un nume de câmp sau poate fi o expresie
formată din nume de câmpuri ale bazei de date;
- PROMPT FILES - opţiunile meniului sunt nume de
fişiere de pe disc, dintr-un anumit director. Clauza LIKE
permite specificarea opţionala a unei măşti (de exemplu LIKE
c:\*.dbf).
- PROMPT STRUCTURE - opţiunile submeniului sunt
câmpurile bazei de date active
Clauza RELATIVE influenţează ordinea şi poziţia în
meniul POPUP a opţiunilor definite cu DEFINE BAR. În
prezenţa clauzei sunt suprimate spaţiile libere lăsate pentru
opţiunile nedefinite. Dacă clauza lipseşte, poziţia în submeniu
a unei opţiuni va fi dată de numărul opţiunii din comanda
DEFINE BAR (pentru opţiunile nedefinite lăsîndu-se spaţiu
liber).
Clauza SCROLL permite afişarea unei bare verticale de
defilare pe latura dreapta a chenarului submeniului, bara
vizibilă atunci când nu toate opţiunile submeniului pot fi
afişate în interiorul chenarului acestuia.
Cauza SHADOW determină un efect de umbrire.
Clauzele TITLE şi respectiv FOOTER determina
afişarea unui mesaj de titlu respectiv de subsol pentru
submeniu. Efectele clauzelor KEY, MARK, MESSAGE şi
COLOR au fost deja tratate la comanda DEFINE PAD.

Exemplu:
USE baza
DEFINE POPUP submen1 FROM 15,15 MARGIN;
PROMPT STRUCTURE
DEFINE POPUP submen2 FROM 15,25 MARGIN;
PROMPT FILE
ACTIVATE POPUP submen1
123
Baze de date SGBD FoxPro

ACTIVATE POPUP submen2


CLEAR POPUPS

Definirea opţiunilor bară ale unui meniu POPUP se face


folosind comanda DEFINE BAR (în cazul absenţei clauzei
PROMPT din comanda DEFINE POPUP):

DEFINE BAR <exprN1>/ <nume_optiune_sistem>


OF <nume_meniu_popup> PROMPT <exprC1>
[BEFORE <exprN2>AFTER <exprN2>]
[KEY <etichetă_tastă> [, <expC2>]]
[MARK <exprC3>]
[MESSAGE <exprC4>][SKIP [FOR <exprL>]]
[COLOR <listă_perechi_culori>
COLOR SCHEME <exprN4>]

Comanda de definire a opţiunilor unui meniu POPUP


este asemănătoare cu comanda de definire a opţiunilor
meniului bară PAD.
Pentru fiecare opţiune se utilizează câte o comandă
DEFINE BAR.
Referirea la o opţiune a meniului POPUP nu se face
printr-un nume ataşat acestuia, ci printr-un număr [exprN1>],
care reprezintă numărul de ordine al opţiunii în meniul
POPUP. Opţiunile submeniului SYSTEM al FoxPro-ului pot fi
opţiuni ale meniului POPUP, dacă se specifică acest lucru
(parametrul <nume_optiune_sistem>).
Clauza PROMPT specifică textul care va fi afişat pe
poziţia opţiunii în submeniul respectiv (denumit prin
<nume_meniu_popup>). Pentru desemnarea unei taste directe
de selectare, în şirul text, aceasta este precedată de “\<”,iar
utilizarea doar a caracterului ”\” înaintea textului, desemnează
o opţiune dezactivată. Daca parametrul <exprC1> din clauza
PROMPT este de forma '\-', pe poziţia opţiunii respective se
introduce o linie separatoare a opţiunilor (permiţând practic o
separare logica a acestora).
Dacă clauza MARK apare atât la definirea meniului
POPUP, cât şi la definirea opţiunii bară BAR, se ia în
considerare caracterul de marcare din comanda DEFINE
BAR.

124
Baze de date SGBD FoxPro

Exemplu:
DEFINE POPUP meniu FROM 5,5
DEFINE BAR 1 OF meniu;
PROMPT \<Modificare';
MESSAGE 'Modificare date'
DEFINE BAR 2 OF meniu PROMPT '\<Adaugare';
MESSAGE 'Adaugare date'
DEFINE BAR 3 OF meniu PROMPT '\<Stergere';
MESSAGE 'Stergere date'
DEFINE BAR 4 OF meniu PROMPT '\-'
DEFINE BAR 5 OF meniu PROMPT '\<Listare';
MESSAGE 'Vizualizare ecran'
DEFINE BAR 6 OF meniu PROMPT 'Ti\<parire';
MESSAGE 'Imprimare'
ACTIVATE POPUP meniu
CLEAR POPUPS

Se poate observa, pe baza


exemplului anterior (figura 10),
ca meniu cu derulare (POPUP),
însoţit de opţiunile lui (BAR),
poate funcţiona în mod
independent, ca un meniu de
sine stătător.
Figura 10 Meniu POPUP Alte comenzi specifice
unui meniu POPUP (şi opţiunilor
BAR) sunt:

- activare (afişare pe ecran a meniului POPUP şi a


opţiunilor BAR):
ACTIVATE POPUP <nume_popup>
- dezactivare (ştergere de pe ecran):
DEACTIVATE POPUP
- ştergere din memorie:
CLEAR POPUPS

RELEASED POPUPS [<lista_submeniuri>]


[EXTENDED]

RELEASED BAR <expN/ALL> OF


<nume_popup>

125
Baze de date SGBD FoxPro

Prin analogie, modul de acţiune al acestor comenzi este


identic cu al comenzilor similare pentru meniurile MENU şi
PAD, descrise în paragraful anterior.
În plus, comanda CLEAR ALL îndepărtează toate
barele de meniu (MENU,PAD) sau submeniu (POPUP, BAR)
din memorie şi de pe ecran.
Comanda:

ON SELECTION POPUP <nume_popup>/ALL


[<instructiune>]

determină executarea instrucţiunii <instructiune> la fiecare


alegere a unei opţiuni (BAR) din submeniul <nume_popup>,
sau din orice alt submeniu definit, dacă se foloseşte clauza
ALL.
Specificarea acţiunii care trebuie să aibă loc la selecţia
unui anumite opţiuni BAR se realizează cu comanda:

ON SELECTION BAR <exprN> OF<meniu_popup>


[<comanda>]

Dacă lipseşte <comanda>, opţiunea se eliberează de


orice comandă.
Forma ON BAR a acestei comenzi de selecţie se
utilizează mai ales în cazul în care la selecţia opţiunii se
doreşte activarea unui submeniu, fie de tip POPUP fie de tip
bară MENU.

ON BAR <exprN> OF <nume_meniu_popup1>


[ACTIVATE POPUP <nume_m_popup2>/
ACTIVATE MENU <nume_meniu>]

Toate comenzile de tip ON [SELECTION] BAR se


vor plasa între comenzile DEFINE POPUP şi ACTIVATE
POPUP.

După cum s-a mai precizat, comanda pentru activarea


unui meniu POPUP este ACTIVATE POPUP având sintaxa:

ACTIVATE POPUP <nume_m_popup>


[AT <L1>, <C2>]
[BAR <exprN>] [NOWAIT] [REST]

126
Baze de date SGBD FoxPro

comanda va activa şi va afişa meniul POPUP specificat la


coordonatele specificate în clauza AT în ecran şi în fereastră,
sau, în absenţa clauzei în poziţia specificată la definirea
meniului POPUP. Dacă este prezentă clauza BAR, iniţial se va
selecta opţiunea cu numărul <exprN>
Clauza REST se foloseşte pentru meniu POPUP definit
cu clauza PROMPT FIELD, determinând selectarea iniţială a
opţiunii corespunzătoare înregistrării curente din fişierului
bază de date. Dacă aceasta opţiune lipseşte va fi selectata
opţiunea BAR corespunzătoare primei înregistrări din baza de
date.
Clauza NOWAIT determina continuarea execuţiei
programului cu submeniul activat (aceeaşi semnificaţie cu cea
a clauzei NOWAIT de la comanda ACTIVATE MENU).

Ca şi în cazul meniurilor bara (MENU, în multe


situaţii, la selectarea unei anumite opţiuni BAR se doreşte şi o
“ascundere” a submeniului pe parcursul execuţiei unei
anumite acţiuni (date de o comanda sau o procedura), urmând
ca la terminarea acţiunii, submeniul POPUP (cu opţiunile
BAR aferente) sa fie reafişat pe ecran. Comenzile utilizate
pentru “mascarea” (ascunderea), respectiv reafişarea pe ecran
a unui submeniu POPUP sunt următoarele:
- ascundere meniu POPUP specificat, sau toate
meniurile POPUP definite (fără însă a le elimina din
memorie):
HIDE POPUP <nume_meniu_popup1>
[nume_meniu_popup2>/ALL]
[SAVE]

- afişare meniu POPUP:


SHOW POPUP <nume_meniu_popup1>
[,<nume_meniu_popup2>/ALL]
[SAVE]

Se pot ascunde/afişa mai multe meniuri POPUP (sau


chiar toate folosind clauza [ALL]).
Clauza SAVE păstrează pe ecran imaginea meniului,
imagine care poate fi ştearsă cu comanda CLEAR.

127
Baze de date SGBD FoxPro

Exemplu:
USE baza
DEFINE POPUP meniu FROM 2,1
DEFINE BAR 1 OF meniu;
PROMPT '\<Modificare'
DEFINE BAR 2 OF meniu PROMPT '\<Afisare';
MESSAGE 'Afisare cu filtrare'
DEFINE BAR 3 OF meniu PROMPT '\<Iesire';
** definire acţiune opţiuni
ON SELECTION BAR 1 OF meniu BROWSE
ON SELECTION BAR 2 OF meniu DO proc
ON SELECTION BAR 3 OF MENIU DEACTIVATE
POPUP
ACTIVATE POPUP meniu
CLEAR POPUPS
USE
RETURN

** procedura pentru opţiunea Afişare


PROCEDURE proc
HIDE POPUP meniu
@ 2,3 SAY “Afisare pentru virsta >”;
GET var DEFAULT 0 PICTURE “99”
READ
SET FILTER TO virsta>var
BROWSE
SHOW POPUP meniu
RETURN

După cum am mai menţionat, un meniu cu derulare


(POPUP) împreună cu opţiunile lui (BAR) poate funcţiona ca
un meniu independent (vezi exemplul anterior). De asemenea,
în multe din formulările anterioare pentru un meniu POPUP
am folosit şi titulatura de submeniu. Aceasta titulatura este
justificata prin faptul ca, de regula, în cadrul unui aplicaţii
complexe se creează un meniu complet. Printr-un meniu
complet se înţelege un meniu bara MENU, căruia îi sunt ataşate
mai multe bare opţiuni (PAD), iar unor dintre acestea le sunt
ataşate la rândul lor submeniuri POPUP cu mai multe opţiuni
BAR. Exemplul prezentat în continuare se doreşte a edifica
conceptul de meniu complet (format din MENU,PAD,POPUP,
BAR).

128
Baze de date SGBD FoxPro

Exemplu:
set talk off
clear
use baza1
** definire meniu bară
define menu functii
define pad submeniu of functii;
prompt "\<Submeniu"
define pad informatii of functii;
prompt "\<Informatii"
define pad iesire of functii;
prompt "I\<esire"

** definire acţiuni opţiuni meniu bară


on pad submeniu of functii;
activate popup submen
on selection pad informatii of functii;
do inform
on selection pad iesire of functii
deactivate menu

** definire submeniu POPUP cu opţiuni BAR


define popup submen margin
define bar 1 of submen prompt '\<Adaugare'
define bar 2 of submen;
prompt '\<Vizualizare'
define bar 3 of submen prompt '\<Cautare'
define bar 4 of submen prompt '\<Stergere'
define bar 5 of submen;
prompt '\<Informatii'

** definire acţiuni opţiuni BAR ale submeniului POPUP


on selection bar 1 of submen append
on selection bar 2 of submen browse
on selection bar 3 of submen do proc3
on selection bar 4 of submen do proc4
on selection bar 5 of submen do proc5

** activare meniu
activate menu functii
clear popups
clear menus
use
return

129
Baze de date SGBD FoxPro

** proceduri
procedure inform
hide menu
@ 1,1 say "se pot scrie orice fel de;
informatii"
wait
clear
show menu functii
return

procedure proc3
hide menu functii
hide popup submen
clear
aaaa=" "
@ 2,2 say "introduceti numele" get aaaa
read
locate all for produs=aaaa
if found()=.T.
browse redit
else
@ 10,10 say "Nu exista"
wait
endif
clear
show menu functii
show popup submen
return

** procedurile proc4 şi proc5 nu sunt prezentate

Figura 11 Meniu complet

130
Baze de date SGBD FoxPro

2.14.3 Funcţii asociate meniurilor

În continuare vor fi prezentate câteva dintre principalele


funcţii utilizate pentru lucrul cu meniuri, cu ajutorul acestora
putându-se obţine informaţii despre:
- opţiunea bară aleasă dintr-o bară de meniu sau
opţiunea aleasă dintr-un submeniu
- submeniul activ
- numărul de opţiuni bară a unei bare de meniu sau
numărul de opţiuni dintr-un submeniu
- textul asociat unei opţiuni bară sau unei opţiuni
Funcţii:
Funcţia MENU ( ) - evaluarea ei are ca rezultat un şir
de caractere conţinând numele barei de meniu active (cu litere
majuscule). Un şir vid va fi returnat de funcţie dacă nu există
o bară de meniu activă.
Ultima opţiune bară aleasă din bara de meniu activă va
fi dată, printr-un şir de caractere returnat de funcţia PAD ( ).
Numele opţiunii bară respective va fi trecut la
majuscule, în şirul returnat de funcţie. În cazul când nu există
o bară de meniu activă, funcţia va returna şirul nul.
Funcţia POPUP ( ) returnează un şir de caractere
reprezentând numele submeniului activ. Acest şir va fi vid
dacă nu este activat nici un submeniu.
Pentru submeniuri (POPUP), funcţia cu care se află
opţiunea aleasă este funcţia BAR ( ).
Valoarea returnată de funcţie va fi de tip numeric,
reprezentând numărul ultimei opţiuni alese din submeniul
activ. În cazul când nu există nici un submeniu activ sau s-a
ieşit din submeniu cu tasta Escape, funcţia va returna
valoarea 0.
Fiecare opţiune bară (PAD) şi fiecare opţiune BAR are
asociat câte un text care este afişat pe ecran în locul opţiunii
respective şi este definit prin clauza PROMPT a comenzilor
DEFINE PAD şi DEFINE BAR.
Funcţia PROMPT( ) returnează un şir de caractere
conţinând textul ultimei opţiuni bară aleasă dintr-o bară de
meniu sau ultimei opţiuni aleasă dintr-un submeniu. Funcţia
PROMPT () va returna şirul vid dacă nu există nici o bară de
meniu şi nici un submeniu activ sau dacă s-a folosit tasta
Escape la ieşirea din meniul respectiv.

131
Baze de date SGBD FoxPro

REZUMAT (Paragraf 2.14)

Meniul reprezintă sistemul de selecţie al funcţionării unui


program sau al unei aplicaţii, oferind utilizatorului
posibilitatea de a selecta anumite opţiuni (dintr-o listă fixă de
opţiuni), urmând ca în funcţie de opţiunea aleasă să se
execute o serie de instrucţiuni.

FoxPro-ul permite meniuri cu 2 tipuri :


- meniu bară orizontală (de regula) sau verticală (format doar
din bara meniului şi opţiunile bară ale acesteia, funcţionând
de sine stătător şi permiţând selectarea unor acţiuni specifice
fiecărei opţiuni);
- meniu cu derulare (practic un submeniu cu opţiunile
specifice, putând funcţiona şi independent, fără a fi ataşat de
un meniu bara).

De regulă un meniu proiectat adecvat (meniu complet)


cuprinde, într-un tot unitar, ambele tipuri de meniuri anterior
referite.

La un moment dat poate fi activ un singur meniu (de acelaşi


tip).

Utilizarea unui meniu implică următoarele etape:


- definirea meniului
- definirea opţiunilor meniului
- definirea operaţiilor efectuate la selecţia opţiunilor
- activarea meniului

Definirea unui meniu de tip bară se face cu comanda:


DEFINE MENU <nume_meniu>
[BAR [AT LINE <exprN1]]
[IN WINDOW <nume>/ IN SCREEN]
[KEY <etichetă_tastă.]
[MARK <exprC1]
[MESSAGE <exprC2>]
[NO MARGIN]
[COLOR <listă_perechi>/COLOR SCHEME <exprN2>]

132
Baze de date SGBD FoxPro

Definirea opţiunilor unui meniu de tip bară se face cu


comanda
DEFINE PAD <nume_opţiune_bară>
OF <nume_meniu_principal>
PROMPT <expresieC1>
[AT <linie> <coloană>]
[BEFORE <opţiune_bară2>/
AFTER <opţiune_bară3>]
[KEY <etichetă> [,<expresieC2]]
[MARK <expresieC3>
[SKIP [FOR <expresie_logică1>]]
[MESSAGE <expresieC4>]
[COLOR <listă_perechi_culori>/
COLOR SCHEME <exprN2>]

Pentru comenzile anterioare, cele mai utilizate forme


sintactice sunt:
DEFINE MENU <nume_meniu>
DEFINE PAD <nume_opţiune_bară> OF <nume_meniu>;
PROMPT <expresieC1> MESSAGE <expresieC2>

Pentru precizarea unei anumite acţiuni, fixată a fi executată


prin selecţia unei opţiuni de tip bară, se foloseşte comanda:
ON [SELECTION] PAD <nume_opţiune>
OF <nume_meniu principal> [<instrucţiune>]

Comanda de activare a unui meniu bară are sintaxa:


ACTIVATE MENU <nume_meniu> [NOWAIT]
[PAD <nume_opţiune_bara>]

Comanda de dezactivare a unui meniu de tip bară este :


DEACTIVATE MENU

Ştergerea definitivă a unui meniu de tip bară (din memorie) se


face cu una din comenzile:
CLEAR MENUS
RELEASED MENUS [<lista meniri>][EXTENDED]

Comenzile utilizate pentru “mascarea” (ascunderea),


respectiv reafişarea pe ecran a unui meniu bară sunt
următoarele:
HIDE MENU <nume_meniu1>[,<nume_meniu2>…]
/ ALL [SAVE]

133
Baze de date SGBD FoxPro

SHOW MENU <nume_meniu1>[,nume_meniu2>…]


/ALL [PAD <nume_opţiune_bară>] [SAVE]

Meniurile POPUP sunt meniuri verticale, ale căror elemente-


opţiuni pot fi: elemente definite de utilizator, informaţii
conţinute în înregistrările unui fişier bază de date, denumiri
de fişiere conţinute pe disc, câmpurile din structura unui fişier
bază de date.

O sintaxă minimală (uzual folosită) a comenzii folosite pentru


definirea unui meniu POPUP este:
DEFINE POPUP <nume_popup>
[FROM <linie1>, <col1>] [TO<linie2>,<col2>]
[MARGIN]
[PROMPT FIELD <expr > / PROMPT FILES
[LIKE <mască>]/ PROMPT STRUCTURE]

O definire minimal-uzuală a opţiunilor unui meniu POPUP (în


cazul absenţei clauzei PROMPT din comanda DEFINE
POPUP) se poate face cu comanda:
DEFINE BAR <exprN1>/ <nume_opţiune_sistem>
OF <nume_meniu_popup> PROMPT <exprC1>
[MESSAGE <exprC4>]

Activarea (afişare pe ecran a meniului POPUP şi a opţiunilor


BAR): ACTIVATE POPUP <nume_popup>

Dezactivarea (ştergerea de pe ecran) a unui meniu POPUP:


DEACTIVATE POPUP

Ştergerea din memorie a unui meniu POPUP sau a unei


opţiuni bară BAR:
CLEAR POPUPS
RELEASED POPUPS [<lista_submeniuri>]
[EXTENDED]
RELEASED BAR <expN/ALL> OF <nume_popup>

Specificarea acţiunii care trebuie să aibă loc la selecţia unui


anumite opţiuni BAR se realizează cu comanda:
ON [SELECTION] BAR <exprN> OF<meniu_popup>
[<comanda>]

134
Baze de date SGBD FoxPro

Activarea unui meniu POPUP (într-o sintaxă minimală):


ACTIVATE POPUP <nume_m_popup>

Ascunderea/ afişarea unui meniu POPUP:


HIDE POPUP <nume_meniu_popup1>
[nume_meniu_popup2>/ALL][SAVE]
SHOW POPUP <nume_meniu_popup1>
[,<nume_meniu_popup2>/ALL] [SAVE]

Funcţii uzual folosite, asociate meniurilor:


MENU(),PAD(),POPUP(), BAR(), PROMPT()

ÎNTREBĂRI

Ce este un meniu? Care este utilitatea lui?

Ce tipuri de meniuri în FoxPro cunoaşteţi?

Câte meniuri pot fi activate la un moment dat? Pot fi activate


simultan un meniu bară MENU şi un meniu vertical POPUP?

De ce, de regulă, acţiunea care este efectuată la selecţia unei


opţiuni de meniu, constă în lansarea în execuţie a unei
proceduri?

Care este scopul “ascunderii” unui meniu (comanda HIDE)?

În ce condiţii, un meniu poate fi şters din memorie?

Comentaţi secvenţa de program, precizând dacă era necesară


deschiderea unei baze de date:
USE baza
DEFINE POPUP meniu PROMPT STRUCTURE

Să se scrie o secvenţă de program prin care să se creeze şi


activeze un meniu complet format dintr-un meniu bară
(MENU) cu 3 opţiuni PAD. Toate cele 3 opţiuni PAD sunt
legate de câte un submeniu POPUP, acestea la rândul lor
având mai multe opţiuni de tip BAR.

Explicaţi situaţiile de utilizare ale comenzilor


ON SELECTION PAD…, respectiv ON PAD…

135
Baze de date SGBD FoxPro

1. Ellen Sander – “FoxPro2 Self Teaching Guide”, John


Wiley&Sons, INC., Copyright 1992.
2. Ion Lungu, Nely Musat, etc. – “Sistemul FoxPro –
prezentare şi aplicatii”, Editura All, Bucuresti, 1993.
3. Gabriel Dima, Mihai Dima – “Fox-Pro”, Editura Teora,
Bucuresti, 1995.

136

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