Filtrarea datelor în Delphi
Vreau să vă spun despre câteva modalități utile de filtrare a datelor care pot fi aplicate pentru a obține efectul de date de screening, pe măsură ce tastați șirul de căutare. De exemplu, în tabel are o coloană de „Last Name“, utilizatorul introduce în caseta de căutare în formă în mod constant ca litere, iar datele sunt filtrate (abandon) - utilizatorul a intrat primul bukovku și afișează toate numele care încep cu prima literă, atunci numai cei care încep cu primul și al doilea, și așa mai departe. d. până când găsește. ceva util sau nimic nu se va. Ie Filtrarea are loc nu coincidență completă, ca parte a unui șir de intrare de către un utilizator. Așa cum va fi prezentat în mai multe domenii de moduri de filtrare.
Un pic de teorie.
Principalul avantaj pe filtre cu căutare este că puteți aplica filtrul fără nici o acțiune pregătitoare pe un set de date, deoarece filtrele nu utilizează indici. Un minus - filtrarea se face mai lent decât căutarea în baza indicelui.
Există două opțiuni cu care puteți seta starea filtrului. Le puteți utiliza separat sau ambele în același timp.
Primul - valoarea șir în Filtrul de proprietate.
În al doilea rând - această condiție este descrisă în tratare a evenimentului OnFilterRecord.
Filtrarea începe imediat după proprietatea Filtrate. Acesta este setat la True.
Filtrul de proprietate.
În primul rând, am descrie posibilitățile oferite de proprietate de filtrare, iar în a doua parte a acestui capitol va explica modul în care puteți utiliza eveniment OnFilterRecord. Această Filtrul de proprietate ar trebui să fie utilizat în principal ca Acest lucru oferă un câștig semnificativ de performanță atunci când procesarea seturi mari de date de volum (în comparație cu evenimentul OnFilterRecord). Acest lucru este vizibil mai ales atunci când un număr mare de înregistrări în tabel (
mai mult de 100.000), și, desigur, mult depinde de capacitatea mașinii. Pentru o cantitate mică de date care urmează să fie prelucrate, diferența nu este viteza vizibilă.
Ei bine, începe. Să presupunem că există un tabel cu câmpurile Nume, prenume, al doilea prenume. Necesitatea de a filtra datele pentru unul dintre domeniile (alegerea ta), adică utilizatorul ar trebui să poată să aleagă care dintre câmpuri pentru a filtra datele. Pentru cei care fac, termenii „câmpul“ și „coloana“ din rezervor - se referă la același lucru.
Sarcina este de a ecran astfel de date pe măsură ce tastați șirul de căutare în Edit.
Arunca sub formă de componente ComboBox și Edit. ComboBox va fi utilizat pentru a selecta coloana, iar cuvântul de căutare este înscris în Edit. Umple proprietatea Elemente în numele coloanelor combobox. Pune proprietate stil de ComboBox egal csDropDownList (astfel încât lovitura nu a fost administrat). Apoi, în tratare a evenimentului Edit1Change scrie următoarele:
Procedura TForm1.Edit1Change (Expeditor: TObject);
începe
dacă Lungime (Edit1.Text)> 0 atunci
începe
ADOTable1.Filtered: = false;
ADOTable1.Filter: = Combobox1.Text + 'LIKE' + # 39 + Edit1.Text + '%' + # 39;
ADOTable1.Filtered: = true;
capăt
altceva ADOTable1.Filtered: = false;
se încheie;
Hit F9 - Voila. După cum puteți vedea, este destul de simplu. Cod curat și simplu. În orice caz, eu traduc în limba română - dacă Editare nu este gol (o eroare de muscă gol), dezactivați filtrul, care formează șirul de filtrare, începe filtrarea dacă sunt goale Editare - filtrarea dezactivare.
În cel mai simplu caz, dacă nu dau posibilitatea de a selecta o anumită coloană, și se filtrează pe un anumit domeniu (de ex „NAME“), șirul de filtru ar arata dupa cum urmeaza:
ADOTable1Fil.Filter: 'NUME LIKE' = + # 39 + Edit1.Text + '%' + # 39;
Condiția string-filtru înseamnă următoarele - pentru a selecta acele intrări din coloana „NAME“, care începe cu aceleași caractere ca și dactilografiat în Edit1.Text.
Să acorde o atenție deosebită lacunelor - „pierdut“ spațiu - nu va funcționa.
Cuvânt cheie cum ar permite un șablon pentru a compara siruri de caractere. Astfel, este necesar să se cunoască următoarele:
simbolul „_“ (subliniere) - se potrivește cu orice caracter unic
caracterul „%“ (procente) - înlocuiește orice secvență de caractere.
Insigna # 39 - indică numărul de caractere „(ghilimele) în tabelul de cod ASCII. Faptul că valoarea de filtrare trebuie să fie specificate în ghilimele simple, precum ghilimele simple sunt utilizate pentru siruri de caractere în limitări Delphi este de a pune într-un singur șir citat, acesta trebuie să fie pus de două ori. Proiectare # 39 + Edit1.Text + '%' + # 39 este identic cu '' '' + Edit1.Text + '%' + '' ''. în cazul în care prima opțiune nu este adevărat o dată poponyatnee. Puteți utiliza, de asemenea speciale. Funcția QuotedStr, care returnează un șir de caractere delimitat de ghilimele simple.
În general, următoarele trei opțiuni pentru formarea de linii în exact aceeași lucrare, și care versiune este mai ușor de utilizat, decide pentru tine.
ADOTable1.Filter: 'NUME LIKE' = + '' '' + Edit1.Text + '%' + '' '';
ADOTable1.Filter: 'NUME LIKE' = + QuotedStr (edit1.Text + '%');
ADOTable1Fil.Filter: 'NUME LIKE' = + # 39 + Edit1.Text + '%' + # 39;
Dă-i drumul. Dacă, de exemplu, pentru a căuta orice apariție a șirului de căutare în înregistrările, și nu din primul caracter, șirul de filtru ar arăta după cum urmează:
ADOTable1.Filter: 'NUME LIKE' = + # 39 + '%' + Edit1.Text + '%' + # 39;
Am observat o „%“ înainte de Edit1.Text? Traduce ca - selectați intrările respective din coloana „NAME“, care este o secvență de caractere care sunt introduse în Edit1.Text.
Toate acestea este bine, dar este adesea necesar pentru a filtra pe mai multe coloane. Apoi se aplică un pic altele mici. Design.
Adăugați încă două componente în formă Edit. ComboBox nu va folosi, o puteți șterge, după cum ne fiecare câmp (Editare) va fi responsabil pentru introducerea informațiilor de către o anumită coloană. Chiar și adăugați un buton, acesta va începe filtrarea. Se pare a fi următoarea construcție pentru a funcționa corect:
Procedura TForm1.Button1Click (Expeditor: TObject);
începe
ADOTable1.Filtered: = false;
ADOTable1.Filter: 'NUME LIKE' = + # 39 + Edit2.Text + '%' + # 39 + 'I' + 'NUME LIKE' + # 39 + Edit3.Text + '%' + # 39 + 'I' + 'patronim LIKE' + # 39 + Edit4.Text + '%' + # 39;
ADOTable1.Filtered: = true;
se încheie;
Ea funcționează, dar numai în cazul în care datele sunt introduse în toate cele trei domenii. Dacă unul dintre câmpurile de introducere (Editare) gol - eroare ia „Argumentele au un tip greșit.“
Cu toate acestea, există o modalitate de a face cu ea. În primul rând, codul:
Procedura TForm1.Button1Click (Expeditor: TObject);
var filtr, // string filtru format
add: string;
începe
ADOTable1.filtered: = false;
filtr: = '';
în cazul în care lungimea (edit2.text)> 0 atunci
filtr: 'NUME LIKE' = + # 39 + Edit2.Text + '%' + # 39;
în cazul în care lungimea (edit3.text)> 0 atunci
începe
în cazul în care lungimea (filtr)> 0 apoi se adaugă: = 'și' altceva adaugă: = '';
filtr: = filtr + adaugă + 'NAME LIKE' + # 39 + Edit3.Text + '%' + # 39;
se încheie;
în cazul în care lungimea (edit4.text)> 0 atunci
începe
în cazul în care lungimea (filtr)> 0 apoi se adaugă: = 'și' altceva adaugă: = '';
filtr: = filtr + adaugă + 'patronymic LIKE' + # 39 + Edit4.Text + '%' + # 39;
se încheie;
în cazul în care lungimea (filtr)> 0 atunci
începe
ADOTable1.Filter: = filtr;
ADOTable1.filtered: = true;
capăt
Showmessage altceva ( „Toate câmpurile sunt goale!“);
Implicațiile acestui fapt, este necesar să se verifice câmpul de intrare gol sau nu, și apoi formând un șir de filtru. Mai mult decât atât, din moment ce al doilea câmp de intrare și de necesitatea de a verifica linia de filtrare. Este necesar pentru formarea corespunzătoare a rândului următor.
De exemplu, dacă câmpul Edit2 (Last) este gol, și în consecință, filtrul va fi gol string (filtr: = „“). și, de exemplu, câmpul Edit3 (NAME) este umplut, ceea ce înseamnă că șirul filtrului trebuie să ia forma de 'NAME LIKE' + # 39 + Edit3.Text + '%' + # 39.
în loc de 'și' + 'NAME LIKE' + # 39 + Edit3.Text + '%' + # 39. (Adică fără „și“ mai întâi).
Următorul fragment de cod și se execută:
în cazul în care lungimea (edit3.text)> 0 atunci
începe
în cazul în care lungimea (filtr)> 0 apoi se adaugă: = 'și' altceva adaugă: = '';
filtr: = filtr + adaugă + 'NAME LIKE' + # 39 + Edit3.Text + '%' + # 39;
se încheie;
.
Din nou traduce - Edit3 în cazul în care nu este gol, apoi verificați linia de filtrare (filtr) în cazul în care nu este gol, apoi pentru a adăuga storke de filtru „și“ + „nume de genul“ + # 39 + Edit3.Text + „%“ + # 39 dacă sunt goale apoi pur și simplu 'NAME LIKE' + # 39 + Edit3.Text + '%' + # 39.
Toate. După atribuirea șir format (filtr) proprietate ADOTable1.Filter și filtrare alerga.
în cazul în care lungimea (filtr)> 0 atunci
începe
ADOTable1.Filter: = filtr;
ADOTable1.filtered: = true;
capăt
Showmessage altceva ( „Toate câmpurile sunt goale!“);
.
Prin urmare, în cazul în care, în acest stadiu filtr = „“, atunci nici unul dintre câmpuri nu au fost completate, ca și o inscripție corespunzătoare scoate.
Explicația este un pic confuz, dar merită o privire mai atentă la codul și totul devine clar. Privind în perspectivă, voi spune că, dacă utilizați evenimentul OnFilterRecord, necesitatea de a verifica prezența în caractere dispare din câmpul de intrare (de exemplu. Este mai convenabil și mai ușor de utilizat), dar atunci când aceasta scade rata de filtrare. Dar este de remarcat doar în procesarea seturilor de date de mare volum. În cele din urmă am spus, cu excepția funcționării și pot fi utilizate, precum și alte operații logice sau, nu, XOR. atunci când condițiile de formare filtru linie de mai multe coloane, deși o astfel de necesitate apare rar.
Pot skachatrabochy exemplu de filtrare pe baza proprietăților filtrului.
Avem de a face cu evenimentul OnFilterRecod.
Să ne uităm la antetul procedurii de
Procedura TForm1.Table1FilterRecord (DataSet: TDataSet; var Acceptare: Boolean);
DataSet - set de date filtrate numele. Acceptarea este de tip Boolean, ceea ce înseamnă că poate lua două valori reale - să ia de înregistrare, fals - respinge. Cine nu sunt prieteni cu limba engleză translate: accepta -Adopts, ia, sunt de acord.
Principiul este acela că - în OnFilterRecord iterează handler prin toate înregistrările unui anumit domeniu (câmpuri) din datele din tabel pentru respectarea condițiilor de filtrare.
Pentru claritate, câteva exemple:
Permiteți-mi să vă reamintesc încă o dată că Acceptare - variabila booleană, ceea ce înseamnă că puteți utiliza operatori booleeni (= <>, <,>, <=,>=, Și, sau, nu), să-l atribuie o anumită valoare.
Să presupunem că tabelul are câmpuri în luna și anul care au tip întreg și să conțină anul și luna nașterii de altcineva.
TForm1.Table1FilterRecord (DataSet: TDataSet; var Acceptare: Boolean);
începe
Acceptare: = (DataSet [ 'YEAR']> 1973);
se încheie;
Undeva în program
...
Table1.Filtered: = true;
...
Ca rezultat DBGrid înregistrările de afișare în care valoarea a anului câmp mai mult de 1973.
Dacă scrieți un handler această linie:
Acceptare: = (DataSet [ 'YEAR']> 1973) și ((DataSet [ 'LUNA']> 5) și (DataSet [ 'MONTH'] <9));
înregistrările afișate acelor persoane care au fost născuți după 1973 de vară.
Cred că totul este clar - DataSet [ „COLUMN_NAME“] „trage“ valoarea următoare intrării coloană specificată, apoi Accept: = nekotoroe_logicheskoe_uslovie;
De dragul experimentului set Acceptare: = true; și să aducă toate înregistrările, dacă Accept: = false; - nici unul.
Dacă, din anumite motive pe care doriți să apeleze la setul de date nu este pe numele coloanei, și numărul său, puteți folosi un design DataSet.Fields [column_num] .AsString DataSet în loc de [ „COLUMN_NAME“].
Teoria este terminat, trece la practica.
Spune tabelul are câmpul NAME (de tip șir) și au un șir de căutare de intrare - edit1.
Trebuie să avem atunci când intră în următorul caracter este o filtrare (mai întâi pe primul caracter, apoi primul și al doilea, și așa mai departe). Cu alte cuvinte, trebuie să definiți o condiție în OnFilterRecord, și în tratare a evenimentelor pentru a rula OnEdit1Change de filtrare - Table1. Filtrate: = true;.
Deci, începe sculptarea OnFilterRecord.
Rămâne doar să intensifice handler-ul nostru, așa cum sa menționat mai sus, în caz OnEdit1Change ca aceasta:
Procedura TForm1.Edit1Change (Expeditor: TObject);
începe
table1.Filtered: = false;
table1.Filtered: = true;
se încheie;
Asta e tot. Aproape. Există un alt mod de a „caracter cu caracter“ filtrare, dar funcționează un pic ca exemplul anterior. În primul rând este codul:
Procedura TForm1.Table1FilterRecord (DataSet: TDataSet; var Acceptare: Boolean);
începe
accepta: = poz (Edit1.Text, DataSet [ 'NAME'])<>0);
se încheie;
Pos caută o funcție subșir de a intra în șir, în cazul în care substringul este găsit revine în poziția de apariție a secvenței specificate de caractere din șirul specificat, dar că nu ne interesează, este interesant faptul că în cazul în care șirul specificat nu este o anumită secvență de caractere, funcția returnează zero. Adică, dacă oriunde în rândul care conține numele (nu doar din prima literă, iar această diferență) este găsită combinația dorită de simboluri, este acceptat intrarea.
Dacă filtrarea ar trebui să fie litere insensibil, linia ar trebui să arate în felul următor:
Oh, și, uneori, trebuie să știți cât de multe înregistrări sunt filtrate în setul de date, puteți utiliza proprietatea RecordCount. Se returnează numărul actual de înregistrări din setul de date. De exemplu, puteți utiliza următoarea structură:
În acest caz, acesta poate fi introdus în caz de ieșire OnEdit1Change imediat după activarea procedurii de filtrare.
Aici puteți descărca un exemplu de lucru de filtrare bazate pe evenimente OnFilterRecord.
PS. Fiecare dintre metodele are propriile avantaje și dezavantaje. proprietate filtru oferă un câștig considerabil în viteza de procesare, și OnFilterRecord eveniment mult mai „flexibil“ și mai ușor de utilizat. Utilizați proprietatea Filtru în aceste cazuri, dacă se poate face fără a folosi OnFilterRecord.
Dacă utilizați ambele metode, merită să ne amintim că de tratare a evenimentelor mai degrabă completează decât înlocuiește proprietatea de filtrare, de exemplu, în cazul în care filtrarea este activată și St-filtru cuprinde o valoare de filtru, o relație logică de tratare a evenimentului OnFilterRecord și filtru (filtru) asociat " ȘI „(ambele).
Adăugarea unui marcaj pentru materialul: