Sunteți pe pagina 1din 80

Visual FoxPro – Contacts pentru începători Versiunea 1.

Cuprins

CAP 1. Controlul mediului de lucru ............................................................................................... 3

• Crearea directorului de lucru


• Primii paşi
• Ajutor din partea ... Help-ului
• Rezumat

CAP 2. Crearea unui proiect ........................................................................................................... 6

• Proiect fără wizard


• Rezumat

CAP 3. Biblioteci de clase şi clase ................................................................................................... 7

• Crearea bibliotecilor de clase


• Crearea claselor base class
• Crearea claselor application class
• Proprietăţi, metode, evenimente
• Rezumat

CAP 4. Căi de căutare ...................................................................................................................... 18

• Ce ştie şi ce nu ştie VFPro de subdirectoarele noastre


• Rezumat

CAP 5. Utilizarea şi utilitatea claselor ............................................................................................. 23

• Folosirea propriilor clase


• Adăugarea propietăţilor
• Rezumat

CAP 6. Baze de date – proiectare..................................................................................................... 32

• Cum proiectăm o bază de date


• Rezumat

CAP 7. Baze de date – execuţie ........................................................................................................ 36

• Crearea bazei de date


• Rezumat

CAP 8. Nomenclatoare ..................................................................................................................... 47

• Rezumat

Pagina 1 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Câteva cuvinte...

Aplicaţia va fi scrisă în VFPro 9 cu SP1. Nu o să merg pentru compatibilitate la versiuni anterioare.

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:

• Crearea directorului de lucru.


• Crearea unui proiect fără ajutorul wizard-ului.
• Crearea bibliotecilor de clase.
• Crearea claselor de bază pe două nivele – base şi application.
• Crearea claselor derivate.

Pagina 2 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

CAP 1. Controlul mediului de lucru

• Crearea directorului de lucru

Pornim de la început cu ideea că acest director al aplicaţiei poate fi oriunde pe disc şi


aplicaţia va putea rula din orice locaţie. Personal am să-l creez pe partiţia D:\ şi-l voi numi ProFox
(fig.1.1). Vom avea nevoie de mai multe subdirectoare în care să păstrăm separat obiecte asemănătoare
(form-uri, rapoarte, bibliotecile de clase). Această structură permite setarea căilor de căutare (vom vedea
ceva mai încolo) şi permite o regăsire uşoară.

Figura 1.1

• Primii paşi

Se porneşte VFPro, fără a avea deschis vreun proiect, ci numai fereastra de comenzi, Command
Window.

Unde ne aflăm de fapt?

Tastaţi în fereastra de comenzi:

?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:

?SET("Default")- întoarce D:\


?CURDIR()- întoarce: \PROFOX\
?FULLPATH("") - întoarce D:\PROFOX\

La fel verificaţi şi comenzile:

?SYS(5)
?SYS(2003)
?SYS(5)+SYS(2003)

Există o metodă pe care o folosesc personal.

Tastaţi:

SET DEFAULT TO + Enter (ştergem setările de până acum)

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 ? ).

Tastaţi din nou:

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

• Ajutor din partea... Help-ului

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

CAP 2. Crearea unui proiect

• Proiect fără wizard

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

CAP 3. Biblioteci de clase şi clase

• Crearea bibliotecilor de clase

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ă.

Sper că v-am convins, aşa că trecem la treabă.Tastaţi în fereastra de comenzi:

CREATE CLASSLIB + Enter

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

După modelul de mai sus vom creea următoarele biblioteci:

• 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ă.

Aşa ar trebui să apară proiectul nostru acum (fig. 3.2).

Pagina 8 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Figura 3.2

• Crearea claselor base class

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.

Confirmăm cu OK şi se va deschide fereastra Class Designer, ca în fig. 3.4.

Pagina 9 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Figura 3.4

Aceasta este prima clasă creată. Felicitări!


Dar ce este de fapt o clasă? O definiţie a unui obiect, care conţine infomaţii despre cum arată (vom folosi
proprietăţile clasei pentru aceasta) şi cum trebuie să se comporte (vom folosi metodele clasei). După cum
probabil aţi constatat, CheckBox-ul nu poate fi folosit, aşa cum apare aici, ca şi clasă. Putem să facem
click pe el mult şi bine. Pentru asta va trebui să instanţiem această clasă (nimic altceva decât să tragem cu
mouse-ul de ea pe un formular şi gata – din clasă am făcut un obiect).

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:

CommandButton – prescurtat b_cmb


CommandGroup – prescurtat b_cmg
Container – prescurtat b_cnt
Custom – prescurtat b_cus
Grid – prescurtat b_grd
Image – prescurtat b_img
Label – prescurtat b_lbl
ListBox – prescurtat b_lst
Page – prescurtat b_pag
PageFrame – prescurtat b_pfr
Shape – prescurtat b_shp
TextBox – prescurtat b_txt

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ă.

Va trebui să revenim asupra claselor b_cmg şi b_pfr ceva mai încolo.

După ce terminăm, Project Manager-ul trebuie să arate ca în figura 3.7.

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

A sosit momentul să derivăm clase din propriile noastre clase.

• selectaţi biblioteca b_forms din Project Manager. Apăsaţi butonul New... .


• în fereastra New Class care se deschide apăsăm butonul cu trei puncte ... din dreptul ComboBox-
ului Based On: .
• se deschide fereastra Open unde selectăm biblioteca b_forms.vcx iar în dreapta vom avea selectat
b_frm, care nu este alta decât clasa creată de noi mai devreme. Confirmăm cu Open (fig. 3.10).

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?

Aşa ar trebui să arate în acest moment proiectul (fig. 3.13).

Figura 3.13

• Crearea claselor application class

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.

• Proprietăţi, metode, evenimente

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.

În concluzie: putem gestiona obiectele prin intermediul proprietăţilor, metodelor şi al


evenimentelor.

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

CAP 4. Căi de căutare

• Ce ştie şi ce nu ştie VFPro de subdirectoarele noastre

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:

CD ? + Enter. Alegeţi directorul ProFox (dacă nu este încă directoul curent).

SET PATH TO + Enter (ştergem toate căile de căutare care ar putea exista setate de noi).

CREATE FORM test as a_frm_modless FROM a_forms + Enter.

(vrem să facem un formular pe care să-l cheme test, din clasa a_frm_modless care aparţine bibliotecii
a_forms).

Vom obţine un mesaj de eroare ca cel din fig. 4.1.

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

În fereastra care se deschide scrieţi:

Set Path To " Data;Forms;Images;Libs;Menus;Programs;Reports"

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

Acum să vedem şi beneficiile. Tastaţi din nou:

CREATE FORM test as a_frm_modless FROM a_forms + Enter

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:

SET PATH TO "Temp" + Enter

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:

Set Path To " Data;Forms;Images;Libs;Menus;Programs;Reports" Additive

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

CAP 5. Utilizarea şi utilitatea claselor

• Folosirea propriilor clase

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

If Messagebox('Vrei sa inchizi formularul?',3+32,'Atentie !')=6


Thisform.Release
Endif

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

Trebuie să se deschidă o fereastră ca cea din fig. 5.9.

Figura 5.9

Completaţi după cum urmează:

• Name: afisez_mesaj
• Defaut/Initial Value: .T.
• Description: Comutator pentru afisarea sau inhibarea mesajului de închidere.

apoi click pe Add.... Prima noastră proprietate a fost adăugată. Următoarea:

• Name: mesaj
• Defaut/Initial Value:

Pagina 27 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

• Description: Mesajul care va fi afişat la închiderea formularului.

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.

Salvaţi şi închideţi. Fereastra Properties trebuie să arate ca în fig. 5.10.

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

fereastra Properties şi bifaţi Property Descriptions (fig. 5.11).

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:

If This.afisez_mesaj=.F.&& Nu afisez mesaj


DoDefault()
Return .T.
Else
If Messagebox(This.mesaj,4+32,This.mesaj_titlebar)=6 && Am apasat OK
DoDefault()
Return .T.
Else
Nodefault
Return .F.
Endif
Endif

Salvaţi şi închideţi. Deschideţi formularul test. În evenimentul Click, înlocuiţi vechiul cod:

If Messagebox('Vrei sa inchizi formularul?',3+32,'Atentie !')=6


Thisform.Release
Endif

cu următorul:

If Thisform.QueryUnload()&& daca se executa metoda din eveniment


Thisform.Release&& inchide formularul
Endif

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.

Scrieţi în proprietatea afisez_mesaj: Vrei sa inchizi formularul ? Iar în proprietatea mesaj_titlebar:


ATENTIE !, ca în fig. 5.12.

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... .

Am atins două obiective majore. Rapiditate şi întreţinere uşoară.

Pagina 31 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

CAP 6. Baze de date – proiectare

• Cum proiectăm o bază de date

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.

Pe baza aceluiaşi raţionament continuăm cu judeţele.

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

Proiectarea bazei de date ar trebui să urmărească un “set” minim de reguli:

• 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

CAP 7. Baze de date – execuţie

• Crearea bazei de date

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:

• nume lungi câmpuri


• valori implicite
• reguli la nivel de câmp şi înregistrare etc.

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

După toate astea, Project Manager-ul trebuie să arate ca în fig. 7.10.

Figura 7.10

Pagina 42 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Urmînd aceeaşi paşi facem şi următoarele tabele:

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()).

Project Manager-ul trebuie să arate ca în fig. 7.11.

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

fereastră asemănătoare cu cea din fig. 7.12.

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:

• id din tabela localitati tragem peste id_loc din tabela firma;


• id din tabela tipcontact peste id_tipcont din tabela contact_firma;
• id din tabela firma peste id_firma din tabela contact_firma.

În final baza noastră de date trebuie să arate ca în fig. 7.13.

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

id – cheia unică pentru tabela user;


denuser – numele şi prenumele user-rilor;
id_user_add – ID-ul userului care adaugă înregistrarea
data_add – data şi ora la care s-a adăugat înregistrarea.

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ă.

Facem o nouă bibliotecă:

● nume bibliotecă: b_nom (nomenclator de bază)


● salvează în: ProFox\Libs

Adăugaţi-o în Project Manager.

Facem o nouă clasă:

● nume clasă: b_frm_nom (form pt. nomenclatorul de bază)


● clasa părinte: b_frm_modal
● biblioteca clasei părinte: b_forms
● biblioteca în care salvăm: b_nom

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.

În acest moment form-ul nostru ar trebui să arate ca în fig. 8.1.

Pagina 47 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Figura 8.1

Vom redenumi TextBox-ul în fereastra Properties/Name cu txtDenumire, iar ListBox-ul cu


lstValoriIntroduse. Aceste denumiri noi ne vor ajuta pe parcurs să le găsim mai uşor când tastăm cod, fără
să ne gândimce-o fi însemnând oare List1 sau ceva similar.

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.

Facem o nouă clasă:

● nume clasă: b_cmg_set (set de butoane de bază)


● clasa părinte: b_cmg
● biblioteca clasei părinte: b_std
● biblioteca în care salvăm: b_cmd

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:

● nume clasă: b_cmdset


● clasa părinte: b_cmd
● biblioteca clasei părinte: b_std
● biblioteca în care salvăm: b_cmd

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

Modificăm numărul de butoane la 5 (Adauga, Modifica, Salveaza, Renunta, Sterge) în fereastra


Properties/ButtonCount.

Acum clasa noastră ar trebui să arate ca în fig. 8.5.

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

Modificăm proprietăţile Name pentru butoane din fereastra Properties în cmdAdaugă,


cmdModifica, cmdSalveaza, cmdRenunta şi cmdSterge. Le vom găsi astfel foarte uşor când vom tasta cod.

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

Modificăm în fereastra Properties/Name numele containerului cu butoane (click cu mouse-ul pe el


întâi) în cmgSet.

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

Completaţi după cum urmează:

• 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.

Completaţi după cum urmează:

● Name: afisare_mesaj
● Description: Metoda de management mesaje pt. butoane

În metoda arata_mesaj a butonului scriem următorul cod:

If This.afisez_mesaj=.T.&&Vreau sa apara fereastra mesaj


If Messagebox(This.mesaj,4+48,This.mesaj_titlebar)=6&&Am apasat OK
Return .T.
Else
Return .F.
Endif
Endif

Haideţi să facem o probă. În fereastra de comenzi tastăm:

CREATE FORM frm_nom as b_frm_nom FROM b_nom

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

apăsarea butonului Adauga butoanele Modifica şi Sterge trebuie să devină inactive.

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.

Codul din butonul Adauga:

With This
.Enabled= .F.
.Parent.cmdModifica.Enabled= .F.
.Parent.cmdSterge.Enabled= .F.
.Parent.cmdRenunta.Enabled= .T.
.Parent.cmdSalveaza.Enabled= .T.
Endwith

Codul din butonul Modifica:


With This
.Enabled= .F.
.Parent.cmdSterge.Enabled= .F.
.Parent.cmdAdauga.Enabled= .F.
.Parent.cmdSalveaza.Enabled= .T.
.Parent.cmdRenunta.Enabled= .T.
Endwith

Codul din butonul Salveaza: ( nu avem cod)

Codul din butonul Renunta:

With This
.Enabled= .F.
.Parent.cmdAdauga.Enabled= .T.
.Parent.cmdSalveaza.Enabled= .F.
Endwith

Codul din butonul Sterge: ( nu avem cod)

Restul codului o să-l punem când avem şi datele în controale.

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

CAP 9. Data Environment; view-uri

