Documente noi - cercetari, esee, comentariu, compunere, document
Documente categorii

Proceduri si functii definite de utilizator in FoxPro

Proceduri si functii definite de utilizator in FoxPro

Comanda DO

Lansarea in executia a unui program se face cu comanda DO, a carei sintaxa este urmatoare:

DO <fisier>

[WITH <lista_parm>]

[IN <fisier_proc>]

unde:

<fisier>

Reprezinta numele fisierului ce se va executa. Daca nu includeti o extensie la numele fisierului, FoxPro va cauta fisierele cu numele specificat, in urmatoarea ordine:

versiune executabila a programului (.EXE)

aplicatia (.APP)

versiunea compilata a programului (.FXP)

programul sursa (.PRG)

Pentru a executa programul specific unui meniu, ecran sau interogare folosind comanda DO, trebuie sa precizati extensiile acestora impreuna cu numele fisierului (.MPR, .SPR sau .QPR).

WITH <lista_param>

Clauza WITH permite transmiterea parametrilor programului ce se executa.

Parametrii din <lista_param> pot fi expresii, variabile de memorie, literali (constante), campuri sau functii definite de utilizator.

In mod prestabilit, transmiterea parametrilor se face prin referinta (prin adresa). Pentru a transmite un oarametru prin valoare, se plaseaza parametrul respectiv intre paranteze.

Numarul maxim de parametrii ce pot fi transmisi unui program este 24.

IN <fisier_proc>

Iclauza IN se foloseste atunci cand se apeleaza o procedura (cu numele <fisier>) din programul sursa specificat prin <fisier_proc>.

Observatii

Un fisier program poate contine comenzi DO suplimentare pentru a lansa in executie alte programe. Imbricarea comenzilor DO este limitata la 32.

Cand un program este lansat in executie folosind comanda DO, comenzile existente in programul sursa sunt executate pana cand se When you use DO to run a program, the commands contained in the program file are executed until one of the following occurs:

o       s-a intalnit comanda RETURN.

o       s-a executat comanda CANCEL.

o       s-a lansat o alta comanda DO.

o       sa- intalnit sfarsitul fisierului sursa.

o       s-a executat comanda QUIT.

Cand s-a terminat executia programului, controlul este returnat programului apelant, ferestrei Command, sistemului de operare MS-DOS in FoxPro pentru MS-DOS sau sistemului de operare Windows in FoxPro pentru Windows.

Daca folositi optiunea Do din meniul Program pentru a lansa in executie un program dintr-un director si/sau unitate de disc diferita fata de directorul si unitatea implicita, FoxPro schimba directorul si unitatea implicita la directorul si unitatea ce contine programul.

Definirea procedurilor si functiilor

Lansarea in executie a unui program din interiorul altui program, folosind comanda DO, reprezinta un pas important in structurarea aplicatiilor complexe. Pe masura ce numarul liniilor de program ale unei aplicatii creste, testarea si depanarea acesteia devine din ce in ce mai dificila, in principal datorita numarului mare de variabile utilizate, a numarului mare de instructiuni si a legaturilor dintre acestea.

In asemenea situatii este indicat ca aplicatia sa fie impartita in module separate, care rezolva o anumita parte a problemei; modulele fiind independente intre ele. Comunicarea cu celelalte module se face prin intermediul unor parametrii, variabile de comunicare, carea realizeaza interfatarea modulului cu exteriorul.

Sa presupunem ca pe disc exista trei programe sursa: monitor.prg, combin.prg si fact.prg. Continutul acestor trei fisiere este urmatorul:

MONITOR.PRG

opt = ' '

DO WHILE .T.

CLEAR

@ 3, 7 SAY 'O P T I U N I L E P R O G R A M U L U I'

@ 5, 10 SAY ' 1 - Calcul factoria'

@ 6, 10 SAY ' 2 - Calcul combinari de N cate K'

@ 7, 10 SAY ' 0 - Terminare program'

@ 9, 17 SAY ' Optiunea dorita: ' GET opt PICTURE 'X'

READ

DO CASE

CASE opt = '1'

DO fact

CASE opt = '2'

DO combin

CASE opt = '0'

CANCEL

ENDCASE

WAIT 'Apasati orice tasta' WINDOW

ENDDO

FACT.PRG (Calculeaza factorialului unui numar intreg dat - n! = 1*2*3 .* n)

CLEAR

n = 0

@ 5, 10 SAY 'Introduceti un intreg: ' GET n PICTURE '99'

READ

fact = 1

FOR i = 1 TO n

fact = fact * i

NEXT

@ 7, 10 SAY 'n! = ' + STR(fact)

COMBIN.PRG (Calculeaza combinari de n luate cate k cu relatia n! / k! / (n - k)!)

CLEAR

n = 0

k = 0

@ 3, 10 SAY 'n =' GET n PICTURE '99'

@ 4, 10 SAY 'K =' GET k PICTURE '99'

READ

f1 = 1

FOR i = 1 TO n

f1 = f1 * i

NEXT

f2 = 1

FOR i = 1 TO k

f2 = f2 * i

NEXT

f3 = 1

FOR i = 1 TO n - k

f3 = f3 * i

NEXT

sir = 'Combinari de ' + STR(n, 2) + ' luate cate '

sir = sir + STR(k, 2) + ' = ' + STR(f1 / f2 / f3, 13, 0)

@ 6, 10 SAY sir

Programele FACT.PRG si COMBIN.PRG reprezinta de fapr niste module relativ la programul MONITOR.PRG, care este programul principal. Modulele de acest tip pot fi create si in interiorul fisierului ce contine programul principal, formand asa numitele "proceduri si functii definite de utilizator" (in engleza se foloseste prescurtarea UDF - User Defined Function).

O functie definita de utilizator reprezinta un grup de instructiuni, care primeste sau nu un set de parametrii de la programul apelant si returneaza acestuia o valoare ca rezultat al prelucrarilor efectuate. O functie definita de utilizator poate intra ca operand in componenta unei expresii, analog functiilor standard din FoxPro. Definire unei functii se realizeaza utilizand comanda FUNCTION a carei sintaxa este:

FUNCTION <nume_functie>

O procedura definita de utilizator reprezinta de asemenea un grup de instructiuni ce primeste de la programul apelant un grup de parametrii, realizeaza prelucrarile specificate dupa care se revine in programul apelant. O procedura nu poate intra in compunerea unei expresii ca operand. Pentru definirea unei proceduri se foloseste comanda PROCEDURE, care are sintaxa:

PROCEDURE <nume_procedura>

unde <nume_functie> si <nume_procedura> reprezinta numele functiei procedurii si respectiv numele procedurii definite de utilizator, pe cre le vom denumi in continuare rutine, poate fi format din maximum 10 caractere, incepand cu o litera sau liniuta de subliniere si continand litere, liniuta de subliniere si cifre.

Structura unei rutine este urmatoarea:

FUNCTION PROCEDURE <nume_rutina>

[PARAMETERS <lista_parametri_fictivi>]

<comenzi>

RETURN

Trebuie sa se faca distinctie intre definitia unei rutine si apelul acesteia. La definirea unei rutine se stabilesc parametrii care se primesc, prelucrarile ce se vor efectua si rezultatele ce se vor transmite dupa prelucrare.

Apelul unei functii se face prin numele acesteia, urmat, intre paranteze rotunde, de lista parametrilor efectivi (reali, actuali) care se transmit. La executarea programului care contine o functie, in locul constructiei respective (apelul de functie) se va introduce valoarea returnata de functie, ca rezultat al prelucrarilor executate asupra datelor.

O procedura definita de utilizator se lanseaza in executie la fel ca un program, folosind comanda DO, cu deosebirea ca in loculu unui nume de fisier se precizeaza numele procedurii respective, iar parametrii reali ce se transmit acesteia se indica prin intermediul clauzei WITH a comenzii DO.

Procedurile si functiile unui program se introduc, de regula dupa ultima instructiune a programului, in acelasi fisier cu acesta. Dar rutinele se pot introduce si intr-un fisier separat care va fi asociat programului apelant prin comanda SET PROCEDURE a carei sintaxa este:

SET PROCEDURE TO [<fisier>]

unde <fisier> reprezinta numele unui fisier cu extensia implicit .PRG, ce contine rutinele care nu se gasesc in programul apelant.

Comanda SET PROCEDURE TO, fara parametri, determina inchiderea fisierului de proceduri curent asociat programului. Un program poate avea la un moment dat un singur fisier de proceduri deschis.

La apelarea unei proceduri folosind comanda DO, cautarea acesteia se face in ordinea urmatoare:

in fisierul care contine comanda DO;

in fisierul de proceduri deschis prin comanda SET PROCEDURE;

in programele in curs de executie, pe diferite nivele, pana la programul de nivel 1 (primul lansat in executie);

in directorul si unitatea curenta, considerand ca numele specificat in comanda DO reprezinta un program sursa si nu o procedura.

Pentru ca operatia de cautarea a unei proceduri sa se faca numai intr-un anumit fisier, numele acestui fisier se va include in clauza IN a comenzii DO.

Variabile globale si variabile locale

Variabilele unui program sunt definite prin diferite comenzi FoxPro (STORE, @GET etc.) si ele exista in memorie atata timp cat programul este in curs de executie, fiind automat eliminate la terminarea programului.

Probleme speciale apar atunci cand un modul (program, functie, procedura) este apelat din interiorul altui program. Variabilele din programul apelant sunt cunoscute in cel apelant si invers? Ce se intampla cand in modulul apelat se folosesc variabile cu nume identice cu cele din programul apelant? Raspunsurile la aceste intrebari vor fi date pe parcursul acetui paragraf.

Intr-un modul pot fi referite doua tipuri de variabile: variabile globale si variabile locale.

Variabilele globale (publice) pot fi accesate si modificate in orice modul in curs de executie, de pe un nivel inferior, egal sau superior nivelului modulului curent. Variabilele globale sunt create cu comanda PUBLIC care are 2 forme, una pentru variabilele simple si alta pentru variabilele structurate de tip tablou:

PUBLIC <lista_variabile>

PUBLIC ARRAY] <tablou1>(<expN1[,<expN2>])

[, <tablou2>(<expN3> [, <expN4>])]

Variabilele de memorie si tablourile create cu PUBLIC sunt initializate cu valoarea logica fals (.F.).

Variabilele locale (private) pot fi accesate si modificate doar in modulul in care au fost declarate si in cele subordonate acestuia. Variabilele private se declara folosind comanda PRIVATE care are 2 forme, una pentru variabilele simple si alta pentru variabilele structurate de tip tablou:

PRIVATE <lista_variabile>

PRIVATE ALL LIKE <masca> | EXCEPT <masca>]

Prin forma a comenzii PRIVATE declara ca fiind locale (private) variabilele din <lista_variabile>. A doua forma a comenzii PRIVATE declara ca fiind locale (private) fie toate variabilele (forma PRIVATE ALL), fie toate variabilele care se potrivesc cu <masca> (forma PRIVATE ALL LIKE <masca>) fie toate variabilele cu exceptia celor care se potrivesc cu <masca> (forma PRIVATE ALL EXECEPT <masca>).

NOTA Comanda PRIVATE nu creaza variabile, ci doar le declara ca fiind locale (private).

Transferul parametrilor

Pentru dezvoltarea aplicatiilor mai complexe, care include mai multe module (programe, functii, proceduri), este indicat ca in cadrul acestor module sa se foloseasca numai (sau cat mai mult) variabile locale, comunicarea cu celelalte module realizandu-se prin intermediul unor variabile speciale, numite parametri fictivi

In FoxPro sunt implementate doua metode de transmitere a parametrilor:

prin referinta (adresa), in care variabila transmisa este afectata de eventualele modificari aduse in subprogram;

prin valoare, cand o eventuala modificare a variabilei in subprogram nu afecteaza valoarea acesteia in programul (modulul) apelant.

Atunci cand comunicarea intre programul (modulul) apelant si subprogramul apelat se realizeaza prin intermediul parametrilor trebuie sa avem in vedere faptul ca, corespondenta dintre variabilele listei parametrilor reali si variabilele din lista parametrilor fictivi se face prin pozitie si nu prin nume.

Lista variabilelor transmise ca parametrii reali este stabilita fie prin clauza WITH a comenzii DO, in cazul apelului unui subprogram sau a unei proceduri, fie prin lista dintre parantezele rotunde ce urmeaza numelui functiei, cand avem un apel de functie.

Pentru stabili in subprogram care sunt variabilele locale in care se incarca parametrii transmisi se foloseste comanda PARAMETERS, a carei sintaxa este:

PARAMETERS <lista_variabile_locale>

Aceasta comanda, care trebuie sa fie prima comanda a unui modul (in cazul cand aceasta exista) defineste lista de variabile locale care vor prelua parametrii transmisi de la programul apelant.

Lista variabilelor locale (<lista_variabile_locale>) trebuie sa aiba totdeauna un numar de elemente mai mare sau cel putin egal cu numarul de elemente din lista parametrilor transmisi, pentru ca fiecare sa aiba un corespondent in subprogram.

In mod prestabilit, transmiterea parametrilor unui subprogram se realizeaza prin referinte (adrese). Adica subprogramului i se transmit adresele zonelor de memorie in care se gasesc valorile parametrilor reali. Schimbarea metodei implicite de transmitere a parametrilor se face folosind comanda SET UDFPARMS, a carei sintaxa este:

SET UDFPARMS TO VALUE | REFERENCE

Comanda SET UDFPARMS TO VALUE stabileste transmiterea prin valoare a parametrilor, ca metoda implicita, iar comanda SET UDFPARMS TO REFERENCE face ca transmiterea sa se faca implicit prin referinta.

Pentru ca un parametru sa fie transmis prin valoare atunci cand transmiterea implicita este prin referinta se include intre paranteze rotunde variabila respectiva in lista parametrilor reali. Daca vrem ca un parametru sa fie transmis prin referinta atunci cand transmiterea implicita este prin valoare, in lista parametrilor reali se precede variabila respectiva de caracterul @.

