Aplicatie Dezvoltata In Visual Studio 2013 Pentru Gestionarea Unei Baze DE Date Excel
APLICAȚIE DEZVOLTATĂ ÎN VISUAL STUDIO 2013 PENTRU GESTIONAREA UNEI BAZE DE DATE EXCEL
CUPRINS
INTRODUCERE
CAPITOLUL I. LIMBAJUL DE PROGRAMARE
1.1 CARACTERISTICILE UNUI JIMBAJ
1.2 PRODUSUL MICROSOFT VISUAL STUDIO
1.3 CONSIDERENTE VISUAL C#
CAPITOLUL II. PLATFORMA .NET FRAMEWORK
2.1 INTRODUCERE ÎN .NET FRAMEWORK
2.2 ARHITECTURA .NET FRAMEWORK
2.3 COMPILAREA PROGRAMELOR
CAPITOLUL III. PROGRAMARE ORIENTATĂ PE OBIECTE
3.1 EVOLUȚIA TEHNICILOR DE PROGRAMARE
3.2 TIPURI DE DATE OBIECTUALE. ÎNCAPSULARE
3.3 SUPRAÎNCARCARE
3.4 MOȘTENIRE
3.5 POLIORFISM. METODE VIRTUALE
3.6 PRINCIPIILE PROGRAMĂRII ORIENTATE PE OBIECTE
3.7 STRUCTURA UNEI APLICAȚII C#
3.8 CONSTRUCTORI
3.10 DESTRUCTOR
3.11 METODE
3.12 PROPRIETĂȚI
CAPITOLUL IV. PARTICULARITĂȚI ÎN VISUAL C#
4.1 GESTIONAREA AUTOMATĂ A MEMORIEI
4.2 COMPARAȚIE ÎNTRE C# ȘI C++
CAPITOLUL V. IMPLEMENTAREA ȘI TESTAREA APLICAȚIEI
5.1 PREZENTAREA PROBLEMEI
5.2 DEFINIREA GRUPULUI ȚINTĂ
5.3 DEFINIREA SPECIFICAȚIILOR
5.4 ELABORAREA CODULUI SURSĂ
5.5 GESTIONAREA AUTOMATĂ A MEMORIEI
CONCLUZII
BIBLIOGRAFIE
ANEXA 1 – Codul sursă
INTRODUCERE
Scopul lucrării este dezvoltarea unei aplicații software care să ajute la gestionarea unei baze de date Excel.
Necesitatea lucrării este dată de nevoia de a gestiona o bază de date în Excel ce va cuprinde numele, seria și numărul de echipamente dintr-un stoc. Aplicația intitulată ”Status Report App” va oferi posibilitatea de a adăuga elemente noi și a vizualiza pe cele deja existente, dând utilizatorului posibilitatea de oferi informații referitoare la stoc în cel mai scurt timp.
Datele despre stoc sunt confidențiale și integritatea lor este necesară. Este nevoie de un sistem de securitate care să nu permită accesul neautorizat și o modalitate de a accesa baza de date Excel fără a o modifica direct și risca pierderea de informație.
Aplicația trebuie să aibă o interfață cu utilizatorul simplă și ușor de folosit. Un sistem de înștiințare va fi folosit pentru a alerta utilizatorul asupra succesului sau eșecului unei operații.
Structura lucrării include 5 capitole în care se abordează problema dezvoltării aplicație pentru gestionarea bazei de date Excel.
Capitolul intitulat ”Limbajul de programare” realizează o introducere în conceptul de limbaj de programare și oferă o mică istorie a acestuia. În continuare va prezenta pe scurt produsul folosit pentru a dezvolta aplicația.
Capitolul intitulat ”Platforma .NET Framework” va prezenta elementul central al produsului și modul în care funcționează acesta. În final va prezenta motivele pentru care s-a ales folosirea acestui produs de dezvoltare.
Capitolul intitulat ”Programare orientată pe obiecte” prezintă conceptele care stau la baza limbajului folosit: clasele și obiectele. Aplicația va folosi clase predefinite oferite de produsul dezvoltator dar și clase personalizate, construite în funcție de necesități. Vor fi prezentate mecanismele prin care funcționează aceste concepte.
Capitolul intitulat ”Particularități în Visual C#” va realiza o prezentare a elementelor ce scot în evidentă limbajul de programare ales. Va fi oferită o comparație între limbajul C++ și C# care prezenta elemente similare în ambele limbaje dar care funcționează diferit cât și elemente noi ce aduc avantaje programatorului și ajută în dezvoltarea aplicației.
Capitolul intitulat ”Implementarea și testarea aplicației” realizează o prezentare a problemei pentru care s-a conceput aplicația. Va continua cu prezentarea ciclului de dezvoltare: grupul țintă, specificarea cerințelor, elaborarea codului, elementele de testare și implementare.
Ulterior se continua cu prezentarea interfeței și structurii aplicației, a resurselor folosite. În final este prezentat testul prin care trece aplicația și modalitățile folosite pentru depanare.
Lucrarea se incheie cu concluziile în care se prezintă modalități de dezvoltare viitoare a produsului software, înșirând avantajele pe care le prezintă utilizarea aplicației de gestionare a bazei de date Excel.
LIMBAJUL DE PROGRAMARE
Caracteristicile unui limbaj
Un limbaj de programare pe calculator este folosit pentru a oferi instrucțiuni unui computer pentru a efectua o sarcină specifică. Asemenea unui limbaj vorbit, un limbaj de programare este definit de cuvinte cheie, sintaxe, gramatică, formule și reguli care trebuie urmate pentru a construi propoziții cu înțeles.
Hardware-ul este o serie de obiecte fizice care primesc instrucțiuni printr-un un limbaj de programare. Hardware-ul poate constitui din toate componentele unui telefon mobil, o mașină, un cuptor cu microunde sau un aparat medical. Unele limbaje interacționează cu un anumit hardware sau unele instrucțiuni sunt îndreptate către un anumit mediu, spre exemplu echipamentele dintr-o rețea de telecomunicații de tip CORE. Un astfel de mediu folosește sisteme de operare specifice care nu pot fi împrumutate și altor medii.
O specifică a limbajelor de operare în comparație cu limbajele vorbite de oameni este că acestea pot fi categorizate după rol sau scop. Unele limbaje sunt folosite pentru a rezolva o problemă anume și nu pot efectua sarcini generale. Spre exemplu, unele limbaje sunt folosite pe Internet pentru a afișa lucruri într-un browser. Altele sunt folosite pentru a opera cu anumite valori (e.g. adevărat sau fals). Majoritatea limbajelor sunt folosite pentru a rezolva toate sau aproape toate tipurile de probleme. Aceste limbaje sunt numite limbaje de uz general (general purpose languages).
Timp de 61 de ani, numărați de la apariția primului limbaj de programare denumit FORTRAN, dezvoltatorii de software au scris instrucțiuni în limbajele de programare. Tehnologii noi continuă să apară și sa se maturizeze într-un ritm rapid. În prezent sunt recunoscute peste 5000 de limbaje de programare.
1.2 Produsul Microsoft Visual Studio
Microsoft Visual Studio este un mediu de dezvoltare integrat sau integrated development environment produs de Microsoft. Acesta este folosit în dezvoltarea programelor pe calculator pentru sistemul de operare Microsoft Windows, precum și a site-uri, aplicațiilor și serviciilor web. Windows API, Windows Forms, Windows Presentation Foundation, Windows Store și Microsoft Silverlight sunt platforme folosite de Visual pentru dezvoltarea software-ului.
Visual Studio suportă diferite limbaje de programare și permite editorului de cod și debugger-ului sa sprijine aproape orice limbaj de programare, cu condiția să existe un serviciu al acelui limbaj. Limbajele de programare promovate de Visual Studio sunt C, C++, Visual C++, Visual Basic .NET, C# și F#. Limbajele M, Ruby și Python sunt suportate daca sunt instalate servicii separate și HTML / XHTML, XML / XSLT, JavaScript și CSS pot fi înțelese.
Fig. 1 – Logo-ul Visual Studio 2013 și Visual C#
1.3 Considerente Visual C#
C# (Sharp) este un limbaj de programare dezvoltat de către Microsoft prin inițiativa .NET care a primit titlul de standard de către Ecma (ECMA-334) și ISO (ISO/IEC 23270). Microsoft .NET este o strategie dezvoltată de către Microsoft pentru a încuraja comunicarea între sistemele unei organizații. Tehnologiile care suportă .NET promovează soluții ușor de dezvoltat care se pot folosi eficient și eficace. .NET Framework este compus din componente care modularizează și simplifică dezvoltarea aplicațiilor. Componentele principale promovate de către .NET Framework sunt common language runtime (CLR) și librăria de clase .NET Framework.
Common language runtime este o componentă fundamentală a .NET Framework. Aceasta permite dezvoltarea aplicației într-un limbaj de programare ales de către programator. Compilatorul .NET transformă codul sursă de nivel înalt într-un modul pe care CLR-ul instalat pe un computer client îl poate executa. Procesul de execuție al unei aplicații constă în următorii pași: codul sursă este compilat într-un limbaj de programare care poate fi înțeles de către CLR și transformat în cod MSIL (Microsoft Intermediate Language), acest cod MSIL este translatat în cod mașină printr-un proces ce poartă numele de compilare JIT (Just-in-time) în momentul în care este pornită aplicația, limbajul mașină este executat folosind infrastructura CLR, loader-ul este responsabil pentru încărcarea și inițializarea codului astfel încât secțiuni nefolosite din program nu sunt aduse în memorie.
C# este un limbaj bazat pe programarea orientată pe obiecte derivat din C++. Din acest motiv sintaxa este asemănătoare, pentru ca programatorii familiarizați deja cu C++ să poată trece de la un limbaj de programare la altul. C# este un limbaj expresiv, de tip type-safe (descurajează și previne apariția erorilor de scriere) ce permite programatorilor să dezvolte o varietate de aplicații sigure și robuste care rulează pe platforma .NET.
PLATFORMA .NET FRAMEWORK
Introducere în .NET Framework
.NET este un Framework pentru dezvoltarea software-ului care oferă posibilitatea de a construi, distribui și rula aplicații Windows și aplicații WEB.
Tehnologia .NET adună tehnologii precum ASP, XML, OOP, SOAP, WDSL, UDDI și limbaje de programare precum VB, C++, C#, J#. Codul compilat poate fi portat între diferite calculatoare cu sistem de operare Windows și reutilizat în programe indiferent de limbajul de programare.
.NET Framework este o componentă instalată odată cu sistemul de operare Windows. De-a lungul timpului au fost dezvoltate următoarele versiuni de .NET: 2.0 pentru Windows Server 2003, 3.0 pentru Windows Vista și Windows Server 2008, 3.5 pentru Windows 7, 4.0 și 4.5 pentru Windows 8 / 8.1.
Sunt necesare 3 componente pentru a dezvolta aplicații pe platforma .NET:
Un set de limbaje (C, C++, Visual C++, Visual Basic .NET, C#, F# etc.)
Un mediu de dezvoltare (Visual Studio)
O bibliotecă de clase pentru servicii WEB și aplicații Windows sau WEB.
În dezvoltarea aplicațiilor putem folosi urmatoarele servicii puse la dispoziție de către Visual Studio:
Baze de date precum care pun la dispoziție diverse funcții de stocare (e. g. Azure SQL database)
Servicii folosite în identificarea utilizatorilor (e. g. .NET Identity)
Funcții pentru construirea aplicațiilor non-PC (e. g. Xamarin)
Componenta .NET Framework este centrul tehnologiei .NET și reprezintă ultima interfață între aplicațiile .NET și sistemul de operare instalat. .NET Framework include:
Limbajele C++, Visual C++, Visual Basic .NET, C#, F#. Pentru a fi integrate în platforma .NET, aceste limbaje urmează reguli de programare orientată pe obiecte denumite Common Type System (CTS) ce au clase, interfețe, delegări, tipuri valoare și referință drept elemente fundamentale și conceptele de moștenire, polimorfism și tratarea excepțiilor drept mecanisme.
Mașina virtuală numită Common Language Runtime (CLR) folosită pentru executarea programelor .NET
Ansamblul de biblioteci denumit Framework Class Library, folosit în dezvoltarea aplicațiilor Desktop sau WEB.
2.2 Arhitectura .NET Framework
Componenta .NET Framework este construită din biblioteci, diverse compilatoare și executabile. Fișierele corespunzătoare pot fi localizate în folderul Windows de pe partiția pe care este instalat sistemul de operare. Spre exemplu C:\Windows\Microsoft. NET\Framework și de aici putem observa versiunile instalate.
Fig. 2 – Arhitectura pe nivele a componentei .NET Framework
2.3 Compilarea programelor
O aplicație dezvoltată într-un din limbajele .NET conform Common Language Specification este compilată în Microsoft Intermediate Language. Codul obținut va respecta un format unic cu extensia .exe.
Common Language Runtime este o mașină virtuală ce execută instrucțiunile obținute în urma compilării. Aceasta utilizează un compilator special Just-In-Time care analizează codul Intermediate Language corespunzător și produce codul mașină. JIT recunoaște secvențele de cod pentru care există deja codul mașină, permițând refolosirea acestuia fără a compila din nou, ceea ce face aplicațiile .NET să fie m.
2.2 Arhitectura .NET Framework
Componenta .NET Framework este construită din biblioteci, diverse compilatoare și executabile. Fișierele corespunzătoare pot fi localizate în folderul Windows de pe partiția pe care este instalat sistemul de operare. Spre exemplu C:\Windows\Microsoft. NET\Framework și de aici putem observa versiunile instalate.
Fig. 2 – Arhitectura pe nivele a componentei .NET Framework
2.3 Compilarea programelor
O aplicație dezvoltată într-un din limbajele .NET conform Common Language Specification este compilată în Microsoft Intermediate Language. Codul obținut va respecta un format unic cu extensia .exe.
Common Language Runtime este o mașină virtuală ce execută instrucțiunile obținute în urma compilării. Aceasta utilizează un compilator special Just-In-Time care analizează codul Intermediate Language corespunzător și produce codul mașină. JIT recunoaște secvențele de cod pentru care există deja codul mașină, permițând refolosirea acestuia fără a compila din nou, ceea ce face aplicațiile .NET să fie mai eficiente pe parcursul executării, din punct de vedere al vitezei.
Interoperabilitatea între limbajele .NET există deoarece programul Intermediate Language produs în diferite limbaje este asemănător. Clasele și obiectele create pot fi utilizate dintr-un limbaj .NET în altul.
CLR oferă servicii adiționale precum gestionarea memoriei, tratarea excepțiilor, securitate, gestionarea proceselor și type safety.
.NET Framework este implementarea unui standard ISO numit Common Language Infrastructure, care permite executarea aplicațiilor .NET și pe alte sisteme de operare în afară de Windows precum Linux, Unix, Linux, Solaris etc.
.NET oferă instrumente pe care le putem folosi și în alte programe, acces la baze de date și realizarea ușoară a unor elemente grafice. Spațiul de nume System.Windows.Forms conține instrumente care permit adăugarea elementelor de interfață grafică cu utilizatorul. Folosind aceste instrumente, este posibilă proiectarea și dezvoltarea rapidă a unei aplicații cu interfață către utilizator.
Tot .NET ne oferă clase care efectuează majoritatea sarcinilor uzuale cu care se confruntă programele reducând astfel timpul necesar dezvoltării aplicațiilor.
Fig. 3 – Structura CLI
PROGRAMAREA ORIENTATĂ PE OBIECTE
3.1 Evoluția tehnicilor de programare
Programarea nestructurată (un program simplu, ce utilizează numai variabile globale); complicațiile apar când prelucrarea devine mai amplă, iar datele se multiplică și se diversifică.
Programarea procedurală (program principal deservit de subprograme cu parametri formali, variabile locale și apeluri cu parametri efectivi); se obțin avantaje privind depanarea și reutilizarea codului și se aplică noi tehnici privind transferul parametrilor și vizibilitatea variabilelor; complicațiile apar atunci când la program sunt asignați doi sau mai mulți programatori care nu pot lucra simultan pe un același fișier ce conține codul sursă.
Programarea modulară (gruparea subprogramelor cu funcționalități similare în module, implementate și depanate separat); se obțin avantaje privind independența și încapsularea (prin separarea zonei de implementare, păstrând vizibilitatea numai asupra zonei de interfață a modulului) și se aplică tehnici de asociere a procedurilor cu datele pe care le manevrează, stabilind și diferite reguli de acces la date și la subprograme.
Se observă că modulele sunt „centrate” pe proceduri, acestea gestionând și setul de date pe care le prelucrează (date+date1 din figură). Dacă, de exemplu, dorim să avem mai multe seturi diferite de date, toate înzestrate comportamental cu procedurile din modulul modul1, această arhitectură de aplicație nu este avantajoasă.
Fig. 4 – Programul principal coordonează apelurile în module separate
Programarea orientată pe obiect (programe cu noi tipuri ce integrează atât datele, cât și metodele asociate creării, prelucrării și distrugerii acestor date); se obțin avantaje prin abstractizarea programării (programul nu mai este o succesiune de prelucrări, ci un ansamblu de obiecte care prind viață, au diverse proprietăți, sunt capabile de acțiuni specifice și care interacționează în cadrul programului); intervin tehnici noi privind instanțierea, derivarea și polimorfismul tipurilor obiectuale. [NUȘA07]
Fig. 5 – Obiectele programului interacționează una cu cealaltă prin mesaje
3.2 Tipuri de date obiectuale. Încapsulare.
Un tip de date abstract (ADT) este o entitate caracterizată printr-o structură de
date și un ansamblu de operații aplicabile acestor date.
Considerând, în rezolvarea unei probleme de gestiune a accesului utilizatorilor la un anumit site, tipul abstract USER, vom observă că sunt multe date ce caracterizează un utilizator Internet. Totuși se va ține cont doar de datele semnificative pentru problema dată. Astfel, „culoarea ochilor” este irelevantă în acest caz, în timp ce „data nașterii” poate fi importantă. În aceeași idee, operații specifice ca „se înregistrează”, „comandă on-line” pot fi relevante, în timp ce operația „mănâncă” nu este, în cazul nostru. Evident, nici nu se pun în discuție date sau operații nespecifice („numărul de laturi” sau acțiunea „zboară”).
Operațiile care sunt accesibile din afara ADT formează interfața acesteia. Astfel, operații interne cum ar fi conversia datei de naștere la un număr standard calculat de la 01.01.1900 nu fac parte din interfața tipului de date abstract, în timp ce operația „plasează o comandă on-line” face parte, deoarece permite interacțiunea cu alte obiecte (SITE, STOC etc.).
Numim instanță a unui tip de date abstract o „concretizare” a tipului respectiv, formată din valori efective ale datelor.
Un tip de date obiectual este un tip de date care implementează un tip de date abstract.
Un exemplu clasic de tip de date abstract este STIVA. Ea poate avea ca date: numerele naturale din stivă, capacitatea stivei, vârful etc. Iar operațiile specifice pot fi: introducerea în stivă (push) și extragerea din stivă (pop). La implementarea tipului STIVA, vom defini o structură de date care să rețină valorile memorate în stivă și câmpuri de date simple pentru: capacitate, număr de elemente etc. Vom mai defini metode (subprograme) capabile să creeze o stivă vidă, care să introducă o valoare în stivă, să extragă valoarea din vârful stivei, să testeze dacă stiva este vidă sau dacă stiva este plină etc.
Crearea unei instanțe noi a unui tip obiectual, presupune operații specifice de „construire” a noului obiect, metoda corespunzătoare purtând numele de constructor.
La desființarea unei instanțe și eliberarea spațiului de memorie aferent datelor sale, se aplică o metodă specifică numită destructor (datorită tehnicii de supraîncărcare, limbaje de genul C++, Java și C# permit existența mai multor constructori).
O aplicație ce utilizează tipul obiectual STIVA, va putea construi două sau mai multe stive (de cărți de joc, de exemplu), le va umple cu valori distincte, va muta valori dintr-o stivă în alta după o anumită regulă desființând orice stivă golită, până ce rămâne o singură stivă. De observat că toate aceste prelucrări recurg la datele, constructorul, destructorul și la metodele din interfața tipului STIVA descris mai sus.
Principalul tip obiectual întâlnit în majoritatea mediilor de dezvoltare (Visual Basic, Delphi, C++, Java, C#) poartă numele de clasă (class). Există și alte tipuri obiectuale (struct, object). O instanță a unui tip obiectual poartă numele de obiect.
La implementare, datele și metodele asociate trebuie să fie complet și corect definite, astfel încât utilizatorul să nu fie nevoit să țină cont de detalii ale acestei implementări. El va accesa datele, prin intermediul proprietăților și va efectua operațiile, prin intermediul metodelor puse la dispoziție de tipul obiectual definit. Spunem că tipurile de date obiectuale respectă principiul încapsulării.
Astfel, programatorul ce utilizează un tip obiectual CONT (în bancă) nu trebuie să poarte grija modului cum sunt reprezentate în memorie datele referitoare la un cont sau a algoritmului prin care se realizează actualizarea soldului conform operațiilor de depunere, extragere și aplicare a dobânzilor. El va utiliza unul sau mai multe conturi (instanțe ale tipului CONT), accesând proprietățile și metodele din interfață, realizatorul tipului obiectual asumându-și acele griji în momentul definirii tipului CONT.
Permițând extensia tipurilor de date abstracte, clasele pot avea la implementare:
date și metode caracteristice fiecărui obiect din clasă (membri de tip instanță),
date și metode specifice clasei (membri de tip clasă).
Astfel, clasa STIVA poate beneficia, în plus, și de date ale clasei cum ar fi: numărul de stive generate, numărul maxim sau numărul minim de componente ale stivelor existente etc. Modificatorul static plasat la definirea unui membru al clasei face ca acela să fie un membru de clasă, nu unul de tip instanță. Dacă în cazul membrilor nestatici, există câte un exemplar al membrului respectiv pentru fiecare instanță a clasei, membrii statici sunt unici, fiind accesați în comun de toate instanțele clasei. Mai mult, membrii statici pot fi referiți chiar și fără a crea vreo instanță a clasei respective.
3.3 Supraincărcare
Deși nu este o tehnică specifică programării orientată obiect, ea creează un anumit context pentru metodele ce formează o clasă și modul în care acestea pot fi (ca orice subprogram) apelate.
Prin supraîncărcare se înțelege posibilitatea de a defini în același domeniu de vizibilitate mai multe funcții cu același nume, dar cu parametri diferiți ca tip și/sau ca număr.
Ansamblul format din numele funcției și lista sa de parametri reprezintă o modalitate unică de identificare numită semnătură sau amprentă. Supraîncărcarea permite obținerea unor efecte diferite ale apelului în contexte diferite.
Capacitatea unor limbaje (este și cazul limbajului C#) de a folosi ca „nume” al unui subprogram un operator, reprezintă supraîncărcarea operatorilor. Aceasta este o facilitate care „reduce” diferențele dintre operarea la nivel abstract (cu DTA) și apelul metodei ce realizează această operație la nivel de implementare obiectuală. Deși ajută la sporirea expresivității codului, prin supraîncărcarea operatorilor și metodelor se pot crea și confuzii.
Apelul unei funcții care beneficiază, prin supraîncărcare, de două sau mai multe semnături se realizează prin selecția funcției a cărei semnătură se potrivește cel mai bine cu lista de parametri efectivi (de la apel).
Astfel, poate fi definită metoda „comandă on-line” cu trei semnături diferite:
comanda_online(cod_prod) cu un parametru întreg (desemnând comanda unui singur produs identificat prin cod_prod
comanda_online(cod_prod,cantitate) cu primul parametru întreg și celalalt real
comanda_online(cod_prod,calitate) cu primul parametru întreg și al-II-lea caracter.
3.4 Moștenire
Pentru tipurile de date obiectuale class este posibilă o operație de extindere sau specializare a comportamentului unei clase existente prin definirea unei clase noi ce moștenește datele și metodele clasei de bază, cu această ocazie putând fi redefiniți unii membri existenți sau adăugați unii membri noi. Operația mai poartă numele de derivare. [NUȘA07]
Clasa din care se moștenește se mai numește clasă de bază sau superclasă. Clasa care moștenește se numește subclasă, clasă derivată sau clasă descendentă.
Ca și în Java, în C# o subclasă poate moșteni de la o singură superclasă, adică avem de-a face cu moștenire simplă; aceeași superclasă însă poate fi derivată în mai multe subclase distincte. O subclasă, la rândul ei, poate fi superclasă pentru o altă clasă derivată. O clasă de bază împreună cu toate clasele descendente (direct sau indirect) formează o ierarhie de clase. În C#, toate clasele moștenesc de la clasa de bază Object.
În contextul mecanismelor de moștenire trebuie amintiți modificatorii abstract și sealed aplicați unei clase, modificatori ce obligă la și respectiv se opun procesului de derivare. Astfel, o clasă abstractă trebuie obligatoriu derivată, deoarece direct din ea nu se pot obține obiecte prin operația de instanțiere, în timp ce o clasă sigilată (sealed) nu mai poate fi derivată (e un fel de terminal în ierarhia claselor).
O metodă abstractă este o metodă pentru care nu este definită o implementare, aceasta urmând a fi realizată în clasele derivate din clasa curentă care trebuie să fie și ea abstractă (virtuală pură, conform terminologiei din C++).
O metodă sigilată este o metodă care nu mai poate fi redefinită în clasele derivate din clasa curentă.
3.5 Polimorfism. Metode virtuale.
Folosind o extensie a sensului etimologic, un obiect polimorfic este cel capabil să ia diferite forme, să se afle în diferite stări, să aibă comportamente diferite. Polimorfismul obiectual, care trebuie să fie abstract, se manifestă în lucrul cu obiecte din clase aparținând unei ierarhii de clase, unde, prin redefinirea unor date sau metode, se obțin membri diferiți având însă același nume. [NUȘA07]
Astfel, în cazul unei referiri obiectuale, se pune problema stabilirii datei sau metodei referite. Comportamentul polimorfic este un element de flexibilitate care permite stabilirea contextuală, în mod dinamic, a membrului referit. Acest lucru este posibil doar în cazul limbajelor ce permit „legarea întârziată”. La limbajele cu „legare timpurie”, adresa la care se face un apel al unui subprogram se stabilește la compilare. La limbajele cu legare întârziată, această adresă se stabilește doar in momentul rulării, putându-se calcula distinct, în funcție de contextul în care apare apelul.
Dacă este definită clasa numită PIESA (de șah), cu metoda nestatică muta (pozitie_initiala, pozitie_finala), atunci subclasele TURN și PION trebuie să aibă metoda muta definită în mod diferit (pentru a implementa maniera specifică a pionului de a captura o piesă „en passant”, sau, într-o altă concepție, metoda muta poate fi implementată la nivelul clasei PIESA și redefinită la nivelul subclasei PION, pentru a particulariza acest tip de deplasare care capturează piesa peste care trece pionul în diagonală). Atunci, pentru un obiect T, aparținând claselor derivate din PIESA, referirea la metoda muta pare nedefinită. Totuși mecanismele POO permit stabilirea, în momentul apelului, a clasei proxime căreia îi aparține obiectul T și apelarea metodei corespunzătore (mutare de pion sau tură sau altă piesă).
Pentru a permite acest mecanism, metodele care necesită o decizie contextuală (în momentul apelului), se declară ca metode virtuale (cu modificatorul virtual). În mod curent, în C# modificatorului virtual al funcției din clasa de bază, îi corespunde un specificator override al funcției din clasa derivată ce redefinește funcția din clasa de bază.
O metodă ne-virtuală nu este polimorfică și, indiferent de clasa căreia îi aparține obiectul, va fi invocată metoda din clasa de bază.
3.6 Principiile programării orientată pe obiecte
Ideea POO este de a crea programele ca o colecție de obiecte, unități individuale de cod care interacționează unele cu altele, în loc de simple liste de instrucțiuni sau de apeluri de proceduri.
Obiectele POO sunt, de obicei, reprezentări ale obiectelor din viața reală (domeniul problemei), astfel încât programele realizate prin tehnica POO sunt mai ușor de înțeles, de depanat și de extins decât programele procedurale. Aceasta este adevărată mai ales în cazul proiectelor software complexe și de dimensiuni mari.
Principiile POO sunt:
1. Abstractizarea – principiu care permite identificarea caracteristicilor și comportamentului obiectelor ce țin nemijlocit de domeniul problemei. Rezultatul este un model. În urma abstractizării, entităților din domeniul problemei se definesc prin clase.
2. Încapsularea – numită și ascunderea de informații, este caracterizată prin 2 aspecte:
a. Gruparea comportamentelor și caracteristicilor într-un tip abstract de date
b. Definirea nivelului de acces la datele unui obiect
3. Moștenirea – organizează și facilitează polimorfismul și încapsularea permițând definirea si crearea unor clase specializate plecând de la clase (generale) care sunt deja definite; acestea pot împărtăși (și extinde) comportamentul lor fără a fi nevoie de redefinirea aceluiași comportament.
Polimorfismul – posibilitatea mai multor obiecte dintr-o ierarhie de clase de a utiliza denumiri de metode cu același nume dar, cu un comportament diferit.
3.7 Structura unei aplicații în C#
Limbajul C# permite utilizarea programării orientate pe obiecte respectând toate principiile enunțate anterior. Toate componentele limbajului sunt într-un fel sau altul, asociate noțiunii de clasă. Programul însuși este o clasă având metoda statică Main() ca punct de intrare, clasă ce nu se instanțiază.
Chiar și tipurile predefinite byte, int sau bool sunt clase sigilate derivate din clasa ValueType din spațiul System. Tot din ierarhia de clase oferită de limbaj se obțin și tipuri speciale cum ar fi: interfețe, delegări și atribute. Începând cu versiunea 2.0 a limbajului i s-a adăugat un nou tip clasele generice, echivalentul claselor template din C++.
În cele ce urmează vom analiza, fără a intra în detalii o aplicație POO simplă în C#.
Să definim o clasă numită Persoană:
Public class Persoana { }
unde:
public – este modificator de acces
class – cuvânt rezervat pentru noțiunea de clasă
Persoana – numele clasei
{ } – corpul clasei
Dacă considerăm clasa Persoana ca și clasă de bază, putem deriva două clase Femeie și Barbat
Public class Femeie: Persoana { }
Public sealed class Barbat: Persoana { }
unde:
modificatorul sealed a fost folosit pentru a desemna faptul că nu se mai pot obține clase derivate din clasa Barbat
3.8 Constructori
Înainte de a continua amintim câteva noțiuni legate de constructorii unei clase:
Constructorul este o funcție care face parte din corpul unei clase. Corpul constructorului este format din instrucțiuni care se execută la crearea unui nou obiect al clasei respective (sau la crearea clasei, în cazul constructorilor cu modificatorul static).
Pot exista mai mulți constructori care se pot diferenția prin lista lor de parametri
Constructorii nu pot fi moșteniți
Dacă o clasă nu are definit niciun constructor, se va asigna automat constructorul fără parametri al clasei de bază (clasa object, dacă nu este precizată clasa de bază)
Instanțierea presupune declararea unei variabile de tipul clasei respective și inițializarea acesteia prin apelul constructorului clasei (unul dintre ei, dacă sunt definiți mai mulți) precedat de operatorul new.
Reluăm exemplu de mai sus în care vom prezenta un constructor fără parametri și constructorul implicit din clasa derivată. Vom adăuga un constructor fără parametri. La inițializarea obiectului se va citi de la tastatură un șir de caractere care va reprezenta numele persoanei.
public class Persoana
{
protected string nume; //data accesibila numai in interiorul
//clasei si a claselor derivate
public Persoana ( ) //constructorul fara parametrii ai clasei
{
nume = Console.ReadLine( );
}
}
class Femeie: Persoana
{ }
…
Femeie f = new Femeie ( );
Persoana p = new Persoana ( );
3.9 Destructor
Corpul destructorului este format din instrucțiuni care se execută la distrugerea unui obiect al clasei respective. Pentru orice clasă poate fi definit un singur constructor. Destructorii nu pot fi moșteniți. În mod normal, destructorul nu este apelat în mod explicit, deoarece procesul de distrugere a unui obiect este invocat și gestionat automat de Garbage Collector. [NUȘA07]
3.10 Metode
Din corpul unei clase pot face parte și alte funcții: metodele. Exemplificarea o vom face tot pe exemplul anterior.
public class Persoana
{
protected string nume; //data accesibila numai in interiorul
//clasei si a claselor derivate
public const int nr_max = 10; //constanta
public static int nr_persoane = 0; //camp simplu (variabila)
static Persoana[] persoane = new persoana[nr_max]; //camp de tip
//tablou (variabila)
public static void adaug_persoana(Persoana p) //metodă
{
persoane[nr_persoane++] = p;
if (nr_persoane == nr_max)
throw new Exception("Prea multe persoane");
}
public static void afisare() //metodă
{
Console.WriteLine("Sunt {0} persoane:", nr_persoane);
for (int i = 0; i < nr_persoane; i++)
Console.WriteLine("Nr.{0}. {1}", i + 1, persoane[i].nume);
}
public Persoana() //constructorul fara parametrii ai clasei
{
nume = Console.ReadLine();
}
public Persoana(string s) //constructor cu parametru
{
nume = s;
}
}
class Femeie : Persoana
{
public Femeie(string s)
: base(s) //base semnifica faptul ca
{ //se face apel la
nume = "Femeie " + nume; //constructorul
//din clasa de baza
}
}
Femeie c = new Gemeie();
Persoana.adaug_persoana(c);
// referința noului obiect se memorează în tabloul static persoane
// (caracteristic clasei) și se incrementează data statică nr_persoane
Barbat c = new Barbat();
Persoana.adaug_persoana (c);
Persoana c = new Persoana();
Persoana.adaug_persoana (c);
Persoana.afisare(); //se afișează o listă cu numele celor 3 persoane
…
3.11 Proprietăți
Proprietățile sunt asemănătoare cu metodele în ceea ce privește modificatorii și numele metodelor. Metodele de acces sunt două: set și get. Dacă proprietatea nu este abstractă sau externă, poate să apară una singură dintre cele două metode de acces sau amândouă, în orice ordine.
Este o manieră de lucru recomandabilă aceea de a proteja datele membru (câmpuri) ale clasei, definind instrumente de acces la acestea: pentru a obține valoarea câmpului respectiv (get) sau de a memora o anumită valoare în câmpul respectiv (set). Dacă metoda de acces get este perfect asimilabilă cu o metodă ce returnează o valoare (valoarea datei pe care vrem s-o obținem sau valoarea ei modificată conform unei prelucrări suplimentare specifice problemei în cauză), metoda set este asimilabilă cu o metodă care un parametru de tip valoare (de intrare) și care atribuie (sau nu, în funcție de context) valoarea respectivă câmpului. Cum parametrul corespunzător valorii transmise nu apare în structura sintactică a metodei, este de știut că el este implicit identificat prin cuvântul value. Dacă se supune unor condiții specifice problemei, se face o atribuire de felul câmp=value. [NUȘA07]
Definirea în clasa Persoana a proprietății Nume, corespunzătoare câmpului protejat ce reține, sub forma unui șir de caractere, numele persoanei respective. Se va observă că proprietatea este moștenită și de clasele derivate Femeie și Barbat.
Scrierea unui program orientat obiect implică determinarea obiectelor necesare; acestea vor realiza prelucrările care definesc comportarea sistemului. Obiectele sunt responsabile pentru modificarea datelor proprii.
În proiectarea unei aplicații POO parcurgem următoarele etape:
identificarea entităților, adică a obiectelor care apar în domeniul aplicației, prin evidențierea substantivelor din enunțul problemei
pentru fiecare obiect se identifică datele și operațiile, prin evidențierea verbelor și adjectivelor care caracterizează subiectul respectiv
identificarea relațiilor dintre entități
crearea unei ierarhii de clase, pornind de la aceste entități
PARTICULARITĂȚI ÎN VISUAL C#
Limbajul C# a fost dezvoltat de o echipă de ingineri de la Microsoft în frunte cu Anders Hejlsberg (autorul limbajului Turbo Pascal și membru al echipei care a proiectat Borland Delphi). C# este un limbaj simplu, cu 79 de cuvinte cheie și 25 tipuri de cuvinte contextuale (considerând versiunea 2013). El permite programarea structurată, modulară și orientată obiectual, conform perceptelor moderne ale programării profesioniste. Principiile de bază ale programării orientate pe obiecte (încapsulare, moștenire, polimorfism) sunt elemente fundamentale ale programării C#. [APETC7]
La baza acestuia stă limbajul C dar sunt preluate și principiile de programare din C++. Sintaxa este apropiată și limbajului Java.
Au fost adăugate o serie de tipuri noi de date sau funcțiuni diferite ale datelor din C++, iar în spiritul realizării unor secvențe de cod sigure (safe), unele funcțiuni au fost adăugate (de exemplu, interfețe și delegări), diversificate (tipul struct), modificate (tipul string) sau chiar eliminate (moștenirea multiplă și pointerii către funcții). Unele funcțiuni (cum ar fi accesul direct la memorie folosind pointeri) au fost păstrate, dar secvențele de cod corespunzătoare se consideră nesigure.
În momentul în care Microsoft a decis să susțină și să dezvole C# s-a hotărât ca acesta să aibă o legătură deosebita cu mediul sau de rulare, arhitectura .NET. Pe de o parte, C# a fost dezvoltat pentru crearea codului pentru arhitectura .NET, iar pe de alta parte bibliotecile utilizate de C# sunt cele ale arhitecturii .NET. Atunci când este compilat un program C#, rezultatul compilării nu este un cod executabil ci se produce un fișier într-un limbaj. Acest fișier IL poate fi copiat in orice calculator care dispune de .NET CLR, prin intermediul compilatorului JIT (Just In Time), motorul comun de programare transforma codul intermediar in cod executabil. [APETC7]
4.1 Gestionarea automată a memoriei
Prin intermediul operatorilor new și delete, în C++, programatorul gestionează manual memoria ceea ce conferă avantaje dar și dezavantaje.
Avantaje:
permite un control foarte precis asupra momentului în care este distrus un obiect, astfel folosindu-se memoria exact atât cât este nevoie;
permite folosirea destructorilor, astfel obiectele fiind întotdeauna șterse corespunzător.
Dezavantaje:
riscul de a apela prea târziu (sau deloc) operatorul delete. Omiterea apelării operatorului delete nu este în general fatală pentru program, dar conduce la ocuparea memoriei mai mult decât este necesar (memory leakage). Memory leak este o eroare de programare în care programatorul a alocat memorie pe heap utilizând funcțiile din librăria standard C (malloc, calloc, realloc) sau operatorul C++ new, dar nu a mai dezalocat memoria alocata. Acest fapt reprezintă o problemă deoarece consumul de memorie al aplicației poate crește în mod necontrolat. Problema devine critică mai ales în cazul aplicațiilor care trebuie sa ruleze un timp îndelungat (de exemplu un server de baza de date, sau un server web, un filesystem etc. ).
riscul de a apela prea devreme operatorul delete este o problemă mult mai gravă.
Obiect *P = new Obiect(); // cream un obiect
functie(P); // il transmitem unei funcții
P->calculeazaX(); // folosim obiectul
… // Obiectul a fost sters in functie din greseala si nu va putea fi folosit
void functie (Obiect *ob)
{
ob->calculeazaX(); // folosește obiectul
delete pct; // obiectul este sters
}
Ca și Sun Microsystems în cazul limbajului Java, Microsoft a decis că dezavantajele gestionării manuale a alocărilor făcute depășesc avantajele oferite, de aceea s-a trecut la gestionarea automată a memoriei.
Se pot crea în continuare obiecte în mod dinamic, dar ștergerea obiectelor intră în responsabilitatea sistemului, nu a programatorului. Sistemul urmărește referirile la obiecte și atunci când un obiect nu mai este referit, devine un candidat pentru “colectarea gunoiului”.
Consecința este ca nu se poate ști când se face colectarea gunoiului pentru un obiect.
4.2 Comparație între C# și C++
C++ este un limbaj de programare care are capabilități high-level (POO) și low-level (lucrul cu pointerii, adresele de memorie etc). [APETC7]
C++ este privit ca un “mid-level language”. C# este un limbaj simplu, modern orientat obiect și “type-safe programming language” (ex.: nu suntem lăsați să facem declarații care în C++ generau erori de genul “Access violation”).
1) În .NET este implementat Garbage Collector, unealtă care permite gestionarea automată a memoriei. Nu mai este obligatorie folosirea operatorilor “delete” sau “delete[]” din c++, framework-ul se ocupa de memorie, decide dacă anumite zone de memorie si-au încetat activitatea și le dealocă automat. (din acest motiv, de multe ori, destructorii în C# au doar un rol simbolic).
2) Codul C++ este compilat în cod assembly, pe când codul C# este compilat în “Intermediate language” (sau pe scurt IL), apoi acesta este compilat în executabil prin metoda Just-In-Time Compilation.
3) În C# obiectele simple precum int, float, double sau structurile sunt create pe stiva, iar clasele întotdeauna în coadă.
În C++ un șir este pur și simplu o serie de caractere. În C #, șirurile de caractere sunt obiecte ale clasei String, clasă înzestrată cu o gamă largă de metode predefinite.
4) În C++ un tablou este doar un pointer. În C# tablourile sunt obiecte care includ metode și proprietăți (exemplu: dimensiunea unui tablou poate fi obținută prin intermediul proprietății Length). Mai mult, în C# este verificat fiecare indice utilizat pentru a accesa elementele tabloului. Există diferențe și de sintaxă pentru declararea tablourilor: semnul "[]" apare în C# după tipul elementelor tabloului în timp ce în C++ apare după variabilă.
Exemplu:
C#: int[] tablou;
C++: int tablou[5];
5) Pointerii sunt permiși în C #, dar numai în mod ”unsafe”.
6) În C# metodele și variabilele globale nu sunt acceptate. Metodele și variabilele trebuie să fie conținute într-o clasă sau într-o structură. Metoda Main() în C# este declarată în mod diferit față de funcția main() din C++. În C# numele acestei metode începe cu majusculă și este întotdeauna de tip static. Diferă și argumentele din linia de comandă.
Dacă în C++ toate variabilele sunt transmise prin valoare (cu excepția cazului în care se utilizează pointeri sau o referințe), în C# clasele sunt transmise prin referință și structurile sunt transmise prin valoare, cu excepția cazului în care se folosește explicit modificatorul ref sau out.
În C# delegații sunt aproximativ la fel cu pointerii de funcții din C++.
7) C# suportă operatori noi, cum ar fi is și typeof. De asemenea sunt suportate diferite funcționalități pentru unii operatori logici. Supraîncărcarea operatorilor se realizează în mod diferit în C#.
8) În C# instrucțiunile if / else, while, for sunt la fel ca în C++. switch diferă prin faptul că este obligatoriu să se pună break după fiecare case.
În C# se poate folosi foreach:
int[] v = new int {1, 4, 7, 9, 11, 25, 6};
foreach (int i in v) // Se creează de fiecare data un obiect virtual int
if (i % 2 == 0)
Console.WriteLine(i); // Echivalent cout<<i<<endl;
Această instrucțiune are dezavantajul că se creează obiecte virtuale și îngreunează lucrul, dar pentru procesoarele de astăzi nu mai reprezintă o problemă.
În C++ tipul bool este în esență un număr întreg pe când în C# nu există nici o conversie între tipul bool și alte tipuri. Din acest motiv instrucțiunile condiționale (if, while etc) nu mai merg ca în C++, spre exemplu:
int x = 4;
if (x){…} ; // Reprezintă o eroare, condițiile trebuie sa fie de tip bool
if (x != 0) ; // Este corect
bool b = true;
if (b) {…} ; // Este corect
9) În C# există 2 mari tipuri de date: value type si refference type.
Tipurile simple precum int, float, double, bool, precum și struct sunt value type:
valueType x = new valueType();
valueType y = x; //se face copierea bit cu bit din x in y
Clasele și tipurile ce deriva din object sunt reference type:
myClass c = new myClass();
myClass c1 =c ; //nu se va face copiere, c1 va fi o referinta pt c
10) În C# se poate folosi tipul object, care poate retine orice data:
object o1 = “un text”;
object o2 = 12.3F;
float f = (float)o2;
IMPLEMENTAREA ȘI TESTAREA APLICAȚIEI
Prezentarea problemei
Necesitarea aplicației de gestionare se naște din următorul scenariu real:
Consideram compania de telecomunicații X ce oferă servicii de întreținere și mentenanță unui client Y. Clientul Y este un purtător de servicii pentru companii multinaționale. Y închiriază echipamente de telecomunicații și căi de transmisie pe bandă optică pentru clienții săi.
Un departament din compania X se va ocupa cu întreținerea unui stoc de echipamente care sunt trimise prin curier pentru a înlocui componentele defecte ce vor apărea în rețeaua de telecomunicații. Acesta folosește un template Excel numit ”Status Report”, propus de clientul Y, pentru a oferi rapoarte cu privire la numărul de echipamente și disponibilitatea lor în stoc.
Aplicația intitulată ”Status Report App” va oferi posibilitatea departamentului de a lucra în mod ușor și sigur cu o baza de date Excel. Va exista un sistem de securitate pentru a preveni accesul neautorizat și vor putea fi introduse înregistrări noi precum și vizualiza numărul de echipamente din stoc.
Definirea grupului țintă
Aplicația dezvoltată este destinată echipei din compania X care are rolul de a actualiza baza de date Excel cu intrări noi ce reprezintă echipament nou venit în stoc. Echipa va trebui să poate să ofere informații curente despre stoc atunci când clientul Y va plasa solicitarea.
În mod adițional, echipa va trebui să poată să notifice clientul Y când unul dintre numărul unui tip de echipament a scăzut sub o limită minimă impusă de client. Această acțiune are rolul de a cunoaște momentul când este necesară plasarea unei comenzi către producătorul de echipamente pentru a reaproviziona stocul.
Definirea specificațiilor
Aplicația de gestionare a bazei de date Excel pune la dispoziția utilizatorului un instrument simplu și ușor de folosit care oferă următoarele facilități:
Acces non-stop la aplicație prin intermediul unui sistem de securitate care va aproba sau refuza credențialele introduse de utilizator.
Acces în timp real la cele mai recente informații despre stoc
Modalitate eficientă de a deschide și modifica fișierul Excel în care se stochează informațiile
Modalitate de a vizualiza sau căuta informații despre un anumit tip de echipament
Elaborarea codului sursă
Pentru dezvoltarea aplicației s-a folosit limbajul de programare C#. Sunt folosite două obiecte de tip Windows Form (una pentru ecranul de înregistrare și una pentru aplicația propriu-zisă) ce vor oferi interfața cu utilizatorul.
Fereastra de autentificare conține folosește următoarele unelte:
Un Panel pentru afișarea logo-ului sub forma unei imagini care s-a identifice aplicația
Trei Label-uri care să ofere utilizatorului informații despre interfață
Două Text Box-uri care să culeagă datele de autentificare introduse de utilizator
Două Butoane, unul pentru confirmarea datelor de autentificare și altul pentru ieșirea din aplicație.
Pentru a autoriza un utilizator vom folosi o bază de date de tip Microsoft SQL. Vom face operațiuni asupra bazei de date prin intermediul claselor și funcțiilor din librăriile System.Data.Sql și System.Data.SqlClient.
Codul sursă pentru fereastra de autentificare conține trei funcții:
Funcția de inițializarea a ferestrei:
public LoginScreen()
Funcția care descrie evenimentul de ”click” asupra butonului de ieșire:
private void btnExit_Click(object sender, EventArgs e)
Funcția care descrie evenimentul de ”click” asupra butonului de înregistrare:
private void btnLogin_Click(object sender, EventArgs e)
Această ultimă funcție va avea rolul de a defini obiectele de tip SqlConnection și SqlCommand care ne vor ajuta să interogăm baza de date. Dacă informațiile introduse de utilizator sunt autentice, fereastra principală a aplicației va fi instanțiată. Dacă nu, se va afisa un mesaj de eroare către utilizator.
La pasul următor va fi construită o clasă numită ”Echipament” care va avea drept atribute ID-ul, seria, numărul actual și numărul minim din stoc.
Vom folosi librăriile System.Data.OleDb și Excel=Microsoft.Office.Interop.Excel pentru a avea acces la obiecte de tip List și BindingList care ne ajuta să adunam și să afișăm informații din Worksheet.
Următoarea clasă definită va fi numită ”MyExcel” în care vom defini funcțiile următoare:
Funcția de inițializare a fișierului Excel:
public static void InitializeExcel()
Funcția care citește informațiile din Worksheet și stochează într-un obiect de tip Echipament:
public static BindingList<Echipament> ReadMyExcel()
Funcția care va scrie informații în Worksheet:
public static void WriteToExcel(Echipament ech)
Funcția care va căuta și filtra informațiile afișate:
public static List<Echipament> FiltruEchLista(string searchValue, string searchExpr)
Funcția care va închide fișierul Excel:
public static void CloseExcel()
Fereastra principală a aplicației va folosi unelte de tip Panel și Label pentru a oferi o interfață clară și ușor de folosit. Obiecte de tip Text Box se vor folosi pentru a culege informațiile introduse cu referire la ID-ul și seria echipamentului, cantitatea din stoc și numărul minim agreat.
Se va utiliza un obiect de tip Tab Control pentru a oferi două tab-uri ”Adauga echipament nou” și ”Detalii despre stoc”. Aceste tab-uri au rolul de a trece de la o funcționalitate la alta.
Vom folosi două Butoane, unul pentru a alege baza de date Excel pe care vrem să o modificăm (”Deschide”) iar celălalt pentru a updata baza de date cu o informație nouă (”Actualizează”). Tab-ul ”Detalii despre stoc” va conține două Label-uri ce vor identifica celelalte elemente: un obiect de tip DropDownList care va fi folosit pentru a selecta criteriul de căutare și obiect de tip TextBox în care utilizatorul va introduce o expresie ce va fi căutată.
Ultimul obiect din tab-ul ”detalii despre stoc” este un DataGridView în care se vor afișa informațiile extrase din Worksheet.
Fig. 6 – Vizualizarea proiectului în Visual Studio 2013
Proiectul dezvoltat în Visual Studio 2013 este compus din 7 fișiere de tip .cs care conțin cod sursă și două fișiere de tip ”design” prin care poate observa aspectul fiecărei ferestre.
Testarea aplicației
Aplicația software este publicată sub forma unui folder ce conține kit-ul de instalare.
Fig. 7 – Folder-ul care va fi distribuit utilizatorilor pentru a instala aplicația
În continuare, vom testa funcționalitatea sistemului de autentificare. În acest scop am creat un singur cont autorizat.
Pentru a vedea informațiile din baza de date ce conține credențialele utilizatorilor se va folosi serviciul Server Explorer.
Fig. 8 – Modul de a vizualiza conturile autorizate ale utilizatorilor
Fig. 9 – Tabelul din baza de date ce conține conturile autorizate. Acest tabel poate fi modificat ușor prin intermediul aplicației Visual Studio.
Dacă un utilizator va încerca să se înregistreze printr-un username și o parolă care nu se află în baza de date atunci va primi un mesaj de avertizare și i se va refuza accesul. Pentru test vom folosi Username ”utilizator1” și Password ”123”.
Fig. 10 – Încercare de acces neutorizat
Pentru a porni fereastra principală a aplicației vom folosi contul de utilizator definit prin perechea Username ”cristian.sabac” și Password ”Start123”.
Fig. 11 – Încercare de acces autorizat
Fig. 12 – Fereastra principală a aplicației
Din fereastra principală putem să selectăm fișierul ce conține baza de date Excel prin evenimentul ”click” pe TextBox sau prin apăsarea pe butonul ”Deschide”. Acest fișier poate fi localizat pe orice calculator conectat la o rețea cu condiția ca utilizatorul să aibă vizibilitate la folder-ul în care se află.
Dacă un utilizator încearcă să navigheze tab-ul ”Detalii despre stoc” va primi un mesaj de eroare deoarece aplicația nu va avea ce să interogheze.
Fig. 13 – Mesaj de eroare în cazul în care fișierul Excel nu este încărcat
În acest test vom folosi un fișier .xlsx intitulat ”Status Report” care va fi inițial gol.
Fig. 14 – Fereastra care permite alegerea fișierului dorit
După ce fișierul dorit a fost deschis, vor fi deblocate tab-urile de management și se vor putea adăuga intrări noi în baza de date.
Fig. 15 – Forma aplicației după încărcarea fișierului Excel
Deoarece am folosit un fișier .xlsx gol, putem observa în tab-ul ”Detalii despre stoc” ca nu vom avea nici o intrare.
Fig. 16 – Vizualizarea unui fișier gol
Vom testa în continuare funcția de gestionare a bazei de date Excel. Vom introduce pe rând următoarele valori în câmpurile oferite. Valorile reprezintă informații despre modulele optice aflate în stocul de echipamente.
SFP-1GE-LX 3. XFP-10G-L-OC192-SR1
740-011614 740-014279
50 30
15
SFPP-10GE-LR 4. GLC-LH-SM
740-031981 30-1299-01
120 40
60 5
Fig. 17 – Adăugarea unei înregistrări noi in fișierul Excel
În momentul în care o înregistrare nouă a fost salvată, utilizatorul va fi informat, printr-un mesaj, că operația a avut succes.
Fig. 18 – Operația de adăugare a avut succes
Folosind tab-ul ”Detalii despre stoc” vom putea vizualiza datele pe care tocmai le-am introdus și putem alege unul din atributele clasei Echipament pentru a filtra datele și a căuta informații specifice.
Fig. 19 – Vizualizarea datelor din baza de date Excel
Pentru a testa funcție de căutare și filtrare a datelor vom lua în considerare următorul scenariu: dorim să vizualizăm toate echipamentele din stoc al căror ID începe cu șirul de caractere ”XFP”.
Fig. 20 – Operația de căutare și filtrare
Obiectul de tip DataGridView în care afișăm datele obținute în urma interogării fișierului .xlsx se va actualiza în timp real pe măsură ce utilizatorul scrie în TextBox-ul din dreptul label-ului ”Expresie”.
Resurse folosite
.NET Framework 4.0
Conexiune și acces la locația unde va fi ținută baza de date Excel
Drepturi de administrator pentru a instala aplicația
Spațiu de 1Mb pe Hard Disk și aproximativ 15Mb de memorie RAM
Microsoft SQL Server sau Microsoft SQL Server Express
CONCLUZII
Aplicația de gestionarea a unei baze de date in Excel se adresează unui departament din cadrul unei companii care trebuie să supervizeze un stoc de echipamente. Aceasta oferă cu succes un sistem de prevenire al accesului neautorizat și metode prin care pot fi introduse date noi. Folosind funcția de căutare și filtrare, este foarte ușor ca un utilizator să observe care este numărul total de echipamente de un anumit fel aflat în stoc și dacă acest număr este insuficient.
Interfața cu utilizatorul a fost construită ca fiind ușor de înțeles prin folosirea unor denumiri specifice pentru obiectele folosite, adăugarea de label-uri și informarea utilizatorului prin mesaje de tip pop-up.
Resursele consumate de aplicație sunt neglijabile. Este de așteptat ca aceasta să funcționeze pe majoritatea calculatoarelor indiferent de specificațiile lor tehnice.
Aplicația implementată în cadrul acestui proiect a fost dezvoltată în Visual Studio 2013. Visual C# .NET este un limbaj de programare dependent de .NET Framework. Un sistem de operare care nu are instalat acest pachet nu va putea rula programul. Începând cu Windows 8, .NET Framework 4.0 este deja încorporat în sistemul de operare. Pentru celelalte sisteme de operare va trebui instalat separat sau poate fi ușor disponibil prin activarea serviciul Windows Automatic Updates. Aplicația a fost creată pentru versiunea .NET 4.0.
Toate funcțiile aplicației au fost verificate cu succes și evidențiate prin exemple în cadrul secțiunii ”Testarea aplicației”. Cele mai comune erori care pot fi create de utilizator au fost prevenite. Aceste erori includ: accesul neautorizat sau eronat, încercarea de a deschide un alt tip de fișier decât cel indicat, accesarea funcțiilor aplicației înainte de încărcarea bazei de date etc
Deși au fost luate în considerare și prevenite anumite greșeli pe care utilizatorul ar putea să le genereze, se presupune că acesta este familiar cu aplicația sau a urmat un scurt curs introductiv. În cazul în care utilizatorul este nefamiliar cu aplicațiile Windows, modul în care a fost proiectată aplicația permite adăugarea unor facilitați noi care să prevină următoarele erori: introducea în baza de date a unor informații eronate precum două echipamente cu același ID, introducerea unui șir de caractere în loc de numere pentru câmpurile care reprezintă numărul actual de echipamente din stoc și numărul minim agreat cu clientul.
Utilizatorul nu va folosi aplicația ca să modifice valorile din baza de date. Acesta are sarcina de a adăuga echipamente noi și de a interoga baza de date pentru a genera diverse rapoarte. O altă versiune a aplicației va permite doar modificarea numărului de echipamente din stoc va fi distribuită către inginerii care vor instala echipamentele de rețea pentru a fi folosită in urma fiecărei intervenții.
Funcția de căutare și filtrare va fi folosită pentru a observa când un numărul unui tip de echipament a scăzut sub pragul minim acceptat. În acest caz utilizatorul va putea informa clientul de nevoie unei achiziții noi de echipamente.
Bibliografie
Bruce JOHNSON – ”Professional Visual Studio 2013”, John Wiley & Sons, Indianopolis, 2014, ISBN: 978-1-118-84147-1, 15 pg., 151 pg., 499 pg.
Dumitriu-Lupa NUȘA – ”Introducere în programarea .NET Framework”, Microsoft, Năvodari 2007, 3 pg., 5 pg., 9 pg., 13 pg. [NUȘA07]
Jeff MARTIN, Richard BANKS – ”Visual Studio 2013 Cookbook”, Packt Publishing, Birmingham, 2014, ISBN 978-1-78217-196-6, 22 pg., 118 pg.
John SHARP – ”Microsoft Visual C# 2013 Step by Step”, Octal Publishing, USA, 2013, ISBN: 978-0-7356-8183-5, xix pg., 5 pg., 17 pg., 317 pg, 452 pg.
Marius APETRII – ”Programare orientată pe obiecte”, Facultatea de matematică ”Alexandru Ioan Cuza”, Iași, Curs 7, 4 pg., 8 pg. [APETC7]
https://msdn.microsoft.com/ – ”Overview of the .NET Framework”, ”OLE DB Programmer’s Guide”, ”Microsoft.Office.Interop.Excel”,
Anexa 1 – Codul sursă
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace StatusReport
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LoginScreen());
}
}
}
Echipament.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StatusReport
{
class Echipament
{
public string ID { get; set; }
public string Serie { get; set; }
public string Stoc { get; set; }
public string Minim { get; set; }
}
}
MyExcel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using Excel=Microsoft.Office.Interop.Excel;
using System.ComponentModel;
namespace StatusReport
{
class MyExcel
{
public static string DB_PATH = @"";
public static BindingList<Echipament> EchLista = new BindingList<Echipament>();
private static Excel.Workbook MyBook = null;
private static Excel.Application MyApp = null;
private static Excel.Worksheet MySheet = null;
private static int lastRow=0;
public static void InitializeExcel()
{
MyApp = new Excel.Application();
MyApp.Visible = false;
MyBook = MyApp.Workbooks.Open(DB_PATH);
MySheet = (Excel.Worksheet)MyBook.Sheets[1];
lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
}
public static BindingList<Echipament> ReadMyExcel()
{
EchLista.Clear();
for (int index = 2; index <= lastRow; index++)
{
System.Array MyValues = (System.Array)MySheet.get_Range("A" + index.ToString(), "D" + index.ToString()).Cells.Value;
EchLista.Add(new Echipament {
ID = MyValues.GetValue(1,1).ToString(),
Serie = MyValues.GetValue(1,2).ToString(),
Stoc = MyValues.GetValue(1,3).ToString(),
Minim = MyValues.GetValue(1,4).ToString()
});
}
return EchLista;
}
public static void WriteToExcel(Echipament ech)
{
try
{
lastRow += 1;
MySheet.Cells[lastRow, 1] = ech.ID;
MySheet.Cells[lastRow, 2] = ech.Serie;
MySheet.Cells[lastRow, 3] = ech.Stoc;
MySheet.Cells[lastRow, 4] = ech.Minim;
EchLista.Add(ech);
MyBook.Save();
}
catch (Exception ex)
{ }
}
public static List<Echipament> FiltruEchLista(string searchValue, string searchExpr)
{
List<Echipament> FilteredList = new List<Echipament>();
switch (searchValue.ToUpper())
{
case "ID":
FilteredList = EchLista.ToList().FindAll(ech => ech.ID.ToLower().Contains(searchExpr));
break;
case "SERIE":
FilteredList = EchLista.ToList().FindAll(ech => ech.Serie.ToLower().Contains(searchExpr));
break;
case "STOC":
FilteredList = EchLista.ToList().FindAll(ech => ech.Stoc.ToLower().Contains(searchExpr));
break;
case "MINIM":
FilteredList = EchLista.ToList().FindAll(ech => ech.Minim.ToLower().Contains(searchExpr));
break;
default:
break;
}
return FilteredList;
}
public static void CloseExcel()
{
MyBook.Saved = true;
MyApp.Quit();
}
}
}
Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
namespace StatusReport
{
public partial class LoginScreen : Form
{
public LoginScreen()
{
InitializeComponent();
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnLogin_Click(object sender, EventArgs e)
{
SqlConnection sqlConnect = new SqlConnection();
sqlConnect.ConnectionString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\cristian.sabac\Documents\DataTable.mdf;Integrated Security=True;Connect Timeout=30";
sqlConnect.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT [USERNAME], [PASSWORD] FROM [dbo].[Table] where [USERNAME] ='" + txtUser.Text + "' and [PASSWORD] ='" + txtPass.Text + "'", sqlConnect);
SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd);
DataTable dt = new DataTable();
sqlAdapter.Fill(dt);
if (dt.Rows.Count > 0)
{
this.Hide();
Form1 principal = new Form1();
principal.Show();
}
else
{
MessageBox.Show("Username sau parola incorecta. Va rog reincercati.");
}
}
}
}
Form2.Designer.cs
namespace StatusReport
{
partial class LoginScreen
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.txtPass = new System.Windows.Forms.TextBox();
this.txtUser = new System.Windows.Forms.TextBox();
this.btnExit = new System.Windows.Forms.Button();
this.btnLogin = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackgroundImage = global::StatusReport.Properties.Resources.LoginImage;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(226, 237);
this.panel1.TabIndex = 0;
//
// label3
//
this.label3.AutoSize = true;
this.label3.BackColor = System.Drawing.SystemColors.Control;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(244, 12);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(225, 16);
this.label3.TabIndex = 7;
this.label3.Text = "Va rog introduceti credentialele";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(248, 105);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(61, 13);
this.label2.TabIndex = 11;
this.label2.Text = "Password";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(248, 61);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(63, 13);
this.label1.TabIndex = 10;
this.label1.Text = "Username";
//
// txtPass
//
this.txtPass.Location = new System.Drawing.Point(315, 102);
this.txtPass.Name = "txtPass";
this.txtPass.PasswordChar = '*';
this.txtPass.Size = new System.Drawing.Size(204, 20);
this.txtPass.TabIndex = 9;
//
// txtUser
//
this.txtUser.Location = new System.Drawing.Point(315, 58);
this.txtUser.Name = "txtUser";
this.txtUser.Size = new System.Drawing.Size(204, 20);
this.txtUser.TabIndex = 8;
//
// btnExit
//
this.btnExit.Location = new System.Drawing.Point(444, 190);
this.btnExit.Name = "btnExit";
this.btnExit.Size = new System.Drawing.Size(75, 23);
this.btnExit.TabIndex = 13;
this.btnExit.Text = "&Iesire";
this.btnExit.UseVisualStyleBackColor = true;
this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
//
// btnLogin
//
this.btnLogin.Location = new System.Drawing.Point(315, 190);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(75, 23);
this.btnLogin.TabIndex = 12;
this.btnLogin.Text = "&Logare";
this.btnLogin.UseVisualStyleBackColor = true;
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// LoginScreen
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(566, 261);
this.Controls.Add(this.btnExit);
this.Controls.Add(this.btnLogin);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtPass);
this.Controls.Add(this.txtUser);
this.Controls.Add(this.label3);
this.Controls.Add(this.panel1);
this.Name = "LoginScreen";
this.Text = "Ecran de autentificare";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtPass;
private System.Windows.Forms.TextBox txtUser;
private System.Windows.Forms.Button btnExit;
private System.Windows.Forms.Button btnLogin;
}
}
Principal.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StatusReport;
namespace StatusReport
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tabControl1.Selecting += new TabControlCancelEventHandler(tabControl1_Selecting);
}
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs args)
{
TabPage current = (sender as TabControl).SelectedTab;
if (string.IsNullOrEmpty(MyExcel.DB_PATH))
{
MessageBox.Show("Va rugam sa deschideti fisierul excel", "Eroare!", MessageBoxButtons.OK, MessageBoxIcon.Error);
args.Cancel = true;
}
}
private void tabPage1_Click(object sender, EventArgs e)
{
TabControl tc = sender as TabControl;
if (tc.SelectedIndex == 1)
{
dataGridEchList.DataSource = (BindingList<Echipament>)MyExcel.EchLista;
dataGridEchList.AutoResizeColumns();
}
}
private void button1_Click(object sender, EventArgs e)
{
Echipament ech = new Echipament { ID = textID.Text.ToString(),
Serie = textSerie.Text.ToString(),
Stoc = textStoc.Text.ToString(),
Minim = textMinim.Text.ToString()
};
MyExcel.WriteToExcel(ech);
clearAllFields();
MessageBox.Show("Detaliile au fost adaugate cu succes", "Succes!", MessageBoxButtons.OK, MessageBoxIcon.Information);
textID.Focus();
}
public void clearAllFields()
{
textID.Text = "";
textStoc.Text = "";
textSerie.Text = "";
textMinim.Text = "";
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void OnFormClosing(System.Windows.Forms.FormClosingEventArgs e)
{
if(!string.IsNullOrEmpty(MyExcel.DB_PATH))
MyExcel.CloseExcel();
}
private void cmbSearch_SelectedIndexChanged(object sender, EventArgs e)
{
txtSearchExpr.ReadOnly = false;
}
private void txtSearchExpr_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSearchExpr.Text))
{
dataGridEchList.DataSource = MyExcel.FiltruEchLista(cmbSearch.Text.ToString(), txtSearchExpr.Text.ToLower());
}
else
{
dataGridEchList.DataSource = MyExcel.EchLista;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void btnLoad_Click(object sender, EventArgs e)
{
OpenFileDialog ExcelDialog = new OpenFileDialog();
ExcelDialog.Filter = "Fisiere Excel (*.xlsx) | *.xlsx";
ExcelDialog.InitialDirectory = @"C:\";
ExcelDialog.Title = "Alegeti fisierul excel";
if (ExcelDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MyExcel.DB_PATH = ExcelDialog.FileName;
txtFileName.Text = ExcelDialog.FileName;
txtFileName.ReadOnly = true;
txtFileName.Click -= btnLoad_Click;
tabControl1.Selecting -= tabControl1_Selecting;
btnLoad.Enabled = false;
MyExcel.InitializeExcel();
dataGridEchList.DataSource = MyExcel.ReadMyExcel();
tblLytAddMem.Visible = true;
}
}
}
}
Principal.Designer.cs
namespace StatusReport
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtSearchExpr = new System.Windows.Forms.TextBox();
this.dataGridEchList = new System.Windows.Forms.DataGridView();
this.label11 = new System.Windows.Forms.Label();
this.cmbSearch = new System.Windows.Forms.ComboBox();
this.label10 = new System.Windows.Forms.Label();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.pnlFileHeader = new System.Windows.Forms.Panel();
this.btnLoad = new System.Windows.Forms.Button();
this.txtFileName = new System.Windows.Forms.TextBox();
this.label13 = new System.Windows.Forms.Label();
this.tblLytAddMem = new System.Windows.Forms.TableLayoutPanel();
this.panel1 = new System.Windows.Forms.Panel();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.textMinim = new System.Windows.Forms.TextBox();
this.textStoc = new System.Windows.Forms.TextBox();
this.textSerie = new System.Windows.Forms.TextBox();
this.textID = new System.Windows.Forms.TextBox();
this.panel3 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.empConstantsBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.tabPage2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridEchList)).BeginInit();
this.tabPage1.SuspendLayout();
this.pnlFileHeader.SuspendLayout();
this.tblLytAddMem.SuspendLayout();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.panel3.SuspendLayout();
this.tabControl1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.empConstantsBindingSource)).BeginInit();
this.SuspendLayout();
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtSearchExpr);
this.tabPage2.Controls.Add(this.dataGridEchList);
this.tabPage2.Controls.Add(this.label11);
this.tabPage2.Controls.Add(this.cmbSearch);
this.tabPage2.Controls.Add(this.label10);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(596, 337);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Detalii despre stoc";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtSearchExpr
//
this.txtSearchExpr.Location = new System.Drawing.Point(422, 32);
this.txtSearchExpr.Name = "txtSearchExpr";
this.txtSearchExpr.ReadOnly = true;
this.txtSearchExpr.Size = new System.Drawing.Size(126, 20);
this.txtSearchExpr.TabIndex = 4;
this.txtSearchExpr.TextChanged += new System.EventHandler(this.txtSearchExpr_TextChanged);
//
// dataGridEchList
//
this.dataGridEchList.AllowUserToOrderColumns = true;
this.dataGridEchList.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridEchList.Location = new System.Drawing.Point(28, 92);
this.dataGridEchList.Name = "dataGridEchList";
this.dataGridEchList.RowHeadersWidth = 50;
this.dataGridEchList.Size = new System.Drawing.Size(520, 210);
this.dataGridEchList.TabIndex = 0;
//
// label11
//
this.label11.AutoSize = true;
this.label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label11.Location = new System.Drawing.Point(343, 33);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(73, 16);
this.label11.TabIndex = 3;
this.label11.Text = "Expresie:";
//
// cmbSearch
//
this.cmbSearch.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.cmbSearch.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.cmbSearch.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbSearch.FormattingEnabled = true;
this.cmbSearch.Items.AddRange(new object[] {
"ID",
"Minim",
"Serie",
"Stoc"});
this.cmbSearch.Location = new System.Drawing.Point(122, 32);
this.cmbSearch.Name = "cmbSearch";
this.cmbSearch.Size = new System.Drawing.Size(121, 21);
this.cmbSearch.Sorted = true;
this.cmbSearch.TabIndex = 2;
this.cmbSearch.SelectedIndexChanged += new System.EventHandler(this.cmbSearch_SelectedIndexChanged);
//
// label10
//
this.label10.AutoSize = true;
this.label10.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label10.Location = new System.Drawing.Point(55, 36);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(61, 16);
this.label10.TabIndex = 1;
this.label10.Text = "Criteriu:";
//
// tabPage1
//
this.tabPage1.Controls.Add(this.pnlFileHeader);
this.tabPage1.Controls.Add(this.tblLytAddMem);
this.tabPage1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(596, 337);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Adauga echipament nou";
this.tabPage1.UseVisualStyleBackColor = true;
//
// pnlFileHeader
//
this.pnlFileHeader.Controls.Add(this.btnLoad);
this.pnlFileHeader.Controls.Add(this.txtFileName);
this.pnlFileHeader.Controls.Add(this.label13);
this.pnlFileHeader.Location = new System.Drawing.Point(8, 6);
this.pnlFileHeader.Name = "pnlFileHeader";
this.pnlFileHeader.Size = new System.Drawing.Size(512, 44);
this.pnlFileHeader.TabIndex = 3;
//
// btnLoad
//
this.btnLoad.Location = new System.Drawing.Point(413, 10);
this.btnLoad.Name = "btnLoad";
this.btnLoad.Size = new System.Drawing.Size(95, 23);
this.btnLoad.TabIndex = 2;
this.btnLoad.Text = "Deschide";
this.btnLoad.UseVisualStyleBackColor = true;
this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
//
// txtFileName
//
this.txtFileName.Location = new System.Drawing.Point(185, 10);
this.txtFileName.Name = "txtFileName";
this.txtFileName.Size = new System.Drawing.Size(222, 23);
this.txtFileName.TabIndex = 1;
this.txtFileName.Click += new System.EventHandler(this.btnLoad_Click);
//
// label13
//
this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(13, 13);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(166, 17);
this.label13.TabIndex = 0;
this.label13.Text = "Incarcati fisierul excel";
//
// tblLytAddMem
//
this.tblLytAddMem.ColumnCount = 2;
this.tblLytAddMem.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 35.91954F));
this.tblLytAddMem.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 64.08046F));
this.tblLytAddMem.Controls.Add(this.panel1, 0, 0);
this.tblLytAddMem.Controls.Add(this.panel2, 1, 0);
this.tblLytAddMem.Controls.Add(this.panel3, 1, 1);
this.tblLytAddMem.Location = new System.Drawing.Point(6, 53);
this.tblLytAddMem.Name = "tblLytAddMem";
this.tblLytAddMem.RowCount = 2;
this.tblLytAddMem.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 61.21673F));
this.tblLytAddMem.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 38.78327F));
this.tblLytAddMem.Size = new System.Drawing.Size(515, 263);
this.tblLytAddMem.TabIndex = 2;
this.tblLytAddMem.Visible = false;
//
// panel1
//
this.panel1.Controls.Add(this.label4);
this.panel1.Controls.Add(this.label3);
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(3, 3);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(145, 154);
this.panel1.TabIndex = 0;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(3, 104);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(128, 17);
this.label4.TabIndex = 3;
this.label4.Text = "Cantitate minima";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 77);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(126, 17);
this.label3.TabIndex = 2;
this.label3.Text = "Cantitate in stoc";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 50);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(119, 17);
this.label2.TabIndex = 1;
this.label2.Text = "Numar de serie";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(79, 17);
this.label1.TabIndex = 0;
this.label1.Text = "ID Produs";
//
// panel2
//
this.panel2.Controls.Add(this.textMinim);
this.panel2.Controls.Add(this.textStoc);
this.panel2.Controls.Add(this.textSerie);
this.panel2.Controls.Add(this.textID);
this.panel2.Location = new System.Drawing.Point(187, 3);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(309, 154);
this.panel2.TabIndex = 1;
//
// textMinim
//
this.textMinim.Location = new System.Drawing.Point(14, 104);
this.textMinim.Name = "textMinim";
this.textMinim.Size = new System.Drawing.Size(59, 23);
this.textMinim.TabIndex = 5;
//
// textStoc
//
this.textStoc.Location = new System.Drawing.Point(14, 77);
this.textStoc.Name = "textStoc";
this.textStoc.Size = new System.Drawing.Size(59, 23);
this.textStoc.TabIndex = 2;
//
// textSerie
//
this.textSerie.Location = new System.Drawing.Point(14, 50);
this.textSerie.Name = "textSerie";
this.textSerie.Size = new System.Drawing.Size(181, 23);
this.textSerie.TabIndex = 1;
//
// textID
//
this.textID.Location = new System.Drawing.Point(14, 19);
this.textID.Name = "textID";
this.textID.Size = new System.Drawing.Size(181, 23);
this.textID.TabIndex = 0;
//
// panel3
//
this.panel3.Controls.Add(this.button1);
this.panel3.Location = new System.Drawing.Point(187, 163);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(309, 97);
this.panel3.TabIndex = 2;
//
// button1
//
this.button1.Location = new System.Drawing.Point(14, 44);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(120, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Actualizeaza";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(12, 12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(604, 363);
this.tabControl1.TabIndex = 0;
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabPage1_Click);
//
// Form1
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(628, 397);
this.Controls.Add(this.tabControl1);
this.Name = "Form1";
this.Text = "Status Report App";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridEchList)).EndInit();
this.tabPage1.ResumeLayout(false);
this.pnlFileHeader.ResumeLayout(false);
this.pnlFileHeader.PerformLayout();
this.tblLytAddMem.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
this.panel3.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.empConstantsBindingSource)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.BindingSource empConstantsBindingSource;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtSearchExpr;
private System.Windows.Forms.DataGridView dataGridEchList;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.ComboBox cmbSearch;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.Panel pnlFileHeader;
private System.Windows.Forms.Button btnLoad;
private System.Windows.Forms.TextBox txtFileName;
private System.Windows.Forms.Label label13;
private System.Windows.Forms.TableLayoutPanel tblLytAddMem;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.TextBox textMinim;
private System.Windows.Forms.TextBox textStoc;
private System.Windows.Forms.TextBox textSerie;
private System.Windows.Forms.TextBox textID;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TabControl tabControl1; } }
Bibliografie
Bruce JOHNSON – ”Professional Visual Studio 2013”, John Wiley & Sons, Indianopolis, 2014, ISBN: 978-1-118-84147-1, 15 pg., 151 pg., 499 pg.
Dumitriu-Lupa NUȘA – ”Introducere în programarea .NET Framework”, Microsoft, Năvodari 2007, 3 pg., 5 pg., 9 pg., 13 pg. [NUȘA07]
Jeff MARTIN, Richard BANKS – ”Visual Studio 2013 Cookbook”, Packt Publishing, Birmingham, 2014, ISBN 978-1-78217-196-6, 22 pg., 118 pg.
John SHARP – ”Microsoft Visual C# 2013 Step by Step”, Octal Publishing, USA, 2013, ISBN: 978-0-7356-8183-5, xix pg., 5 pg., 17 pg., 317 pg, 452 pg.
Marius APETRII – ”Programare orientată pe obiecte”, Facultatea de matematică ”Alexandru Ioan Cuza”, Iași, Curs 7, 4 pg., 8 pg. [APETC7]
https://msdn.microsoft.com/ – ”Overview of the .NET Framework”, ”OLE DB Programmer’s Guide”, ”Microsoft.Office.Interop.Excel”,
Anexa 1 – Codul sursă
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace StatusReport
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new LoginScreen());
}
}
}
Echipament.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace StatusReport
{
class Echipament
{
public string ID { get; set; }
public string Serie { get; set; }
public string Stoc { get; set; }
public string Minim { get; set; }
}
}
MyExcel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using Excel=Microsoft.Office.Interop.Excel;
using System.ComponentModel;
namespace StatusReport
{
class MyExcel
{
public static string DB_PATH = @"";
public static BindingList<Echipament> EchLista = new BindingList<Echipament>();
private static Excel.Workbook MyBook = null;
private static Excel.Application MyApp = null;
private static Excel.Worksheet MySheet = null;
private static int lastRow=0;
public static void InitializeExcel()
{
MyApp = new Excel.Application();
MyApp.Visible = false;
MyBook = MyApp.Workbooks.Open(DB_PATH);
MySheet = (Excel.Worksheet)MyBook.Sheets[1];
lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row;
}
public static BindingList<Echipament> ReadMyExcel()
{
EchLista.Clear();
for (int index = 2; index <= lastRow; index++)
{
System.Array MyValues = (System.Array)MySheet.get_Range("A" + index.ToString(), "D" + index.ToString()).Cells.Value;
EchLista.Add(new Echipament {
ID = MyValues.GetValue(1,1).ToString(),
Serie = MyValues.GetValue(1,2).ToString(),
Stoc = MyValues.GetValue(1,3).ToString(),
Minim = MyValues.GetValue(1,4).ToString()
});
}
return EchLista;
}
public static void WriteToExcel(Echipament ech)
{
try
{
lastRow += 1;
MySheet.Cells[lastRow, 1] = ech.ID;
MySheet.Cells[lastRow, 2] = ech.Serie;
MySheet.Cells[lastRow, 3] = ech.Stoc;
MySheet.Cells[lastRow, 4] = ech.Minim;
EchLista.Add(ech);
MyBook.Save();
}
catch (Exception ex)
{ }
}
public static List<Echipament> FiltruEchLista(string searchValue, string searchExpr)
{
List<Echipament> FilteredList = new List<Echipament>();
switch (searchValue.ToUpper())
{
case "ID":
FilteredList = EchLista.ToList().FindAll(ech => ech.ID.ToLower().Contains(searchExpr));
break;
case "SERIE":
FilteredList = EchLista.ToList().FindAll(ech => ech.Serie.ToLower().Contains(searchExpr));
break;
case "STOC":
FilteredList = EchLista.ToList().FindAll(ech => ech.Stoc.ToLower().Contains(searchExpr));
break;
case "MINIM":
FilteredList = EchLista.ToList().FindAll(ech => ech.Minim.ToLower().Contains(searchExpr));
break;
default:
break;
}
return FilteredList;
}
public static void CloseExcel()
{
MyBook.Saved = true;
MyApp.Quit();
}
}
}
Form2.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Sql;
using System.Data.SqlClient;
namespace StatusReport
{
public partial class LoginScreen : Form
{
public LoginScreen()
{
InitializeComponent();
}
private void btnExit_Click(object sender, EventArgs e)
{
this.Close();
}
private void btnLogin_Click(object sender, EventArgs e)
{
SqlConnection sqlConnect = new SqlConnection();
sqlConnect.ConnectionString = @"Data Source=(LocalDB)\v11.0;AttachDbFilename=C:\Users\cristian.sabac\Documents\DataTable.mdf;Integrated Security=True;Connect Timeout=30";
sqlConnect.Open();
SqlCommand sqlCmd = new SqlCommand("SELECT [USERNAME], [PASSWORD] FROM [dbo].[Table] where [USERNAME] ='" + txtUser.Text + "' and [PASSWORD] ='" + txtPass.Text + "'", sqlConnect);
SqlDataAdapter sqlAdapter = new SqlDataAdapter(sqlCmd);
DataTable dt = new DataTable();
sqlAdapter.Fill(dt);
if (dt.Rows.Count > 0)
{
this.Hide();
Form1 principal = new Form1();
principal.Show();
}
else
{
MessageBox.Show("Username sau parola incorecta. Va rog reincercati.");
}
}
}
}
Form2.Designer.cs
namespace StatusReport
{
partial class LoginScreen
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.panel1 = new System.Windows.Forms.Panel();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.txtPass = new System.Windows.Forms.TextBox();
this.txtUser = new System.Windows.Forms.TextBox();
this.btnExit = new System.Windows.Forms.Button();
this.btnLogin = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// panel1
//
this.panel1.BackgroundImage = global::StatusReport.Properties.Resources.LoginImage;
this.panel1.Location = new System.Drawing.Point(12, 12);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(226, 237);
this.panel1.TabIndex = 0;
//
// label3
//
this.label3.AutoSize = true;
this.label3.BackColor = System.Drawing.SystemColors.Control;
this.label3.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label3.Location = new System.Drawing.Point(244, 12);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(225, 16);
this.label3.TabIndex = 7;
this.label3.Text = "Va rog introduceti credentialele";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label2.Location = new System.Drawing.Point(248, 105);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(61, 13);
this.label2.TabIndex = 11;
this.label2.Text = "Password";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label1.Location = new System.Drawing.Point(248, 61);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(63, 13);
this.label1.TabIndex = 10;
this.label1.Text = "Username";
//
// txtPass
//
this.txtPass.Location = new System.Drawing.Point(315, 102);
this.txtPass.Name = "txtPass";
this.txtPass.PasswordChar = '*';
this.txtPass.Size = new System.Drawing.Size(204, 20);
this.txtPass.TabIndex = 9;
//
// txtUser
//
this.txtUser.Location = new System.Drawing.Point(315, 58);
this.txtUser.Name = "txtUser";
this.txtUser.Size = new System.Drawing.Size(204, 20);
this.txtUser.TabIndex = 8;
//
// btnExit
//
this.btnExit.Location = new System.Drawing.Point(444, 190);
this.btnExit.Name = "btnExit";
this.btnExit.Size = new System.Drawing.Size(75, 23);
this.btnExit.TabIndex = 13;
this.btnExit.Text = "&Iesire";
this.btnExit.UseVisualStyleBackColor = true;
this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
//
// btnLogin
//
this.btnLogin.Location = new System.Drawing.Point(315, 190);
this.btnLogin.Name = "btnLogin";
this.btnLogin.Size = new System.Drawing.Size(75, 23);
this.btnLogin.TabIndex = 12;
this.btnLogin.Text = "&Logare";
this.btnLogin.UseVisualStyleBackColor = true;
this.btnLogin.Click += new System.EventHandler(this.btnLogin_Click);
//
// LoginScreen
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(566, 261);
this.Controls.Add(this.btnExit);
this.Controls.Add(this.btnLogin);
this.Controls.Add(this.label2);
this.Controls.Add(this.label1);
this.Controls.Add(this.txtPass);
this.Controls.Add(this.txtUser);
this.Controls.Add(this.label3);
this.Controls.Add(this.panel1);
this.Name = "LoginScreen";
this.Text = "Ecran de autentificare";
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox txtPass;
private System.Windows.Forms.TextBox txtUser;
private System.Windows.Forms.Button btnExit;
private System.Windows.Forms.Button btnLogin;
}
}
Principal.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using StatusReport;
namespace StatusReport
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
tabControl1.Selecting += new TabControlCancelEventHandler(tabControl1_Selecting);
}
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs args)
{
TabPage current = (sender as TabControl).SelectedTab;
if (string.IsNullOrEmpty(MyExcel.DB_PATH))
{
MessageBox.Show("Va rugam sa deschideti fisierul excel", "Eroare!", MessageBoxButtons.OK, MessageBoxIcon.Error);
args.Cancel = true;
}
}
private void tabPage1_Click(object sender, EventArgs e)
{
TabControl tc = sender as TabControl;
if (tc.SelectedIndex == 1)
{
dataGridEchList.DataSource = (BindingList<Echipament>)MyExcel.EchLista;
dataGridEchList.AutoResizeColumns();
}
}
private void button1_Click(object sender, EventArgs e)
{
Echipament ech = new Echipament { ID = textID.Text.ToString(),
Serie = textSerie.Text.ToString(),
Stoc = textStoc.Text.ToString(),
Minim = textMinim.Text.ToString()
};
MyExcel.WriteToExcel(ech);
clearAllFields();
MessageBox.Show("Detaliile au fost adaugate cu succes", "Succes!", MessageBoxButtons.OK, MessageBoxIcon.Information);
textID.Focus();
}
public void clearAllFields()
{
textID.Text = "";
textStoc.Text = "";
textSerie.Text = "";
textMinim.Text = "";
}
private void Form1_Load(object sender, EventArgs e)
{
}
protected override void OnFormClosing(System.Windows.Forms.FormClosingEventArgs e)
{
if(!string.IsNullOrEmpty(MyExcel.DB_PATH))
MyExcel.CloseExcel();
}
private void cmbSearch_SelectedIndexChanged(object sender, EventArgs e)
{
txtSearchExpr.ReadOnly = false;
}
private void txtSearchExpr_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txtSearchExpr.Text))
{
dataGridEchList.DataSource = MyExcel.FiltruEchLista(cmbSearch.Text.ToString(), txtSearchExpr.Text.ToLower());
}
else
{
dataGridEchList.DataSource = MyExcel.EchLista;
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
private void btnLoad_Click(object sender, EventArgs e)
{
OpenFileDialog ExcelDialog = new OpenFileDialog();
ExcelDialog.Filter = "Fisiere Excel (*.xlsx) | *.xlsx";
ExcelDialog.InitialDirectory = @"C:\";
ExcelDialog.Title = "Alegeti fisierul excel";
if (ExcelDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MyExcel.DB_PATH = ExcelDialog.FileName;
txtFileName.Text = ExcelDialog.FileName;
txtFileName.ReadOnly = true;
txtFileName.Click -= btnLoad_Click;
tabControl1.Selecting -= tabControl1_Selecting;
btnLoad.Enabled = false;
MyExcel.InitializeExcel();
dataGridEchList.DataSource = MyExcel.ReadMyExcel();
tblLytAddMem.Visible = true;
}
}
}
}
Principal.Designer.cs
namespace StatusReport
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support – do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.txtSearchExpr = new System.Windows.Forms.TextBox();
this.dataGridEchList = new System.Windows.Forms.DataGridView();
this.label11 = new System.Windows.Forms.Label();
this.cmbSearch = new System.Windows.Forms.ComboBox();
this.label10 = new System.Windows.Forms.Label();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.pnlFileHeader = new System.Windows.Forms.Panel();
this.btnLoad = new System.Windows.Forms.Button();
this.txtFileName = new System.Windows.Forms.TextBox();
this.label13 = new System.Windows.Forms.Label();
this.tblLytAddMem = new System.Windows.Forms.TableLayoutPanel();
this.panel1 = new System.Windows.Forms.Panel();
this.label4 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
this.textMinim = new System.Windows.Forms.TextBox();
this.textStoc = new System.Windows.Forms.TextBox();
this.textSerie = new System.Windows.Forms.TextBox();
this.textID = new System.Windows.Forms.TextBox();
this.panel3 = new System.Windows.Forms.Panel();
this.button1 = new System.Windows.Forms.Button();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.empConstantsBindingSource = new System.Windows.Forms.BindingSource(this.components);
this.tabPage2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridEchList)).BeginInit();
this.tabPage1.SuspendLayout();
this.pnlFileHeader.SuspendLayout();
this.tblLytAddMem.SuspendLayout();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.panel3.SuspendLayout();
this.tabControl1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.empConstantsBindingSource)).BeginInit();
this.SuspendLayout();
//
// tabPage2
//
this.tabPage2.Controls.Add(this.txtSearchExpr);
this.tabPage2.Controls.Add(this.dataGridEchList);
this.tabPage2.Controls.Add(this.label11);
this.tabPage2.Controls.Add(this.cmbSearch);
this.tabPage2.Controls.Add(this.label10);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(596, 337);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Detalii despre stoc";
this.tabPage2.UseVisualStyleBackColor = true;
//
// txtSearchExpr
//
this.txtSearchExpr.Location = new System.Drawing.Point(422, 32);
this.txtSearchExpr.Name = "txtSearchExpr";
this.txtSearchExpr.ReadOnly = true;
this.txtSearchExpr.Size = new System.Drawing.Size(126, 20);
this.txtSearchExpr.TabIndex = 4;
this.txtSearchExpr.TextChanged += new System.EventHandler(this.txtSearchExpr_TextChanged);
//
// dataGridEchList
//
this.dataGridEchList.AllowUserToOrderColumns = true;
this.dataGridEchList.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
this.dataGridEchList.Location = new System.Drawing.Point(28, 92);
this.dataGridEchList.Name = "dataGridEchList";
this.dataGridEchList.RowHeadersWidth = 50;
this.dataGridEchList.Size = new System.Drawing.Size(520, 210);
this.dataGridEchList.TabIndex = 0;
//
// label11
//
this.label11.AutoSize = true;
this.label11.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label11.Location = new System.Drawing.Point(343, 33);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(73, 16);
this.label11.TabIndex = 3;
this.label11.Text = "Expresie:";
//
// cmbSearch
//
this.cmbSearch.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.cmbSearch.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.ListItems;
this.cmbSearch.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cmbSearch.FormattingEnabled = true;
this.cmbSearch.Items.AddRange(new object[] {
"ID",
"Minim",
"Serie",
"Stoc"});
this.cmbSearch.Location = new System.Drawing.Point(122, 32);
this.cmbSearch.Name = "cmbSearch";
this.cmbSearch.Size = new System.Drawing.Size(121, 21);
this.cmbSearch.Sorted = true;
this.cmbSearch.TabIndex = 2;
this.cmbSearch.SelectedIndexChanged += new System.EventHandler(this.cmbSearch_SelectedIndexChanged);
//
// label10
//
this.label10.AutoSize = true;
this.label10.Font = new System.Drawing.Font("Microsoft Sans Serif", 9.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label10.Location = new System.Drawing.Point(55, 36);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(61, 16);
this.label10.TabIndex = 1;
this.label10.Text = "Criteriu:";
//
// tabPage1
//
this.tabPage1.Controls.Add(this.pnlFileHeader);
this.tabPage1.Controls.Add(this.tblLytAddMem);
this.tabPage1.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(596, 337);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Adauga echipament nou";
this.tabPage1.UseVisualStyleBackColor = true;
//
// pnlFileHeader
//
this.pnlFileHeader.Controls.Add(this.btnLoad);
this.pnlFileHeader.Controls.Add(this.txtFileName);
this.pnlFileHeader.Controls.Add(this.label13);
this.pnlFileHeader.Location = new System.Drawing.Point(8, 6);
this.pnlFileHeader.Name = "pnlFileHeader";
this.pnlFileHeader.Size = new System.Drawing.Size(512, 44);
this.pnlFileHeader.TabIndex = 3;
//
// btnLoad
//
this.btnLoad.Location = new System.Drawing.Point(413, 10);
this.btnLoad.Name = "btnLoad";
this.btnLoad.Size = new System.Drawing.Size(95, 23);
this.btnLoad.TabIndex = 2;
this.btnLoad.Text = "Deschide";
this.btnLoad.UseVisualStyleBackColor = true;
this.btnLoad.Click += new System.EventHandler(this.btnLoad_Click);
//
// txtFileName
//
this.txtFileName.Location = new System.Drawing.Point(185, 10);
this.txtFileName.Name = "txtFileName";
this.txtFileName.Size = new System.Drawing.Size(222, 23);
this.txtFileName.TabIndex = 1;
this.txtFileName.Click += new System.EventHandler(this.btnLoad_Click);
//
// label13
//
this.label13.AutoSize = true;
this.label13.Location = new System.Drawing.Point(13, 13);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(166, 17);
this.label13.TabIndex = 0;
this.label13.Text = "Incarcati fisierul excel";
//
// tblLytAddMem
//
this.tblLytAddMem.ColumnCount = 2;
this.tblLytAddMem.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 35.91954F));
this.tblLytAddMem.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 64.08046F));
this.tblLytAddMem.Controls.Add(this.panel1, 0, 0);
this.tblLytAddMem.Controls.Add(this.panel2, 1, 0);
this.tblLytAddMem.Controls.Add(this.panel3, 1, 1);
this.tblLytAddMem.Location = new System.Drawing.Point(6, 53);
this.tblLytAddMem.Name = "tblLytAddMem";
this.tblLytAddMem.RowCount = 2;
this.tblLytAddMem.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 61.21673F));
this.tblLytAddMem.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 38.78327F));
this.tblLytAddMem.Size = new System.Drawing.Size(515, 263);
this.tblLytAddMem.TabIndex = 2;
this.tblLytAddMem.Visible = false;
//
// panel1
//
this.panel1.Controls.Add(this.label4);
this.panel1.Controls.Add(this.label3);
this.panel1.Controls.Add(this.label2);
this.panel1.Controls.Add(this.label1);
this.panel1.Location = new System.Drawing.Point(3, 3);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(145, 154);
this.panel1.TabIndex = 0;
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(3, 104);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(128, 17);
this.label4.TabIndex = 3;
this.label4.Text = "Cantitate minima";
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(3, 77);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(126, 17);
this.label3.TabIndex = 2;
this.label3.Text = "Cantitate in stoc";
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(3, 50);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(119, 17);
this.label2.TabIndex = 1;
this.label2.Text = "Numar de serie";
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(3, 19);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(79, 17);
this.label1.TabIndex = 0;
this.label1.Text = "ID Produs";
//
// panel2
//
this.panel2.Controls.Add(this.textMinim);
this.panel2.Controls.Add(this.textStoc);
this.panel2.Controls.Add(this.textSerie);
this.panel2.Controls.Add(this.textID);
this.panel2.Location = new System.Drawing.Point(187, 3);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(309, 154);
this.panel2.TabIndex = 1;
//
// textMinim
//
this.textMinim.Location = new System.Drawing.Point(14, 104);
this.textMinim.Name = "textMinim";
this.textMinim.Size = new System.Drawing.Size(59, 23);
this.textMinim.TabIndex = 5;
//
// textStoc
//
this.textStoc.Location = new System.Drawing.Point(14, 77);
this.textStoc.Name = "textStoc";
this.textStoc.Size = new System.Drawing.Size(59, 23);
this.textStoc.TabIndex = 2;
//
// textSerie
//
this.textSerie.Location = new System.Drawing.Point(14, 50);
this.textSerie.Name = "textSerie";
this.textSerie.Size = new System.Drawing.Size(181, 23);
this.textSerie.TabIndex = 1;
//
// textID
//
this.textID.Location = new System.Drawing.Point(14, 19);
this.textID.Name = "textID";
this.textID.Size = new System.Drawing.Size(181, 23);
this.textID.TabIndex = 0;
//
// panel3
//
this.panel3.Controls.Add(this.button1);
this.panel3.Location = new System.Drawing.Point(187, 163);
this.panel3.Name = "panel3";
this.panel3.Size = new System.Drawing.Size(309, 97);
this.panel3.TabIndex = 2;
//
// button1
//
this.button1.Location = new System.Drawing.Point(14, 44);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(120, 23);
this.button1.TabIndex = 0;
this.button1.Text = "Actualizeaza";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Location = new System.Drawing.Point(12, 12);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(604, 363);
this.tabControl1.TabIndex = 0;
this.tabControl1.SelectedIndexChanged += new System.EventHandler(this.tabPage1_Click);
//
// Form1
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(628, 397);
this.Controls.Add(this.tabControl1);
this.Name = "Form1";
this.Text = "Status Report App";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.dataGridEchList)).EndInit();
this.tabPage1.ResumeLayout(false);
this.pnlFileHeader.ResumeLayout(false);
this.pnlFileHeader.PerformLayout();
this.tblLytAddMem.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.panel2.ResumeLayout(false);
this.panel2.PerformLayout();
this.panel3.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.empConstantsBindingSource)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.BindingSource empConstantsBindingSource;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TextBox txtSearchExpr;
private System.Windows.Forms.DataGridView dataGridEchList;
private System.Windows.Forms.Label label11;
private System.Windows.Forms.ComboBox cmbSearch;
private System.Windows.Forms.Label label10;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.Panel pnlFileHeader;
private System.Windows.Forms.Button btnLoad;
private System.Windows.Forms.TextBox txtFileName;
private System.Windows.Forms.Label label13;
private System.Windows.Forms.TableLayoutPanel tblLytAddMem;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Panel panel2;
private System.Windows.Forms.TextBox textMinim;
private System.Windows.Forms.TextBox textStoc;
private System.Windows.Forms.TextBox textSerie;
private System.Windows.Forms.TextBox textID;
private System.Windows.Forms.Panel panel3;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.TabControl tabControl1; } }
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Aplicatie Dezvoltata In Visual Studio 2013 Pentru Gestionarea Unei Baze DE Date Excel (ID: 149431)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