Indiferent de cum proiectezi aplicatia, de un lucru nu scapi: accesul la date. Variantele clasice sunt
ceva de genul:

Open Database ...


Set Database To ...

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

Se deschide o fereastră în fundal, inactivă: Data Environment – frm_nom.scx şi deasupra ei


fereastra Add Table or View (fig. 9.2).

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

Închidem fereastra Data Environment, setăm în fereastra Properties/WindowsType pe 0 – Modless


(să putem avea acces la butoanele din Toolbar) pentru frm_nom. Ne asigurăm că nu avem nici o tabelă
deschisă, tastând în fereastra de comenzi:

Pagina 57 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

CLEAR ALL + Enter

Deschidem fereastra Data Session Window (fig. 9.4).

Figura 9.4

În fereastra care se deschide nu apare nici o tabela deschisă (fig. 9.5).

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_).

Haideţi să facem primul nostru nomenclator adevărat. Tastaţi în fereastra de comenzi:

CREATE FORM frm_nom_judet as a_frm_nom FROM a_nom

File/Save As... şi salvaţi în ProFox\Forms. Adăugaţi-l în Project Manager.

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.

Click pe Update Criteria. Deja devine interesant (fig. 9.13).

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.

În fereastra de comenzi tastaţi:

SET DELETED ON + Enter apoi

?SET("Deleted") + Enter

Apăsăm concomitent tastele Shift+Ctrl+Alt şi vedem că într-adevăr setarea este ON.

Modificaţi pentru form-ul nostru DataSession la valoarea 2 – Private Data Session şi


WindowsType la valoarea 0 – Modless (pentru a avea acces la fereastra Command). Rulaţi form-ul,
deschideţi fereastra Data Session Window (fig. 9.4) şi selectaţi sesiunea de date A_frm_nom1(2). Vedem
că tabela şi view-ul sunt acolo. În acest moment suntem în sesiunea de date privată.

Pagina 66 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

Figura 9.18

Închideţi fereastra Data Session şi tastaţi din nou în fereastra de comenzi:

?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

Închideţi form-ul frm_nom şi deschideţi form-ul frm_nom_judet. Deschideţi şi Data Environment.


Selectaţi view-ul v_nom_judet şi verificaţi din nou proprietatea BufferModeOverride (fig. 9.22).

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)

apoi din nou:

?CURSORGETPROP("Buffering")

Apăsaţi concomitent tastele Shift+Ctre+Alt. Valoarea întoarsă este 1.

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

Se poate afla starea cu comanda:

?Set("Multilocks")

Apăsăm butoanele SetAs Default şi OK.

Deschidem frm_nom_judet, deschidem şi fereastra Data Environment, selectăm v_nom_judet şi în


fereastra Properties setăm BufferModeOverride pe 5 – Optimistic Table Buffering.

Î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:

If Messagebox(This.mesaj,4+48,This.mesaj_titlebar)=6 && Am apasat OK

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 form-ul frm_nom_judet în design mode şi pentru label-ul de deasupra TextBox-ului


schimbăm în fereastra Properties Caption în “Denumire judet:” Observăm că nu se vede tot textul.
Închidem şi mergem în biblioteca b_std, deschidem clasa b_lbl şi setăm proprietatea AutoSize pe .T. .

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

Salvăm şi închidem clasa. Deschidem form-ul frm_nom_judet în design mode şi schimbăm


proprietatea Caption a form-ului în “Nomenclator judete”. Salvăm şi rulăm form-ul. Ar trebui să arate ca
în fig. 9.25.

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:

● mesaj = Nomenclatorul va fi închis. Continui ?


● mesaj_titlebar = Atentie !

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).

În evenimentul Click al ListBox-ului lstValoriIntroduse scrieţi următorul cod:

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.

Selectaţi butonul adaugă. În evenimentul Click al acestuia punem următorul cod:

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.

Acest principiu se aplică în general pentru toate butoanele.

Selectaţi butonul Modifica. În evenimentul Click al acestuia punem următorul cod:

If This.afisare_mesaj()&& Execut metoda de afisare a mesajului


DoDefault()&& Resetez butoanele
Thisform.modifica()&& Execut metoda de modificare a inregistrarilor
Endif

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:

If This.afisez_mesaj=.T.&&Vreau sa apara fereastra mesaj


If Messagebox(This.mesaj,4+48,This.mesaj_titlebar)=6&&Am apasat OK
Return .T.
Else
Return .F.
Endif
Endif

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.

Selectaţi butonul Salveaza. În evenimentul Click al acestuia punem următorul cod:

Pagina 75 din 80
Visual FoxPro – Contacts pentru începători Versiunea 1. 5

