Documente Academic
Documente Profesional
Documente Cultură
Cuprins
• Rezumat
Pagina 1 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Câteva cuvinte...
Ce îmi propun? Relizarea unei aplicaţii care să gestioneze datele de contact ale firmelor (adrese,
telefoane etc.). Pentru asta vom avea nevoie în primă fază de:
Pagina 2 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 1.1
• Primii paşi
Se porneşte VFPro, fără a avea deschis vreun proiect, ci numai fereastra de comenzi, Command
Window.
?SET("Default") + Enter - întoarce: C:\ - drive-ul pe care este instalat la mine VFPro.
?CURDIR() + Enter - întoarce: \MICROSOFT VISUAL FOXPRO 9\ - directorul în care este instalat la
mine VFPro.
La fel:
?SYS(5)
?SYS(2003)
?SYS(5)+SYS(2003)
? FULLPATH("")
Implicit VFPro porneşte în directorul în care a fost instalat. Nu ne convine. Vrem să avem aceste
setări pentru directorul ProFox. Tastaţi în fereastra de comenzi:
SET DEFAULT TO ?
Pagina 3 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Se poate alege atât drive-ul curent cât şi directoul curent. Căutaţi ProFox şi daţi-i OK. Tastaţi din nou
comenzile de mai sus. Deja intoarce ceea ce vrem noi:
?SYS(5)
?SYS(2003)
?SYS(5)+SYS(2003)
Tastaţi:
apoi
CD ? + Enter
Alegeţi din nou directorul ProFox. Se poate seta cu o singură comandă atât drive-ul cât şi directoul curent.
(ca de altfel si cu comanda: SET DEFAULT TO ? ).
CD + spaţiu
Va apărea lista cu căile setate anteior, care pot fi selectate cu ajutorul săgeţilor, ca în fig. 1.2. În
cazul în care se lucrează la mai multe proiecte, foarte uşor se poate seta directoul curent dorit, alegând-ul
din listă.
Figura 1.2
Se poate stabili ca VFPro să pornească de fiecare dată în directorul dorit de noi modificând:
Tools\Options... File Locations\Default Directory – actualmente (Not Used) – (fig. 1.3).
Pagina 4 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 1.3
Selectează ultima comandă CD şi apasă tasta F1 (fig. 1.4). Se va deschide Help-ul VFPro exact la
comanda tastată. Această scurtătură poate fi folosită ori de câte ori este nevoie de Help pentru comenzile
tastate în Command Window.
Figura 1.4
• Rezumat
Până aici ar trebui să ştim cum controlăm modul în care VFPro se uită prin directoare. Se poate
stabili directorul curent simplu şi rapid. Personal asta fac prima oară cînd deschid VFPro.
Pagina 5 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Primele proiecte pe care le-am făcut au fost cu ajutorul wizard-ului. Se poate construi însă un
proiect nou nouţ şi funcţional şi fără acest ajutor. Pentru aceasta click pe butonul New (stânga sus – fig.
2.1).
Figura 2.1
În fereastra care se deschide alegem New file (fig. 2.2) şi salvăm proiectul cu numele myproj.pjx (sau
orice alt nume) în directorul ProFox (care acum trebuie să fie cel curent. Dacă nu este, faceţi-l urmând
paşii de mai sus).
Figura 2.2
Gata! Proiectul este creat şi este gol-goluţ. Nu rămâne decât sa trecem mai departe, la lucruri mai
seioase...
• Rezumat
Dacă renunţăm în timp la wizard, putem descoperi că multe lucruri le putem face chiar noi şi mai
mult, le putem înţelege.
Pagina 6 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
O intrebare pare firească: de ce sa-mi construiesc propriile biblioteci de clase şi clase când ele de
fapt există şi se pot folosi imediat?
Am să dau un exemplu (o să-l construim mai târziu). În mare parte aplicaţiile folosesc
nomenclatoare: furnizori, clienţi, produse, caracteistici diverse etc. La un moment dat trebuie să adăugăm
înregistrări, să ştergem etc. Deci avem nevioe de un formular. Ce-aţi zice dacă am face o clasă (un fomular
de fapt), caruia să-i spunem doar cum se numeşte tabela şi câmpul în care intoducem (ştergem etc.)
datele, iar el să se ocupe de restul, fără a mai scrie nici măcar o singură linie de cod? De fiecare dată când
avem nevioe de un nou nomenclator facem tabela pentru el apoi într-un minut este gata şi formularul.
Sună bine, nu-i aşa?
Acesta este unul din multele avantaje ale programării OOP (Object Oriented Programming):
putem reutiliza ceea ce am scris o dată de nenumărate ori.
Pentru asta însă avem nevoie de clase proprii, pe care să le stocăm în biblioteci proprii (după bunul
plac).
Să presupunem că aplicaţia noastră are 10 nomenclatoare, croite după modelul de mai sus. La un
moment dat putem avea surpriza (personal am avut-o de nenumărate ori) să constatăm că ceva nu merge
bine (codul scris conţine greşeli). Staţi liniştiţi: se întâmplă şi la case mai mari... Ce avem de făcut?
Mergem în clasa nomenclatoului şi corectăm greşala. TOATE nomnclatoarele vor moşteni “instant”
corecţia făcută şi binenţeles vor funcţiona după noile reguli. Gândiţi-vă cât munceam dacă trebuia să
facem corecţiile fiecărui nomenclator în parte? Dar dacă aveam 50 de nomenclatoare?
Un alt avantaj major este acela că modificăm/depanăm într-un singur loc şi toată lumea e
fericită.
Se deschide o ferestră care ne cere numele bibliotecii şi locul unde să o salvăm. Denumiţi-o b_std (de la
base standard – bibliotecă de bază pentru clasele standard) şi salvaţi-o neapărat în Libs (unde de fapt vor
sta toate de acum încolo).
Gata! Prima noastră bibliotecă există. Bine, dar unde-i, că n-o văd? Pentru asta selectaţi Cls şi
Add... din Project Manager (ca în fig. 3.1) apoi clasa b_std şi confirmaţi cu OK (sau dublu click pe ea).
Deja avem prima bibliotecă inclusă în proiect. Felicitări!
Pagina 7 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.1
• b_forms (base forms – includem clasele cu formularele de bază, căci vor fi mai multe)
• b_serv (base services – includem serviciile de bază – vom vedea mai încolo)
• b_comp (base compound – includem clasele compuse din clasele de bază)
• a_std (application standard – includem clasele de bază, pe care le vom folosi (instanţia) în
aplicaţie)
• a_forms (application forms – clase cu formularele de bază, pe care le vom folosi (instanţia) în
aplicaţie)
• a_serv (application services – servicii de bază, pe care le vom folosi (instanţia) în aplicaţie)
• a_comp (application compound – includem clasele compuse din clasele de bază, pe care le vom
folosi (instanţia) în aplicaţie).
Întrebare: n-ar fi fost suficient o singură bibliotecă, unde să includem toate clasele? De ce să
muncim atâta?
Se putea şi cu o singură bibliotecă de clase. Însă ceea ce nu se vede încă este faptul că fiecare
bibliotecă va conţine clase specializate sau care îndeplinesc funcţionalităţi asemănătoare, la care vom
putea adăuga noi funcţionalităţi, pe măsură ce apar noi necesităţi. Vom avea nevoie de întreţinere şi de
aceea este bine să găsim şi o logică în construcţia lor. Mai mult, vor fi aplicaţii care necesită un număr
mare de clase, iar altele la care vor fi suficiente doar câteva. De ce să le “cărăm” după noi pe cele de care
nu avem nevoie?
Se mai poate vedea că practic avem două perechi de biblioteci, la care diferă doar pima literă: a
respectiv b ( b_std – a_std; b_forms – a_forms; b_serv - a_serv; b_comp - a_comp ). În cele cu b vor
fi clasele pe care le vom subclasa din clasele de bază ale VFPro şi la care nu vom “umbla” prea mult, iar
cele cu a vor fi subclasate la rândul lor din cele cu b şi pe care le vom folosi (instanţia) în aplicaţie.
Confuz, nu-i aşa? Să trecem atunci la treabă.
Pagina 8 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.2
Selectăm în Project Manager biblioteca b_std (click pe ea), apoi apăsăm butonul New... .Se
deschide o fereastră ca cea din fig. 3.3.
Figura 3.3
Class Name: scriem b_chk (prescurtarea de la base CheckBox). Aici vom trece totdeauna numele pe care-
l dăm claselor noastre.
Based On: avem clasa pe care se bazează – CheckBox. Fiecare clasă are un păinte (pe care se bazează, din
care se subclasează). Aici se stabileşte cine este părintele.
Store In: avem calea spre biblioteca în care salvăm clasa. Toate clasele trebuie să stea într-o bibliotecă. În
cazul nostru b_std.vcx.
Pagina 9 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.4
Salvează şi închide fereastra Class Designer. Project Manage-ul a inclus-o în biblioteca b_std (fig.
3.5).
Figura 3.5
În continuare vom creea câteva clase de care ne vom lovi mai târziu. Apăsăm din nou butonul
New... (ca mai sus, biblioteca b_std fiind selectată) şi alegem ComboBox (fig. 3.6).
Toate clasele pe care le facem acum sunt clase native (cu care vine VFPro de la mama lui). Ceea
ce înseamnă că în bibliotecile care încep cu b_ vom avea doar clase derivate din clasele de bază VFPro (de
unde vine şi numele – base).
Pagina 10 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.6
Vom denumi această clasă b_cbo. După salvare în Project Manager va apărea şi această clasă.
În aceeaşi manieră derivăm din clasele de bază următoarele clase:
Toate aceste prescurtări este bine să le folositi peste tot. Oricine citeşte codul va înţelege mai uşor
despre ce este vorba şi voi veţi avea o viaţă mai uşoară.
Pagina 11 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.7
Contiunăm cu form-urile. Selectăm b_forms (click pe el) din Project Manager. apăsăm butonul
New... şi din combo selectăm Form (fig. 3.8).
Figura 3.8
Salvăm cu OK, nu înainte de a scrie numele clasei în TextBox-ul Class Name: , b_frm. Deja în Project
Pagina 12 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Manager trebuie să apară şi clasa b_frm, inclusă în biblioteca b_forms, ca în fig. 3.9.
Figura 3.9
Figura 3.10
Cu alte cuvinte noua noastră clasă se va baza (va moşteni) pe clasa b_frm, creată ceva mai
devreme. Confirmăm cu Open. La Class Name: scriem b_frm_modal şi confirmăm cu OK (fig. 3.11).
Pagina 13 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.11
Se deschide fereastra Class designer, unde avem form-ul creat de noi. Înainte de a o închide, modificaţi
proprietatea WindowType din 0-Modless în 1-Modal (fig. 3.12). Salvaţi şi închideţi.
Figura 3.12
Paşii făcuţi anterior se repetă, creând o nouă clasă, care să se bazeze pe b_frm, cu numele de
b_frm_modless, la care proprietatea WindowType rămâne 0-Modless.
La ce ne ajută toate astea? Pai dacă de exemplu am un formular în care adaug înregistrări şi la un
moment dat trebuie să deschid un alt formular din care să selectez ceva (un scenariu clasic, dealtfel),
atunci pe cel cu înregistrările îl instanţiez (creez) modless, iar pe cel din care se selectează modal. Acesta
din urmă nu mă mai lasă să selectez nimic din ceea ce se află sub el, până nu îl închid. Este şi normal să se
Pagina 14 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
întâmple aşa. Gândiţi-vă la ferestrele de mesaje. Ce s-ar întâmpla dacă o ferestră din aceasta mă anunţă că
nu pot salva o înregistrare din nu ştiu ce motiv, iar eu selectez formularul de sub ea şi-mi continui treaba?
Figura 3.13
Mai departe trecem la clasele application (cele care încep cu a_). Selectăm în Poject Manager
a_std şi apăsăm butonul New... . Toate clasele care au fost definite în b_std vor trebui subclasate în a_std,
iar numele lor va trebui să înceapă cu a_. Urmează apoi a_forms. La fel vom subclasa toate clasele din
b_forms.
Altfel spus:
• clasa nouă a_chk ce va fi salvată în biblioteca a_std, va moşteni clasa b_chk, din biblioteca b_std
• clasa nouă a_cbo ce va fi salvată în biblioteca a_std, va moşteni clasa b_cbo, din biblioteca b_std
etc.
Când am terminat de subclasat toate clasele din b_std, trecem la biblioteca b_forms:
• clasa nouă a_frm ce va fi salvată în biblioteca a_forms, va moşteni clasa b_frm, din biblioteca
b_forms etc.
În final, când suntem gata, va trebui să avem Project Manager-ul ca în fig. 3.14.
Pagina 15 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 3.14
Putem spune că avem o librărie de clase (toate bibliotecile din ProFox\Libs) aproape gata. Spun
aproape doarece nu ne-am ocupat de b_serv şi a_serv. Dar asta se va întâmpla ceva mai încolo.
Aş mai adăuga câteva cuvinte despre propietăţi, metode şi evenimente. Aproape toate clasele pe
care le-am creat până acum pot fi transformate în obiecte, prin instanţiere (click pe clasă în bara de meniu
şi click pe form). Cu aceste obiecte interacţionăm prin intermediul proprietăţilor, metodelor şi al
evenimentelor pe care le au (unele mai puţine, altele mai multe).
Altfel spus: am un buton pe un form (un obiect, de fapt). Dacă vreau să-i schimb culoarea, merg la
proprietatea numită BackColor şi aleg culoarea verde. Butonul meu va fi verde. Dacă fac click pe el se
apasă – deci reacţionează la acţiunile(evenimentele) mele. În metoda Click pun următoul cod:
Thisform.Release()
Pagina 16 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Ce se întâmplă dacă fac acum click pe buton? Form-ul meu se va închide. Adică eu i-am spus butonului
cum să procedeze dacă îl apăs. De fapt, metodele nu sunt altceva decât proceduri asociate obiectelor.
Daţi jos de pe forum din secţiunea “Articole” Glosar de terminologie OOP . Este un articol
foarte bun care dezvăluie multe lucruri interesante.
• Rezumat
Am trecut peste un hop mare. Bibliotecile de clase şi clasele. Dacă până aici aţi reuşit să faceţi tot
ce am făcut eu, felicitări! Ştergeţi tot proiectul şi mai faceţi-l o dată de la capăt. Pe curat. Sigur veţi
descoperi lucruri noi şi le veţi fixa pe cele învăţate.
Dacă nu, luaţi-o de la capăt. Nu vom putea trece mai departe fără ca aceste lucruri să fie cât de cât
clare.
Pagina 17 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
La începuturi vorbeam de modul în care VFPro se uită prin directoare. Am reuşit să învăţăm cum
setăm directorul de lucru curent. Însă în acest director ProFox avem mai multe subdirectoare. Hai să
vedem ce ştie VFPro despre ele.
Tastaţi:
SET PATH TO + Enter (ştergem toate căile de căutare care ar putea exista setate de noi).
(vrem să facem un formular pe care să-l cheme test, din clasa a_frm_modless care aparţine bibliotecii
a_forms).
Figura 4.1
Adică biblioteca a_forms.vcx nu există. Păi cum să nu existe, chiar noi am creat-o. Şi de fapt aşa
şi este. Numai că VFPro foloseşte directorul curent ca şi cale de căutare implicită, adică 'd:\profox\' şi atât.
Nu are de unde să ştie că de fapt noi am pus toate bibliotecile în Libs. Ca urmare va trebui să “informăm”
programul că folosim mai multe subdirectoare şi să facă bine să se uite şi acolo.
Pentru asta există mai multe posibilităţi. Momentan vom folosi un program (*.prg), care să ne
ajute. Din Project Manager click pe Code, selectaţi Programs, ca în fig. 4.2, si click pe New... .
Pagina 18 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 4.2
ca în fig. 4.3.
Figura 4.3
După cum se vede, nu am inclus şi directorul ProFox sau drive-ul D:\ .Setările directorului curent
au fost făcute mai devreme. Asta înseamnă că dacă mutăm directorul ProFox pe un alt drive (E:\ de
exemplu), căile noastre de căutare rămân valabile. Nimic nu s-a schimbat pentru ele.
Salvaţi programul cu numele setpath sau orice alt nume, în subdirectorul Programs. Project
Manager-ul ar trebui să arate acum ca în fig. 4.4.
Pagina 19 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 4.4
Apăsaţi butonul Run din Project Manager. Mare lucru nu s-a întâmplat. Şi totuşi...
Tastaţi:
?SET("Path") + Enter.
Această comandă întoarce toate căile de căutare setate ultima oară. Pentru a vedea rezultatul
apăsaţi concomitent tastele Ctrl + Alt + Shift. De pe ecran dispar toate ferestrele şi apare rezultatul dorit
(fig. 4.5).
Figura 4.5
Se deschide în sfâşit primul nostru formular, după atâta muncă. Deja VFPro ştie să se uite în
subdirectoare. Alegeţi File>Save As... şi salvaţi-l cu numele de Test în subdirectorul Forms. Apăsaţi
butonul Run (semnul exclamării de culoare vişinie). Gata!
Se pare că am uitat subdirectorul Temp. Acesta nu este trecut în căile de căutare. Nu-i nimic. Am
învăţat cum să setăm aceste căi.
Pagina 20 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Tastaţi:
apoi
?SET("Path") + Enter.
Apăsaţi din nou cele trei taste concomitent (Ctrl + Alt + Shift). Ceea ce vă apare pe ecran trebuie să
fie ca în fig. 4.6.
Figura 4.6
Ultima comandă a întors doar Temp ca şi cale de căutare. Ce s-a întâmplat de fapt? De câte ori
tastăm comanda SET PATH TO + unul sau mai multe directoare (subdirectoare), VFPro înlocuieşte căile
vechi cu cele noi, din ultima comandă.
Nu ne convine întotdeauna treaba asta. Ce se poate face? Putem folosi la sfârşitul liniei de comandă
cuvântul magic Additive.
Haideţi să testăm.
Tastaţi:
apoi din nou cele trei taste concomitent (Ctrl + Alt + Shift). Ce apare trebuie să fie similar cu fig. 4.7.
Figura 4.7
VFPro a adăugat la sfârşitul căii de căutare Temp căile de căutare din comandă.
Cu acest gen de problemă ne mai putem întâlni la comenzile: SET CLASSLIB TO ; SET PROCEDURE TO
etc., unde este important să nu suprascriem valori.
Pagina 21 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
• Rezumat
Se poate spune că am înpuşcat doi iepuri dintr-o lovitură. Ştim să setăm căile de căutare şi avem
deja un formular funcţional.
Când deschideţi Project Managerul nu aveţi decât să setaţi directorul de lucru apoi să daţi Run pe
setpath.prg, şi totul e OK.
Pagina 22 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
La începuturi discutam despre unul din avantajele utilizării claselor, adică scriem codul o singură
dată, apoi îl utilizăm de câte ori este nevoie.
Haideţi să luăm un exemplu concret. Am salvat un form în ProFox\Forms cu numele temp. Pentru
a-l aduce în Poject Manager, click pe Docs>Forms>Add... (fig. 5.1).
Figura 5.1
Alegeţi test din subdirectorul Forms şi confirmaţi cu OK. Project Manager-ul ar trebui să arate ca
în fig. 5.2.
Figura 5.2
Dacă apăsăm Run, formularul va rula. Pentru a-l închide, apăsăm butonul Close (x-ul din dreapta
Pagina 23 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
sus). Putem însă să punem propriul nostru buton pentru a închide formularul. Vom utiliza pentru asta
clasele care încep cu a_, după cum am stabilit. Click pe Modify în Project Manager, cu form-ul test
selectat, ca în figura 5.2 (form-ul test trebuie să fie închis). În acest moment butonul View Classes devine
activ. Click pe el (fig. 5.3).
Figura 5.3
Alegeţi Add...>Libs>a_std.vcx şi confirmaţi cu Open. Au apărut în bară clasele create de noi (fig. 5.4).
Figura 5.4
Pagina 24 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Click pe butonul a_cmd din bara de meniu şi apoi pe form. Form-ul trebuie să arate ca în fig. 5.5.
Figura 5.5
Ce am făcut de fapt? Din clasa a_cmd am instanţiat (creat) un obiect: butonul de comandă.
Modificăm proprietatea Caption în Iesire si Name în cmdIesire (fig. 5.6).
Figura 5.6
Pagina 25 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
• Adăugarea proprietăţilor
Scrieţi următorul cod pentru evenimentul Click din fereastra Properties (dublu click pe el pentru a se
deschide fereastra – fig. 5.7):
Figura 5.7
Rulăm formularul şi facem click pe butonul Iesire. Formularul se va închide dacă apăsăm OK în
fereastra de mesaj. Însă dacă închidem formularul din butonul Close (x-ul dreapta sus), mesajul nu va mai
apărea. Nu e bine. Trebuie să găsim o metodă să apară şi atunci.
Ce pot face? Pot face o clasă cu un un buton de comandă pentru închidere, să pun codul de mai sus
în evenimentul Click al acestuia .Dar uneori am nevoie de alt mesaj. Asta înseamnă să scriu alt cod. Nu
ştiu însă dacă vreau ca toate formularele să afişeze un mesaj la închidere. Atunci pot folosi un buton fără
mesaj.
Lucruile nu pot rămâne aşa. De ce aş avea nevoie ca să rezolv aceste probleme? Mă gândesc la
următoarele:
• un comutator care să comute: mesaj DA, mesaj NU – afişez mesajul doar dacă vreau;
• un loc unde să scriu orice mesaj vreau şi care să fie afişat la nevoie;
• o soluţie ca indiferent cum închide user-ul formularul, dacă am comutatorul pe .T., mesajul să
apară.
Să le luăm pe rând.
Prima problemă. Obiectele au proprietăţile lor native: Caption, Name, Heigh etc. care stochează
valori. Dar şi noi putem adăuga propriile noastre proprităţi. Concret: Formularului nostru putem să-i
adăugăm o proprietate “afisez_mesaj”, în care valorile ce le vom folosi vor fi .T. şi .F. Dacă vrem să avem
mesaj la închiderea ferestrei valoarea va fi .T., altfel .F. Avem de fapt comutatorul. Prima poblemă este
rezolvată teoretic.
A doua problemă. Pentru a putea afişa un alt mesaj de cîte ori vrem noi, fără să intervenim în cod,
megem pe raţionamentul anterior. Adăugăm formularului încă o proprietate, pe care o vom numi “mesaj”.
Când închidem formularul, acesta “se uită” la proprietatea “afisez_mesaj”şi în cazul în care valoarea este
.T., caută ce mesaj trebuie afişat. Putem pune chiar un mesaj personalizat şi pentu TitleBar (bara de titlu)
şi o vom face.
A treia problemă. Cum află formularul la închiderea lui că trebuie să verifice existenta sau nu a
unui mesaj? Pentru asta vom folosi evenimentul QueryUnload al formularului. Ceea ce înseamnă că
Pagina 26 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
indiferent de unde închidem formularul, înainte vom fi întrebaţi dacă vrem sau nu să o facem, dacă am
setat valoarea afisez_mesaj pe .T.
Haideţi să facem aceste lucuri practic. Adăugăm mai întâi proprietăţile.Pentru a scrie codul o
singură dată, îl vom pune în clasa părinte b_frm, iar toate formularele pe care le-am subclasat din această
clasă vor moşteni aceste proprietăţi.
Click în Project Manager pe Cls şi din biblioteca b_forms selectăm b_frm apoi click pe Modify
(pornim fomularul in design mode). Din meniu alegem Class>New Property (fig. 5.8).
Figura 5.8
Figura 5.9
• Name: afisez_mesaj
• Defaut/Initial Value: .T.
• Description: Comutator pentru afisarea sau inhibarea mesajului de închidere.
• Name: mesaj
• Defaut/Initial Value:
Pagina 27 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Următoarea:
• Name: mesaj_titlebar
• Defaut/Initial Value:
• Description: Mesajul care va fi afisat in TitleBar la închiderea formularului.
Intenţionat nu am trecut nimic la ultimele două proprităţi Defaut/Initial Value, pentru că nu ştiu ce
mesaje voi dori să afişez.
Figura 5.10
Deschidem formularul test în design mode. Proprietăţile adăugate de noi ar trebui să fie acolo. Mai
mult, dacă facem click pe ele vom vedea descrirea care le-am atribuit-o. Dacă nu apar, click dreapta pe
Pagina 28 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 5.11
Nu ne-a rămas decât să deschidem din nou clasa b_frm din Project Manager şi să punem următorul
cod pentru evenimentul QueryUnload:
Salvaţi şi închideţi. Deschideţi formularul test. În evenimentul Click, înlocuiţi vechiul cod:
cu următorul:
Rulaţi formularul. Închideţi-l şi cu butonul Iesire şi cu butonul Close ( x-ul din dreapta sus). Va fi
afişat în ambele cazuri mesajul de închidere.
Pagina 29 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 5.12
Rulaţi din nou formularul. La închidere cele două proprietăţi vor apărea la locul lor. Schimbaţi
valoarea proprietăţii afisez_mesaj în .F. Rulaţi din nou formularul. Nici vorbă de mesaj.
Ce am mai putea face? Am putea face o clasă pentru butonul Iesire. Scriem codul în evenimentul
Click, iar cînd avem nevoie de acest buton doar îl punem pe form şi el va şti să-şi facă singur treaba.
Voi face o nouă bibliotecă, b_cmd (base command) unde voi pune o clasă a acestui buton de
închidere (b_cmd_iesire). Butonul îl voi lua din b_std. Apoi voi face o bibliotecă a_cmd (application
command), în care voi subclasa clasa b_cmd_iesire sub numele de a_cmd_iesire. Totul va trebui să arate
ca în fig. 5.13.
Figura 5.13
Aceste biblioteci le voi folosi doar pentru butoane. Mă gândesc că pot să mai apară şi altele,
specializate, şi locul lor ar fi într-o bibliotecă separată.
Ştergeţi butonul cmdIesire din formularul test şi adăugaţi un nou buton de ieşire din clasa a_cmd.
Dacă rulaţi acum, totul trebuie să meagă perfect.
• Rezumat
Clasele ne oferă posibilitatea de a pune cod în ele, pe care-l scriem o singură dată, iar apoi le
folosim în aplicaţii, bazându-ne pe moştenire. Nu vor putea fi automatizate toate procesele, dar pentru cele
Pagina 30 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
de care ne lovim foarte des merită efortul. Un formular care are nevoie de control pentru închiderea lui
acum îl putem face în mai puţin de un minut. Mai mult. Dacă e nevoie de vreo modificare, o vom face în
clasele de bază b_frm şi b_cmd_iesire. La fel dacă se constată că ceva nu funcţionează corect.
Voi şterge clasa a_frm din biblioteca a_forms , deoarece nu-şi are utilitatea. Clasele din biblioteca
a_forms (a_frm_modal şi a_frm_modless) vor moşteni clasele din b_forms (b_frm_modal şi
b_frm_modless) care la rândul lor vor moşteni clasa b_frm. Pentru aceasta selectez în Project Manager
clasa a_frm şi apăs butonul Remove... .
Pagina 31 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Client 2
Client 3
Client 1
Client 4
Client 6
Client 5
Figura 6.1
Aşa arată baza noastă de date. Avem un container (ovalul albastru), echivalentul bazei de date, în
care ţinem datele clienţilor (ovalele galbene). Fiecare client are mai multe date, care-l caracterizează.
Client
Cod fiscal
Nr. Reg. Com.
Adresă
Localitate
Judeţ
Telefoane
e-mail
web
Figura 6.2
O parte din aceste date sunt specifice fiecăruia (codul fiscal este atribuit unic, de exemplu), iar
altele sunt comune mai multora (o localitate poate avea mai multe firme). Datele care sunt comune le voi
scoate separat. Pe cât posibil o să încerc să găsesc o logică în a grupa datele care au caracteristici comune
în tabele separate.
Pagina 32 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Client
Cod fiscal
Nr. Reg. Com.
Adresă
ID Localitate
Judeţ
Telefoane
e-mail Localităţi
web
Figura 6.3
Fig. 6.3 s-ar traduce cam aşa: o localitate are mai multe firme. O firmă nu poate fi în mai multe
localităţi în acelaşi timp (atenţie, nu vorbim de filiale). Avem deci o relaţie “una la mai multe”. În tabelul
(ovalul galben) vom înlocui denumirea localităţii cu ID-ul acesteia, pe care îl vom lua din tabela localităţi.
ID-ul nu reprezintă altceva decât un indice pe care-l atribuim fiecărei localităţi în parte şi care va juca rol
de cheie primară (unică) pentru tabelul localităţi şi cheie străină pentru tabelele clientilor. Tabela localităţi
va reprezenta de fapt un nomenclator. Nomenclatoarele sunt tabele “specializate” în date de acelaşi fel.
Aici vom adăuga o singură dată fiecare înregistrare necesară, pe care o vom folosi peste tot în aplicaţie
unde este nevoie.
Client
Cod fiscal Judeţe
Nr. Reg. Com.
Adresă
ID Localitate
Judeţ
Telefoane
e-mail Localităţi
web ID Judeţ
Figura 6.4
Fig. 6.4 se traduce astfel: un judeţ are mai multe localităţi. O localitate nu poate fi în mai multe
judeţe (ca şi nume se poate, dar fizic nu). Deci relaţia stabilită este la fel ca cea anterioară: “una la mai
multe”. Am introdus în tabela (ovalul) localităţi cheia străină ID Judeţ. În tabela Clienţi judeţul l-am tăiat.
Pagina 33 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Adresa. O firmă poate avea una sau mai multe adrese. De exemplu adresa din certificatul de
înmatriculare al firmei (sediul social), adresa unde-şi desfăşoară activitatea, adresa birouri etc. Pentru
exemplul acesta vom lua în considerare o singură adresă, cea unde se desfăşoară activitatea firmei.
Telefoanele. În general o firmă poate avea mai multe telofoane. Câte telofoane ar fi bine să punem
în baza noastră de date? 2,3,4 sau câte? Greu de spus. Mai mult, tipul telefoanele diferă şi el:
• telefoane fixe;
• telefoane mobile;
• faxuri (care sunt de fapt tot telefoane);
• telefoane RDS şi pot să mai apară.
E-mailul. O firmă are o adresă de mail. Dar ce facem dacă firma îşi mai face câteva adrese peste un
an? De exemplu pot să apară noi adrese pentru comenzi, pentru contabilitate etc. Cîte pot să fie? Greu de
spus.
Ca urmare trebuie să găsim o soluţie flexibilă, care să ne permită adăugarea unui număr nelimitat
de telefoane, adrese, e-mailuri şi chiar alte tipuri de date de contact, pe care încă nu le ştim dar care pot să
apară pe parcurs, fără să intervenim asupra structurii bazei de date mereu.
Ce au toate lucrurile de mai sus în comun? Păi sunt date de contact. Putem raţiona ca înainte: o
firmă are mai multe date de contact (relaţie “una la mai multe”). Asta înseamnă obigatoriu scoaterea din
tabela clienti a datelor de contact. Dar (întotdeauna există un “dar”) un tip de dată de contact poate
aparţine mai multor firme. Asta înseamnă că relaţia noastră este de fapt “mai multe la mai multe”. Genul
acesta de relaţii trebuie evitat. Cea mai bună soluţie este să avem doar relaţii “una la mai multe”.
Pentru rezolvarea cazului de mai sus, nu avem decât să împărţim relaţia “mai multe la mai multe”
în două relaţii “una la mai multe” şi vom fi fericiţi. Cum? Foarte simplu. Facem un nomenclator de date de
contact (Tip contact), avem tabela Clienţi şi între ele vom folosi o tabelă de legătură (joncţiune) - Contact
client, ca în fig. 6.5.
Localităţi Client
Cod fiscal
Contact client
ID Judeţ ID client
Nr. Reg. Com.
Adresă ID tip contact
ID Localitate
Judeţ
Telefoane
e-mail Tip contact
web Prefix
Telefon fix
Telefon mobil
Telefon RDS
Fax
Judeţe e-mail
web
Figura 6.5
Pagina 34 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Haideţi să luăm un exemplu: avem o clasă de 30 de elevi. Fiecare elev are un set de 5 manuale
diferite. În primă fază suntem tentaţi să facem o tabelă cu elevii şi una cu manuale. Adică un elev are mai
multe manuale. Cum va arăta baza de date? În tabelul elevi vom avea 30 de înregistrări (numele fiecărui
elev o singură dată) iar în tabela manuale vom avea un set de 5 înregistrări care se va repeta de 30 se ori,
în total 150. Fiecare manual va apărea de 30 de ori. Nu arată prea bine.
Dar un manual poate aparţine mai multor elevi. Asta înseamnă o relaţie “mai multe la mai multe”.
Corect este să facem tabela elevi (nomenclator), tabela manulale (nomenclator) şi o tabelă intermediară
manuale_elevi. Întreţinem uşor şi elevii şi manualele, într-un singur loc. Dacă apare un nou manual îl
introducem o singură dată în nomenclator, urmând să-l atribuim cărui elev dorim, în tabela de joncţiune.
Revenind la aplicaţia noastră. Până aici avem cam ce ştim despre client. Ne-ar mai trebui datele şi
parolele userilor. Pentru asta vom face o nouă tabelă (nomenclator), cea a userilor. Raţionăm: un user are o
parolă. O parolă aparţine unui singur user (chiar dacă teoretic pot să existe doi useri cu aceeaşi parolă).
Dacă le-am pune în tabele diferite am avea o relaţie “unu la unu”. Nu ne avantajează. Prin urmare aceste
date vor rămîne în aceeaşi tabelă (fig. 6.6)
Useri
Denumire user
Parola
Figura 6.6
• Rezumat
• dacă avem relaţii “unu la unu”, datele vor sta în aceeaşi tabelă;
• dacă avem relaţii “una la mai multe” le vom gestiona în două tabele diferite, legate între ele; partea
“una” reprezintă tabela părinte, iar partea “mai multe” reprezintă tabela copil;
• dacă avem relaţii “mai multe la mai multe” le vom rupe în două relaţii “una la mai multe” cu o
tabelă de joncţiune între ele. Fiecare tabelă desprinsă devine tabelă părinte iar tabela de joncţiune
devine tabelă copil pentru cele două tabele desprinse.
Pagina 35 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Tabelele în Visual Fox Pro pot exista în două moduri: tabele libere şi tabele incluse într-o bază de
date. Baza de date nu este altceva decât un container care conţine informaţii despre tabelele şi vederile
incluse în ea. Folosirea tabelelor incluse în baza de date în locul tabelelor libere are multe avantaje,
putându-se folosi:
Trebuie menţionat că o tabelă poate aparţine la un moment dat unei singure baze de date .
În Project Manager faceţi click pe tab-ul Data, selectaţi Databases apoi click pe butonul New...
(fig. 7.1).
Figura 7.1
În fereastra care se deschide click pe butonul New Database (fig. 7.2).
Figura 7.2
Pagina 36 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Salvaţi baza de date cu numele de contacts în folderul ProFox\Data. Închideţi fereastra care se
deschide în urma salvării – Database Designer. Project Manager-ul trebuie să arate ca în fig. 7.3.
Figura 7.3
Click pe Tables (se află imediat sub contacts în Project Manager – fig. 7.3) apoi pe New... . În
fereastra care se deschide alegeţi New Table (fig. 7.4).
Figura 7.4
Salvaţi tabela cu numele de “firma” în ProFox\Data. Se deschide fereastra Table Designer – firma.dbf (fig.
7.5).
Pagina 37 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.5
Introduceţi câmpurile ca cele din fig. 7.6, respectând tipul fiecăruia (apare sub denumirea Type).
Pagina 38 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.6
Fiecare tabelă va avea o cheie unică (id), care va fi de tip Integer(Autoincrement). Rolul acestei
chei unice este de a identifica unic fiecare înregistrare. Cheia nu va fi vizibilă pentru utilizator. Nici nu ne
interesează ce număr va fi alocat (se va autoincrementa singură). Ce ştim cu siguranţă că va fi unică şi că
nu va trebui să întreţinem noi această unicitate. Super, nu?
La index am selectat Ascending (apare o săgeată orientată în sus). Pentru a face această cheie
unică, selectaţi tab-ul Indexes şi alegeţi Primary (fig. 7.7).
Pagina 39 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.7
Semnificaţia câmpurilor:
• denfirma – aici vom stoca denumirea tuturor firmelor pe care le vom introduce în baza de date;
• denextra – putem introduce o firmă de mai multe ori dacă are mai multe puncte de lucru. La
denextra (denumire extra) scriem denumirea străzii dacă se află în acelaşi oraş sau denumirea
oraşului dacă se află în oraşe diferite. Vom avea ceva de genul: SC LUCS SRL Tulcea şi SC LUCS
SRL Galati sau SC LUCS SRL Margaretei şi SC LUCS SRL Fanionului;
• codfiscal – reprezintă codul fiscal al fiecărei firme. Puteam să folosim acest câmp ca şi cheie
unică, ţinând cont de faptul că este unic pentru fiecare firmă în parte. Eu cred însă că nu este rolul
lui acesta. O cheie primară (unică) trebuie să fie doar o cheie primară şi nimic altceva. Un cod
fiscal este o caracteristică a firmei şi aşa şi trebuie să rămână. Pot fi situaţii în care introducem de
mai multe ori aceeaşi firmă cu acelaşi cod fiscal, dar cu o altă denumire extra (un punct de lucru) –
vezi exemplul de mai sus. Dacă puneam codul fiscal cheie unică am fi avut o mare problemă. Aşa
fiecare înregistrare va avea cheia ei , indiferent de legislaţie, nr. de puncte de lucru etc.;
• nr_regcom – numărul de înregistare la Registrul Comerţului;
• adresa – vom trece adresa formată din stradă, număr, bloc, etaj, apartament, separate prin virgulă,
spaţiu etc. (la alegere). Nu am pus câte un câmp separat pentru fiecare, deoarece nu voi folosi
interogări de genul: câte firme sunt pe strada X sau câte firme au sediul la etajul 4. Dacă aveţi
nevoie de aşa ceva, faceţi câmpuri separate;
• id_user_add – aici vom stoca ID-ul userului logat, care salvează înregistarea. Poate vreţi să ştiţi la
un moment dat cine a introdus o înregistare greşită sau cine a introdus cele mai multe înregistrări;
• data_add – data şi ora când a fost adăugată înregistrarea. Este o informaţie utilă, de care vă puteţi
Pagina 40 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
lovi. Pentru a nu gestiona noi această înregistrare, vom selecta data_add în fereastra Table
Designer şi apoi butonul cu trei puncte din dreptul textbox-ului Default value: (fig. 7.6). Se va
deschide fereastra Expression Builder (fig. 7.8).
Figura 7.8
Facem click pe combo-ul Date:, alegem valoarea DATETIME() (fig. 7.9) şi confirmăm cu OK. În
fereastra Table Designer la Default value: apare valoarea DATETIME(). De câte ori vom adăuga o nouă
înregistrare, funcţia DATETIME() întoarce data şi ora curentă ale sistemului, pe care o salvează în tabelă.
Pagina 41 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.9
Figura 7.10
Pagina 42 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
localitati
• id – cheie primară;
• id_jud – cheie străină din tabela judete, de tip Integer, cu index pe ea (săgeată în sus);
• denloc – denumirea localităţii, de tip Character, lungimea (with) de 20;
• id_user_add – ID-ul userului care adaugă înregistrarea, de tip Integer, cu index pe el;
• data_add – data şi ora când se adaugă înregistarea, de tip DateTime (default value: DATETIME());
judete
• id – cheie primară;
• denjudet – denumirea judeţului, Character (15);
• id_user_add – ID-ul userului care adaugă înregistrarea, de tip Integer, cu index pe el;
• data_add – data şi ora când se adaugă înregistarea, de tip DateTime (default value: DATETIME());
tipcontact
• id – cheie primară;
• dencontact – denumirea tipului de contact, Character (20);
• id_user_add – ID-ul userului care adaugă înregistrarea, de tip Integer, cu index pe el;
• data_add – data şi ora când se adaugă înregistarea, de tip DateTime (default value: DATETIME());
contact_firma
• id – cheie primară;
• id_firma – cheie străină din tabela firma, de tip Integer, cu index pe ea (săgeată în sus);
• id_tipcontact – cheie străină din tabela tipcontact, de tip Integer, cu index pe ea (săgeată în sus);
• id_user_add – ID-ul userului care adaugă înregistrarea, de tip Integer, cu index pe el;
• data_add – data şi ora când se adaugă înregistarea, de tip DateTime (default value: DATETIME()).
Figura 7.11
Selectăm baza de date contacts din Project Manager şi facem click pe Modify. Se deschide o
Pagina 43 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.12
Pentru a lega în relaţie tabela judete cu tabela localitati, facem click pe id în tabela judeţe, ţinem
butonul mouse-ului apăsat şi tragem peste cheia id_loc din tabela localitati. La fel procedăm cu:
Pagina 44 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.13
Pentru a adauga tabela user-ilor click dreapta pe fereastra Database Designer (fig. 7.13), alegeţi
New Table..., click pe butonul New Table şi salvaţi tabela cu numele user în ProFox\Data. Adăugaţi
câmpurile ca în fig. 7.14.
Pagina 45 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 7.14
Rezumat
În momentul de faţă avem baza de date cu tabelele necesare. Pentru tabele folosim chei unice
independente de datele din tabele (de obicei de tip integer autoincrement), rolul acestora fiind acela de a
identifica fiecare înregistrare în mod unic şi atât. Aceste chei nu se vor vedea de către utilizator. Se pot
folosi de asemenea diferite valori predefinite pentru câmpuri (data şi ora adăugării înregistrării, la noi).
Pagina 46 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
CAP 8. Nomenclatoare
ATENŢIE!
În tabela user trebuie adăugat şi câmpul “parola” de tip Character şi lungime (Width) 10.
După cum am discutat înainte, datele de acelaşi fel trebuie ţinute în tabele separate, numite
nomenclatoare. Am dat exemplul cu elevii: toţi elevii trebuie să aparţină unui nomenclator. Întreţinem
aceste date într-un singur loc şi folosim cheia unică a nomenclatorului pentru a lega alte tabele, prin relaţii
“una la mai multe”. La fel şi cu manualele.
Ne propunem să facem o clasă nomenclator, pe care să o folosim de câte ori avem nevoie. De
asemenea codul pentru adăugare, salvare, modificare şi ştergere le vom scrie o singură dată în clasă.
Setări proprietăţi:
● Height – 450
● Width – 390
● AutoCenter .T.
Toate controalele pe care le vom adăuga vor proveni din clasa b_std. Pentru a le avea vizibile click
pe butonul View Clases şi alegem Add.../b_std din ProFox\Libs (fig. 5.3).
Nomenclatorul ar trebui să conţină un TextBox cu Label în care să scriem noua valoare ce urmează
să o salvăm, un ListBox cu Label în care să vedem valorile introduse deja şi un set de butoane: Adauga,
Modifica, Sterge, Renunta, Salveaza plus un buton de ieşire din form. Voi pune aceste lucruri pe rând.
Pagina 47 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 8.1
Facem din nou click pe butonul View Clases (fig. 5.3) şi alegem Add.../b_cmd.vcx din
ProFox\Libs. Punem butonul de ieşire b_cmd_iesire pe form, dreapta jos. Modificăm Name în fereastra
Properties în cmdIesire. Nomenclatorul nostru trebuie să arate ca în fig. 8.2.
Reamintesc că form-ul şi butonul de ieşire au în clasele lor de bază codul necesar pentru a afişa sau
nu un mesaj de închidere, pe care-l putem configura din proprietăţi, fără a scrie nici o linie de cod.
Pagina 48 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 8.2
Ne mai trebuie un set de butoane Adauga, Modifica, Sterge, Renunta, Salveaza. Aceste butoane ar
trebui să fie interblocabile. Mă gândesc că dacă apăsăm butonul Adauga, butoanele de Sterge si Modifica
nu ar trebui să fie active. În momentul în care se adaugă ceva, putem să salvăm sau să renunţăm. Situaţii
similare mai sunt şi vor trebui rezolvate.
Întrebarea care se pune este dacă vom avea nevoie de un astfel de set de butoane şi cu alte ocazii?
Eu zic că sunt şanse. Aşa că le vom face ca şi clasă separată, pentru a le putea întreţine uşor şi pentru a le
face cît mai generale.
Clasa care se deschide are două butoane. Dacă ne uităm mai atent observăm că aceste butoane nu
provin din clasa noastră b_cmd, care clasă ar trebui să fie părintele tuturor butoanelor noastre (selectăm
unul din butoane şi ne uităm în Properties la ClassLibrary – fig. 8.3). Dacă încercăm să le ştergem vom
primi un mesaj de eroare. Nu putem şterge aceste butoane pentru că aparţin unei clase superioare în
ierarhie.
Pagina 49 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 8.3
Închidem Class Designer_ul şi deschidem clasa b_cmg din biblioteca b_std şi ştergem cele două
butoane. Containerul va rămâne gol. Salvăm şi închidem.
Va trebui să-i spunem VFPro-ului că grupul nostru de butoane trebuie să moştenească un buton pe
care-l vrem noi. Pentru mai multă flexibilitate, facem o clasă care va fi părinte pentru butoanele din grupul
de butoane:
Dacă vrem ca butoanele noastre să arate într-un anumit fel de exemplu, nu va trebui să modificăm
fiecare buton în parte ci doar butonul părinte – b_cmdset. Este mult mai uşor şi rapid.
Deschidem din nou clasa b_cmg_set din biblioteca b_cmd, care de această dată este goală. Setăm
ca toate butoanele să provină din butonul nostru părinte pentru grupul de butoane, b_cmdset. Pentru
aceasta selectăm în fereastra Properties MemberClassLibrary apoi facem click pe butonul cu trei puncte de
sub tab-ul Favorites. Răspundem cu Yes în fereastra care se deschide şi alegem clasa b_cmdset din
biblioteca b_cmd ca şi clasă pentru grupul de butoane (fig. 8.4).
Pagina 50 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 8.4
Figura 8.5
Se poate observa în fereastra Properties că aceste butoane provin din clasa noastră B_cmdset.
Modificăm propietăţile Caption pentru butoane ca în fig. 8.6. Butonul Sterge îl mutăm mai jos.
Pagina 51 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 8.6
Salvăm, închidem şi deschidem clasa b_frm_nom, din biblioteca b_nom. Click pe View Classes
(fig. 5.3), Add... şi căutăm biblioteca b_cmd. După afişare punem pe form grupul de butoane. În final
form-ul trebuie să arate ca în fig. 8.7.
Figura 8.7
Se vede că butoanele aparţin unui container. Poate la un moment dat vrem să schimbăm fundalul
Pagina 52 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
form-ului şi atunci grupul de butoane nu va arăta bine. Pentru remediere salvăm şi închidem. Deschidem
din nou clasa b_cmd_set din biblioteca b_cmd şi setăm în fereastra Properties: BorderStyle 0 – None şi
BackStyle 0 – Transparent. Salvăm, închidem şi redeschidem clasa b_frm_nom din biblioteca b_nom.
Trebuie să arate ca în fig. 8.8.
Figura 8.8
Toate butoanele din clasa b_cmd_set ar trebui să aibă posibilitatea de a afişa un mesaj. Nu neapărat
la adăugarea unei noi înregistrări, dar sigur la ştergerea, salvare, modificare sau la renuntare. E bine să
dăm o şansă utilizatorului înainte de a definitiva o astfel de acţiune.
Putem să scriem de fiecare dată un mesaj, în fiecare form unde vom folosi nomenclatorul, putem
să punem în clasa b_cmd_set fiecărui buton propriul mesaj sau putem să ne folosim de faptul că toate
butoanele au un părinte comun: butonul din clasa b_cdmset. Însă acest mesaj ar trebui să fie flexibil.
Textul afişat nu va fi de fiecare dată acelaşi probabil, mesajul dinTitleBar la fel şi uneori chiar nu vrem să
afişăm vreun mesaj. Această problemă am rezolvat-o cu închiderea form-urilor, în clasa b_frm din
biblioteca b_forms (vezi cap. 5).
Salvăm şi închidem Class Designer-ul. Deschidem clasa b_cmdset din biblioteca b_cmd. Alegem
din meniu Class/New Property... şi adăugăm următoarele proprietăţi în fereastra care se deschide:
Pagina 53 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
• Name: afisez_mesaj
• Defaut/Initial Value: .T.
• Description: Comutator pentru afisarea sau inhibarea mesajului
Următoarea
• Name: mesaj
• Defaut/Initial Value:
• Description: Mesajul care va fi afişat la apăsarea butonului.
Următoarea:
• Name: mesaj_titlebar
• Defaut/Initial Value:
• Description: Mesajul care va fi afisat in TitleBar la apasarea butonului.
Salvăm şi închidem. Alegem din meniu Class/New Method... şi adăugăm o metodă care să se
ocupe de afişarea mesajelor.
● Name: afisare_mesaj
● Description: Metoda de management mesaje pt. butoane
Din meniu alegem File/Save As... şi salvăm în Forms. Rulăm form-ul şi facem click pe butoanele
adăugate. Toate afişează mesaj. Acest form este doar de probă.
Ce-am făcut de fapt? Am scris codul într-un singur buton şi avem cinci butoane care ştiu tot ce ştie
butonul original doar prin simpla modoficare a valorii ButtonCount a clasei b_cmg_set. Mai mult, fiecare
buton e complet configurabil: putem sau nu să afişăm mesaj iar acesta poate fi diferit pentru situaţii
diferite. Super!
Mai departe ne vom ocupa de interblocabilitatea butoanelor. Codul îl vom adăuga în clasa
b_cmg_set din biblioteca b_cmd, în evenimentul Click pentru fiecare buton în parte.
Cînd adăugăm o înregistrare utilizatorul poate doar să salveze sau să renunţe. Asta înseamnă că la
Pagina 54 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Dar butonul de adăugare? Păi el ar trebui să devină de asemenea inactiv. Nu putem permite să se
apese butonul de adăugare de câte ori se vrea, fără salvare sau renunţare la salvare. Al doilea aspect ar fi
cel al productivităţii. Dacă trebuie să introduc douăzeci de înregistrări nu-mi prea convine să tot fiu
întrebat: Vrei să adaugi o nouă înregistrare? Oricum până să salvez sau renunţ pot să fac ce vreau: datele
nu vor avea de suferit. Deci şi butonul Adauga va deveni inactiv şi proprietatea afisez_mesaj o punem pe
.F. în clasa b_cmg_set din biblioteca b_cmd.
With This
.Enabled= .F.
.Parent.cmdModifica.Enabled= .F.
.Parent.cmdSterge.Enabled= .F.
.Parent.cmdRenunta.Enabled= .T.
.Parent.cmdSalveaza.Enabled= .T.
Endwith
With This
.Enabled= .F.
.Parent.cmdAdauga.Enabled= .T.
.Parent.cmdSalveaza.Enabled= .F.
Endwith
Rezumat
Ulilizarea claselor ne oferă foarte multe avantaje. Putem face un lucru o singură dată, apoi folosim
de câte ori avem nevoie.
Pagina 55 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Indiferent de cum proiectezi aplicatia, de un lucru nu scapi: accesul la date. Variantele clasice sunt
ceva de genul:
If !Used("tabela")
Use tabela In 0
Endif
etc.
Multă lume spune ca foloseşte acest mod de abordare pentru a avea controlul. Personal credeam şi
eu acelaşi lucru. Dar mă întreb: să am controlul la ce? La deschiderea si închiderea tabelelor? Dacă am un
select care să zicem că este alimentat din 20 de tabele, va trebui să deschid manual acele tabele şi apoi să
le închid tot manual şi am astfel control? Sau dacă aplicaţia mea are 100 de form-uri, de câte ori o să scriu
acest tip de comenzi pentru fiecare form? Socotiţi voi. Merită efortul când există ceva gata făcut, testat de
ani de zile si perfect funcţional? Eu zic că nu. Merită folosit Data Environment.
Ce este de fapt acest Data Environment? Este un obiect container care are proprietăţi, metode şi
evenimente, în care putem adăuga tabele şi view-uri. Odată adăugate acestea vor fi deschise automat şi
închise automat. Nu ne ocupăm noi de închis şi deschis tabele. Putem însă avea controlul asupra lui Data
Environment. Mult mai important şi mai puternic.
Deschidem din Project Manager/Forms form-ul frm_nom în design mode, făcând click Modify... .
Click pe butonul Data Environment (fig. 9.1 cel cu verde).
Figura 9.1
Pagina 56 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.2
Selectăm tabela judeţe, click pe butonul Add apoi pe Close. Rămâne fereastra Data Environment
ca cea din fig. 9.3.
Figura 9.3
Pagina 57 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.4
Figura 9.5
Rulăm form-ul frm_nom apoi deshidem din nou fereastra Data Session. În fereastră apare tabela
judete ca fiind deschisă (fig. 9.6).
Figura 9.6
Închidem form-ul frm_nom şi verificăm din nou. Tabela a fost închisă. Este nevoie de mai mult de-
atât? Se poate face ceva mai bine? Merită să “controlăm” noi aceste procese? Eu zic că nu.
Pagina 58 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Mai există încă un avantaj al folosirii Data Environment. Selectaţi pe form (în design mode)
TextBox-ul txtDenumire, apoi în fereastra Properties click pe ControlSource. Putem selecta sursa de date
cu un singur click (fig. 9.7).
Figura 9.7
Facem o nouă bibliotecă a_nom pe care o salvăm în ProFox\Libs. O adăugăm în Project Manager
şi subclasăm în ea clasa b_frm_nom din biblioteca b_nom, cu numele a_frm_nom. Pentru aplicaţie
reamintesc că vom folosi doar clasele din bibliotecile application (cele care încep cu a_).
Va trebui să adăugăm pentru acest nomenclator date. Pentru asta vom folosi view-rile.
Ce sunt de fapt aceste view-uri? Nimic altceva decât definiţii ale unor interogări SQL care sunt
stocate în containerul bazei de date (cursoare, de fapt). Acestea nu au date în ele precum tabelele, în
schimb conţin codul SQL care le vor popula. Mai mult, pot fi repopulate de câte ori vrem, fără a mai scrie
încă o dată instrucţiunile SQL.
Există view-uri locale (pe care le vom folosi) şi Remoute View-uri, care accesează alte tipuri de
date decât cele native.
Pagina 59 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Haideţi să facem primul nostru view. În Project Manager/Data facem click pe Local Views apoi
click pe butonul New... . Se deschide o fereastră ca cea din fig. 9.8.
Figura 9.8
Click pe butonul New View. Se deschide fereastra Add Table or View (fig. 9.9).
Figura 9.9
Selectăm tabela judete apoi click pe butonul Add. Tabela judete a fost adaugată. Click pe butonul
Close, pentru a închide fereastra din fig. 9.9. Rămâne fereastra View Designer – View1 (fig. 9.10).
Pagina 60 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.10
În partea superioară a ferestrei se poate observa tabela judete. În partea inferioară apar mai multe
tab-uri: Fields, Join, Filter etc. Să le luăm pe rând.
În pagina Fields putem selecta ce câmpuri dorim să conţină view-ul nostru. Dacă aveam mai multe
tabele puteam pune orice câmp din acestea. Deoarece vrem să adăugăm înregistrări noi în tabela judeţe,
vom adăuga toate câmpurile disponibile.
View-urile care se folosesc pentru a salva date în tabele trebuie să fie unu la unu cu tabela,
adică să conţină toate câmpurile tabelei şi numai ale acesteia.
Click pe butonul Add All>>. În ListBox-ul Selected fields au fost adăugate toate câmpurile care le
va conţine view-ul nostru (fig. 9.11).
Pagina 61 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.11
Mai departe. Click pe tab-ul Join. Aici se stabilesc legăturile între câmpurile tabelelor din care se
compune view-ul. Nu e cazul la noi momentan, deoarece avem o singură tabelă.
Click pe Filter. Nici aici nu avem ce face. Nu e nevoie să filtrăm judetele după nici un criteriu.
Click pe Order By. În schimb aici vom selecta câmpul denjud (denumirea judetului) pentru a face o
ordonare alfabetică a numelor de judeţ. Este mai elegant (fig. 9.12).
Pagina 62 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.12
Click pe Group By. Aici putem să grupăm datele din tabele după diferite câmpuri. Nu e cazul la
noi.
Pagina 63 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.13
Pentru combo-ul Table este selectat Judete. E OK. Tabela aceasta ne interesează. Faceţi click pe
bifa de sub cheiţa galbenă, să dispară toate bifele (fig. 9.14).
Figura 9.14
Apăsaţi butonul Reset Key. A apărut din nou bifa pentru câmpul id, care este cheie primară.
Apăsaţi butonul Update All. Bifele sunt puse înapoi, la fel ca în fig. 9.13. Asta înseamnă că toate
câmpurile care au bifa pusă pe coloana cu creionul vor fi câmpuri în care vom trimite update-uri (vom
scrie în ele).
Ce vedem însă este faptul că pentru id nu avem bifă sub creion. Asta înseamnă că pentru acest
Pagina 64 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
cîmp nu vom trimite update. În momentul salvării datelor, câmpul fiind de tip autoincrement îşi va adăuga
singur valoarea nouă.
Mai apare un CheckBox: Send SQL updates. Acesta va trebui obligatoriu bifat dacă vrem ca datele
noastre din view să fie salvate în tabelă. Bifăm. Butoanele radio din dreapta le lăsăm asa cum sunt.
Faceţi click dreapta în jumătatea superioară a ferestrei View Design şi alegeţi View SQL. Se
deschide o fereastră unde putem vedea codul pus de VFPro. Închideţi fereastra şi faceţi din nou clic
dreapta apoi alegeţi Run Query. Se deschide o fereastră Browse goală (încă nu avem înregistrări).
Închideţi-o.
Salvăm view-ul cu numele v_nom_judet şi închidem. În Project Manager a apărut view-ul (fig.
9.15).
Figura 9.15
Deschidem formul frm_nom_judet în design mode, click pe Data Environment (fig. 9.1) şi
selectăm optiunea Views (fig. 9.16).
Figura 9.16
Pagina 65 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
După cum se vede view-ul nostru este acolo. Click pe butonul Add.. apoi pe Close. Data
Environment-ul are adus view-ul nostru (fig. 9.17).
Figura 9.17
Click pe fereastra Data Environment – frm_nom_judet. Urmăriţi câte se pot seta în fereastra
Properties. Selectaţi apoi view-ul V-nom_judet. Urmăriţi din nou fereastra Properties. Aici este de fapt
adevăratul centru de control. De aici trebuiesc făcute setările.
Închideţi fereastra Data Environment şi apoi selectaţi form-ul frm_nom_judet. Mergeţi în fereastra
Properties şi selectaţi DataSession. Valoarea setată este 1 – Default Data Session. De câte ori deschidem
VFPro implicit suntem în Default Datasession. Asta înseamnă de fapt sesiunea de date curentă. Apăsaţi
tasta F1. Se va deschide Help-ul. După cum vedeţi şi de aici se poate apela Help-ul, contextual.
?SET("Deleted") + Enter
Pagina 66 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.18
?SET("Deleted") + Enter
Pe form, sub textbox-ul txtDenumire apare valoarea întoarsă: OFF (fig. 9.19).
Figura 9.19
Pagina 67 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Cu alte cuvinte în sesiunea de date a VFPro avem setat Set Deteted pe ON, iar în noua sesiune de
date privată avem setat Set Deleted pe OFF. Asta înseamnă că într-o sesiune de date privată nu se
păstrează toate setările făcute în altă sesiune. Bine de ştiut. Pentru a afla ce se schimbă într-o sesiune de
date privată, în Help apare lista în tab-ul Index, dacă tastaţi “set datasession”.
În momentul în care vrem să salvăm o înregistrare într-o tabelă, VFPro va trebui să blocheze
înregistrarea în cauză până când aceasta va fi salvată. Există două posibilităţi:
1. înregistarea este blocată din momentul în care utilizatorul începe să facă schimbări şi nu va putea
nimeni să modifice înregistrarea în cauză până nu se salvează modificările începute – Pessimisting
locking;
2. VFPro blochează înregistrarea doar în momentul în care modificările sunt trimise în tabelă. Asta
înseamnă că şi un alt utilizator poate modifica şi salva aceeaşi înregistrare fără probleme, în timp
ce ea mai este modificată – Optimistic loocking.
Haideti sa discutăm putin şi despre Buffering. Avem un view făcut. Dacă modificăm datele în acest
view ele pot să nu fie scrise imediat în tabelă, ci sunt ţinute într-o zonă numită buffer, atâta timp cât noi nu
executăm o comandă care să trimită aceste date în tabelă (Tableupdate). Ca şi comparaţie aş folosi Excel-
ul. Scriem sau ştergem ce vrem, dar atâta timp cât nu salvăm, pe HDD avem fişierul nemodificat.
Valorile pe care le poate lua buffering-ul pentru tabele sunt de la 0 la 5.
Închideţi toate form-urile şi deschideţi form-ul frm_nom din Project Manager. Deschideţi şi
fereastra Data Environment, selectaţi tabela judeţe (click pe ea) şi verificaţi valorile care le poate lua
buffering-ul în fereastra Properties/BufferModeOverride (fig. 9.20).
Figura 9.20
Se poate vedea că buffering-ul poate fi aplicat atât la nivel de înregistrare cât şi la nivel de tabelă.
Acesta poate fi Pessimistic sau Optimistic d.p.d.v. al blocajelor. Închideţi fereastra Data Environment şi
selectaţi form-ul. Verificaţi în fereastra Properties ce valori poate lua BufferMode (fig. 9.21).
Pagina 68 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.21
Figura 9.22
În concluzie avem buffering pentru tabele cu valori de la 0 la 5, buffering pentru view-uri cu valori
1, 3 şi 5 şi buffering pentru form-uri cu valori de la 0 la 2. Trebuie ştiut însă că buffering-ul pentru form-
uri se referă doar la tipul blocajelor pentru tabele (None, Pesimistic şi Optimistic). Nu putem controla prin
această setare buffering-ul tabelelor.
Deschideţi clasa b_frm din biblioteca b_forms şi modificaţi BufferMode pe 2 – Optimistic. Toate
form-urile noastre vor moşteni această modificare.
Deschideţi fereastra Data Session Window (fig. 9.4) , clik pe butonul Open şi alegeţi tabela judete.
În acest moment tabela este deschisă. Tastaţi în fereastra de comenzi:
?CURSORGETPROP("Buffering")
Pagina 69 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
apoi apăsaţi concomitent tastele Shift+Ctrl+Alt. Funcţia întoarce o valoare care depinde de setările făcute
în Tools/Options.../Data/Buffering.
Tastaţi în fereastra de comenzi:
CURSORSETPROP("Buffering",1)
?CURSORGETPROP("Buffering")
Până aici am povestit despre buffering în general. Dar în aplicaţie ce setări vom folosi?
Recomandarea mea ar fi să se folosească form-urile cu BufferMode pe 2 – Optimistic (în fereastra
Properties) şi tabelele (view-urile) pe 5 – Optimistic table buffering.
Închidem tot, mai puţin Project Manager-ul, Command Window şi fereastra Properties, alegem
biblioteca b_forms, selectăm clasa b_frm şi o deschidem (Modify) şi setăm proprietatea BufferMode pe 2
– Optimistic.
Mergem în Tools/Options.../Data şi setăm Buffering: Off (fig. 9.23). Setările pentru buffering le
vom face pentru fiecare view în parte.
Figura 9.23
Se poate vedea că este pusă bifa în CheckBox-ul Multiple Record Locks. Dacă nu a fost pusă veţi
primi un mesaj care vă va anunţa că este nevoie de această setare. Echivalentul este cel al comenzii:
SET MULTILOCKS ON
Pagina 70 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
?Set("Multilocks")
În acest moment am terminat cu setările pentru Buffering ale nomenclatorului. Putem trece mai
departe.
Avem în momentul de faţă trei form-uri în Project Manager. Acestea provin toate din biblioteca
b_forms clasa b_frm. Vom face o corecţie. În QueryUnload vom schimba în linia a cincea iconul care va fi
afişat în fereastra de mesaj dela 32 la 48. Linia corectata arată astfel:
La FoxPro Revolutions s-a discutat această problemă. Microsoft recomandă folosirea triunghiului
cu semnul exclamării în locul semnului întrebării.
Rulaţi cele trei form-uri. La închidere se poate observa schimbarea. Cu alte cuvinte am intervenit
într-un singur loc şi am împuşcat trei iepuri (puteau fi mai mulţi, ce-i drept).
O a doua schimbare o vom face în clasa b_cmd din biblioteca b_std. Fontul (FontName) îl vom
seta pe Tahoma (specific Microsoft) iar mărimea scrisului (FontSize) pe 8. De asemenea înălţimea
butonului o vom seta pe 24 (Height). Acum nici nu vreau să mă gândesc câţi iepuri am împuşcat. Uşor,
nu-i aşa?
A treia schimbare o vom face pentru b_lbl tot din biblioteca b_std. FontName = Tahoma iar
FontSize = 8. Acelaşi lucru şi pentru: b_cbo, b_chk, b_lst şi b_txt. Rulaţi din nou form-urile. Se pot vedea
schimbările. Câţi iepuri am împuşcat? Fără număr...
Deschidem din nou în design mode form-ul frm_nom_judet, iar pentru label-ul de de-asupra
ListBox-ului schimbăm proprietatea Caption în “Judete introduse:”. După cum se poate observa,
AutoSize-ul din base class şi-a făcut datoria.
O să vreau să ataşez şi o imagine care să apară în dreptul fiecărui judeţ din ListBox. Pentru asta va
trebui să setăm în proprietatea Picture a ListBox-ului calea spre poza noastră. Voi pune această poză în
clasa a_frm_nom din biblioteca a_nom (poza se numeşte lstimg.bmp şi se află în ProFox\Images). Ceea
ce înseamnă că toate nomenclatoarele instanţiate din această clasă vor moşteni imaginea.
Verificaţi dacă a apărut imaginea în form-ul frm_nom_judet (în design mode, deaorece încă nu
avem înregistrări ca să o vedem în runtime). Deschideţi şi form-ul frm_nom în design mode. Aici nu mai
apare. Vă reamintesc că acest form a fost făcut doar de probă şi este instanţiat din clasa
b_frm_nomenclator. Ierarhic clasa a_frm-nom este sub clasa b_frm_nom. Moştenirea merge de sus în jos.
Pagina 71 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
O să ami pun încă o imagine în clasa a_frm-nom, sub butonul de Sterge. Pentru asta deschid clasa
a_frm_nom, micşorez fereastra clasei astfel încât să se vadă şi fereastra Project Manager (fig. 9.24).
Figura 9.24
Din biblioteca a_std trag cu mouse-ul clasa a_img în fereastra cu nomenclatorul (se vede în
inaginea 9.24 că eu deja am făcut-o). Acesta este un alt mod de a instanţia.
Pentru imaginea proaspăt adăugată setăm imaginea frmnom.png din ProFox\Images, după care:
● Height 48
● Width 48
● Left 312
● Top 301
● Stretch 2 – Stretch
Pagina 72 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Figura 9.25
Închidem form-ul şi deschidem clasa a_frm_nom din biblioteca a_nom. Modificăm proprietăţile de
mai jos:
Salvăm şi rulăm form-ul frm_nom_judet. La închidere se pot vedea cele doua modificări făcute
mai sus. Toate nomenclatoarele noaste vor avertiza cu un mesaj că vor fi închise.
Haideţi să pregătim terenul pentru primele noastre înregistrări. Deschideţi form-ul frm_nom_judeţe
în design mode. Selectaţi ListBox-ul şi setaţi următoarele în fereastra Properties:
● RowSourceType = 2- Alias
● RowSource = v_nom_judet.denjud
Deschideţi clasa b_cmg_set din biblioteca b_cmd şi în afară de butonul Adauga pentru toate
celelalte (cmdModifica, cmdSalveaza, cmdRenunta, cmdSterge) setaţi Enabled pe .F.
Deschideţi apoi clasa b_frm_nom din biblioteca b_nom şi adăugaţi următoarele metode form-ului:
● adauga
● modifica
● renunta
Pagina 73 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
● salveaza
● sterge
● txtdisabled
● txtenabled
Adaugaţi şi proprietatea:
● modificat
Setaţi pentru txtDenumire Enabled pe .F. (când rulăm form-ul va fi inactiv. Va deveni activ dacă
modificăm sau adăugăm înregistrări).
With Thisform
.cmgSet.cmdSterge.Enabled= .T.
.cmgSet.cmdModifica.Enabled= .T.
Endwith
Butoanele pentru ştergere şi modificare sunt inactive. Pentru a le activa e suficient să selectaţi o
valoare în ListBox-ul lstValoriIntroduse.
Pentru a avea acces mai rapid la butoanele Adauga, Modifica, Salveaza, Renunta, Sterge faceţi
click dreapta pe container şi alegeţi Edit (fig. 9.26).
Figura 9.26
Pagina 74 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
O altă posibilitate este să ţineţi tastele Ctrl+Shift apăsate şi să faceţi click pe unul din butoane.
DoDefault()
Thisform.adauga()&& Execut metoda de adaugare inregistrari
DoDefault() va executa metoda din clasa părinte. Pentru a vedea care este aceasta, click pe
butonul View Parent Code. Se va deschide o fereastră ca cea din fig. 9.27.
Figura 9.27
După ce se execută metoda din fig. 9.27 execuţia va continua cu linia a doua:
Thisform.adauga()
Prin această linie apelăm metoda adauga, făcută ceva mai sus.
Prima linie execută codul din metoda afisare_mesaj, pe care am adăugat-o clasei b_cmdset din
biblioteca b_cmd. Codul este următorul:
Dacă metoda întoarce .T., adică s-a apăsat butonul OK (utilizatorul vrea să modifice înregistrarea),
se execută codul pentru resetarea butoanelor, corespunzator fig. 9.27, apoi metoda de modificare a
înregistrărilor.
Pagina 75 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Primul If verifică dacă userul nu a lăsat TextBox-ul txtDenumire gol. Mesajul l-am trecut direct în
cod. Se poate folosi şi varianta de a folosi proprietăţi, ca în cap. 5 pag. 27.
Aici mai apare o ramnificare cu al doilea Else. Dacă nu se apasă butonul OK ci Cancel, nu se
execută metoda renunta() şi focusul e mutat înapoi în TextBox-ul txtDenumire.
x="tabela.camp"
?JustStem(x)
Pagina 76 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
Valoarea întoarsă va fi tabela. Deci cu această funcţie extragem numele tabelei din proprietatea
RowSource a ListBox-ului lstValoriIntroduse.
Scriem următorul cod în metoda modifica a form-ului:
With This
.lstValoriIntroduse.Enabled= .F.&& Nu permit mutarea cursorului in view
.txtenabled()&& Activex textbox-ul si leg view-ul de el
.modificat=.T. && Anunt butonul de salvare ca am modificat o inregistrare
.txtDenumire.SetFocus()
Endwith
Apare valoarea .T. pentru proprietatea modificat. Această proprietate o să fie explicată la metoda
salveaza.
With This
.lstValoriIntroduse.Enabled= .T.&& Listbox-ul devine activ pentru selectii
.txtdisabled()&& Dezactivez textbox-ul si sterg sursa lui de date
Endwith
Select Juststem(Thisform.lstValoriIntroduse.RowSource)&& Ma asigur ca este selectat
view-ul
Tablerevert(.T.)&& Renunt la inregistrarea goala !!!
Dacă am făcut vreo modificare în view sau am adăugat o nouă înregistrare fără să fi salvat,
comanda: Tablerevert(.T.) anulează toate aceste lucruri pentru toate campurile modificate şi nesalvate
din view.
With This
.lstValoriIntroduse.Requery()&& Repopulez listbox-ul cu valori
If .modificat=.T.&& Inregistarea este modificata
.modificat=.F.&& Pun valoarea inapoi (se poate modifica doar o
inregistrare)
.cmgSet.cmdAdauga.Enabled= .T.
.cmgSet.cmdRenunta.Enabled= .F.
.cmgSet.cmdSalveaza.Enabled= .F.
.txtdisabled()&& Dezactivez view-ul si sterg sursa de date
Else
Append Blank&& Adaugam o noua inregistrare goala
.txtDenumire.SetFocus()&& Mutam focusul in textbox
Endif
Endwith
Prima linie înlocuieşte valoarea din campul id_user_add cu id-ul userului care adaugă înregistrarea
(userul logat). Am folosit aşa linia aceasta pentru că toate tabelele din baza noastră de date au câmpul
Pagina 77 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
_Screen.AddProperty("id_user_log")
_Screen.id_user_log=1
Se poate vedea în fereastra de comenzi că proprietatea a fost adăugată şi i-a fost atribuită valoarea
1 (fig. 9.28).
Figura 9.28
Până ajungem la logarea user-ului în aplicaţie am pus codul de mai sus în setpath.prg. De
câte ori deschideţi proiectul rulaţi acest prg pentru a nu apărea erori.
Linia a doua – Tableupdate(2,.T.) - salvează datelor în tabelă. Atât. O singură linie. Mai mult,
dacă în view avem modificate o sută de linii care nu au fost încă salvate, toate vor fi salvate după
executarea liniei de mai sus. Super, nu?
În linia a şasea apare codul: If .modificat=.T. . Ideea este următoarea: nomenclatorul este
Pagina 78 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
gândit să permită userului să adauge mai multe înregistrări, una după alta, făcând o singură dată click pe
butonul de adăugare. La fiecare salvare butonul execută codul şi rămâne activ, în view făcându-se un
Append Blank pentru o nouă înregistrare care aşteaptă să fie salvată.
Nu acelaşi lucru este atunci când se modifică o înregistrare. De obicei vrei să modifici una singură,
iar după salvare butonul devine inactiv. Asa că semnalizez prin această proprietate dacă metoda de salvare
lucrează după o modificare sau după adăugarea unei noi înregistrări.
With This
.txtDenumire.ControlSource="" && Am eliberat textbox-ul de view
.txtDenumire.Value="" && Curat textbox-ul de valori
.txtDenumire.Enabled= .F. && Textboxul este inactiv
.lstValoriIntroduse.Enabled= .T.&& Activez listbox-ul pentru a permite selectii
Endwith
respectiv
With This
.txtDenumire.Enabled= .T. && Textboxul este activ
.txtDenumire.ControlSource=.lstValoriIntroduse.RowSource&& Am legat textbox-ul
de view
.lstValoriIntroduse.Enabled= .F.&& Dezactivez listbox-ul pentru a nu permite
mutarea cursorului
Endwit
Aceste metode au rolul de a lega şi dezlega view-ul de textbox-ul txtDenumire. Dacă nu am face
treaba aceasta, s-ar vedea valorile în txtDenumire când acesta ar avea proprietatea Enabled pe .F. .
Mai sus am povestit despre faptul ca o sesiune de date privata modifica unele setari, printre care şi
Set Deleted (fig. 9.19). Pentru moment o să punem în evenimentul Load al clasei a_frm_nom din
biblioteca a_nom codul:
Set Deleted On
Fceţi un view nou pentru tabela tipcontact şi numiţi-l v_tipcontact. Paşii şi setările sunt identici, ca
Pagina 79 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5
la view-ul v_nom_judet.
Cam atat am avut de facut pentru al doilea nomenclator. Putin, nu-i aşa?
Pagina 80 din 80