Revenirea in programul apelant

Executia unui subprogram (modul, functie, procedura) se termina atunci cand se produce una din urmatoarele:

s-a intalnit sfarsitul de fisier;

s-a executat comanda RETURN;

s-a executat comanda CANCEL.

Dupa terminarea executiei subprogramului apelat, controlul este preluat de prima instructiune din programul apelant care urmeaza apelului de subprogram (in cazul primelor doua situatii) sau ferestrei Command (in cazul executarii comenzii CANCEL).

Comanda RETURN

Comanda RETURN are rolul de a termina executia programului si de a preda controlul programului apelant, programului de cel mai inalt nivel sau unui alt program. Sintaxa comenzii este urmatoarea:

RETURN [<expr> | TO MASTER TO <nume_program>]

unde:

<expr>

Reprezinta expresia care furnizeaza valoarea ce va fi returnata programului apelant. Daca este omisa expresia <expr> sau lipseste comanda RETURN, programului apelat returneaza in mod automat valoarea logica adevarat (.T.).

TO MASTER

Clauza TO MASTER preda controlul programului apelant de cel mai inalt nivel.

TO <nume_program>

Clauza TO preda controlul programului specificat prin <nume_program>.

Observatii

Dupa executarea comenzii RETURN controlul este preluat de programul apelant, de programul de cel mai inalt nivel, de un alt program sau de fereastra Command.

Variabilele locale, declarate cu comanda PRIVATE, sunt eliminate din memorie dupa executarea comenzii RETURN.

De regula, comanda RETURN se plaseaza la sfarsitul unui program, proceduri sau functii.

Daca comanda RETURN lipseste dintrun program, functie sau procedura, se executa o comanda RETURN implicita.

Un program, procedura sau functie poate avea mai multe comenzi RETURN, daca este necesar.

Exemplu de utilizare proceduri si functii

Programul prezentat la inceputul acestui capitol (pag. 33) poate fi rescris prin utilizarea unei functii pentru calculul factorialului si a unei proceduri pentru calculul combinarilor. Programul sursa astfel modificat ar putea arata astfel:

opt = ' '

DO WHILE .T.

CLEAR

@ 3, 7 SAY 'O P T I U N I L E P R O G R A M U L U I'

@ 5, 10 SAY ' 1 - Calcul factorial'

@ 6, 10 SAY ' 2 - Calcul combinari de N cate K'

@ 7, 10 SAY ' 0 - Terminare program'

@ 9, 17 SAY ' Optiunea dorita: ' GET opt PICTURE 'X'

READ

DO CASE

CASE opt = '1'

CLEAR

n = 0

@ 5, 10 SAY 'Introduceti un intreg: ' GET n PICTURE '99'

READ

@ 7, 10 SAY 'n! = ' + STR(Factorial(n))

CASE opt = '2'

DO Combinari

CASE opt = '0'

CANCEL

ENDCASE

WAIT 'Apasati orice tasta' WINDOW

ENDDO

FUNCTION Factorial

PARAMETERS m

fact = 1

FOR i = 1 TO m

fact = fact * i

NEXT

RETURN fact

PROCEDURE Combinari

CLEAR

n = 0

k = 0

@ 3, 10 SAY 'N =' GET n PICTURE '99'

@ 4, 10 SAY 'K =' GET k PICTURE '99'

READ

sir = 'Combinari de ' + STR(n, 2) + ' luate cate '+ STR(k, 2)

IF (n = 0 ) OR (n = k)

comb = 1

sir1 = '= 1'

ELSE

IF k > n

sir1 = ' nu se poate calcula'

ELSE

comb = factorial(n) / Factorial(k) / Factorial(n - k)

sir1 = '= ' + STR(comb, 13, 0)

ENDIF

ENDIF

@ 6, 10 SAY sir + sir1

RETURN

Analizand programul, se poate constata ca functia Factorial are un singur parametru fictiv (m), transferul se realizeaza prin referinta (modul implicit de transmitere) si contine doua instructiuni RETURN, iar procedura Combinari nu are parametrii si apelaza functia Factorial pentru a calcula combinarile de N luate cate K.

Tinand cont de faptul ca pentru caclulul factorialului unui numar exista urmatoarele relatii de recurenta:

1 pentru n = 0 si n = 1

n! =

n * (n - 1)! pentru n = 2, 3,

functia Factorial poate fi rescrisa ca o functie recursiva (se autoapeleaza) astfel:

FUNCTION Factorial

PARAMETERS m

IF (m = 0) OR (m = 1)

fact = 1

ELSE

fact = m * Factorial(m -1)

ENDIF

RETURN fact