If Empty(Thisform.txtDenumire.Value) && Nu s-a introdus nici o valoare


Messagebox("Nu se pot salva inregistrari vide. Corecteaza.",48,"Atentie !")
Thisform.txtDenumire.SetFocus()&& Mut focusul in textbox
Else
If This.afisare_mesaj()&& Execut metoda de afisare a mesajului
DoDefault()&& Resetez butoanele
Thisform.salveaza()&& Execut metoda de salvare a datelor
Endif
Endif

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.

Restul este ca şi la celelalte metode.

Selectaţi butonul Renunta. În evenimentul Click al acestuia punem următorul cod:

If Empty(Thisform.txtDenumire.Value)&& Nu s-a scris nimic in textbox


DoDefault()&& Resetez butoanele
Thisform.renunta()&& Execut metoda de renuntare
Else&& S-a scris ceva in textbox (prin adaugare sau modificare)
If This.afisare_mesaj()&& Se executa metoda de afisare a mesajului
DoDefault()&& Execut metoda de resetare a butoanelor
Thisform.renunta()&& Execut metoda de renuntare
Else
Thisform.txtDenumire.SetFocus()&& Mut focusul in textbox
Endif
Endif

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.

Selectaţi butonul Sterge. În evenimentul Click al acestuia punem următorul cod:

If This.afisare_mesaj()&& Execut metoda de afisare a mesajului


DoDefault()&& Resetez butoanele
Thisform.sterge()&& Execut metoda de stergere a inregistrarii
Endif

Codul este explicat mai sus.

Scriem următorul cod în metoda adauga a form-ului:

Select Juststem(Thisform.lstValoriIntroduse.RowSource)&&Selectez view-ul


Append Blank&& Adaug o noua inregistrare
With This
.txtenabled()&& Execut metoda de activare textbox si legarea view-ului de el
.txtDenumire.SetFocus()&& Mut focusul pentru a adauga o noua inregistrare
Endwith

Pentru a testa ce face funcţia Juststem tastaţi în fereastra de comenzi:

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

Linia .lstValoriIntroduse.Enabled= .F. o folosim pentru a nu permite utilizatorului să


selecteze valori în ListBox-ul lstValoriIntroduse sau să mute cursorul în view.

Apare valoarea .T. pentru proprietatea modificat. Această proprietate o să fie explicată la metoda
salveaza.

Scriem următorul cod în metoda renunta a form-ului:

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.

Deci cu o singură linie de cod rezolvăm problema.

Scriem următorul cod în metoda salveaza a form-ului:

Replace id_user_add With _Screen.id_user_log&& Adaug in view id-ul userului logat


Tableupdate(2,.T.)&& Salvez datele in tabela !!!
Requery(Juststem(Thisform.lstValoriIntroduse.RowSource))&& Repopulez view-ul

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

acesta cu acelaşi nume.


În general însă este bine să folosim ceva de genul:
Juststem(Thisform.lstValoriIntroduse.RowSource)

care nu ne împiedică să folosim ce denumire vrem pentru tabelele/câmpurile noastre.

_Screen.id_user_log este o proprietate care va fi agăţată de screen în momentul în care


utilizatorul este logat.

Tastaţi în fereastra de comenzi:

_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.

Scriem următorul cod în metoda sterge a form-ului:

Select Juststem(Thisform.lstValoriIntroduse.RowSource)&& Ma asigur ca este selectat


view-ul
Delete && Sterg inregistrarea
Tableupdate(2,.T.)&& Actualizez tabela
Requery(Juststem(Thisform.lstValoriIntroduse.RowSource))&& Repopulez view-ul
Thisform.lstValoriIntroduse.Requery()&& Repopulez listbox-ul

Înregistrarea se şterge cu o singură linie. Tableupdate actualizează ştergerea şi în tabelă.

Metodele txtdisabled şi txtenabled au următorul cod:

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

Faceţi un nou form frm_tip_contact:

Create Form frm_tip_contact as a_frm_nom from a_nom

şi salvaţi-l în ProFox\Forms. Adăugaţi-l în Project Manager.

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.

Adăugaţi view-ul în Data Environment, selectaţi-l şi schimbaţi proprietatea BufferModeOverride în


5 - Optimistic Table Buffering.

Legaţi RowSource-ul listbox-ului lstValoriIntroduse cu valoarea: v_tipcontact.dencontact, salvaţi


şi rulaţi form-ul.

Cam atat am avut de facut pentru al doilea nomenclator. Putin, nu-i aşa?

Pagina 80 din 80

S-ar putea să vă placă și