Tehnički članak

HotXLS validacija podataka, AutoFilter i tabele u Delphiju

Tri funkcije u HotXLS-u dele radni list, ali rade na potpuno različitim objektima, a problemi nastaju kada pretpostavite da rade slične stvari. Validacija podataka (data validation) vezuje pravilo za raspon koje ograničava šta korisnik može upisati u njega. AutoFilter pridružuje definiciju sačuvanih kriterijuma regiji i menja koje redove pregledač prikazuje. Tabela omotava raspon u imenovanu, tipiziranu strukturu sa trakastim oblikovanjem (banded styling). Jedna ograničava unos, jedna beleži prikaz, jedna nameće shemu. Nijedna od njih sama po sebi ne pomera vrednost niti jedne ćelije, a AutoFilter posebno vara ljude jer ta reč sugeriše akciju, dok zapravo čuva samo definiciju. Znati koji objekat svaki poziv dotiče i kada se efekat stvarno materijalizuje ono je što odvaja radnu svesku koja se u Excelu ponaša isto kao i u vašim testovima od one koja tiho odstupa

AutoFilter čuva definiciju, on ne iseca redove

AutoFilter u sačuvanoj datoteci je zapis o kriterijumima. Skrivanje redova događa se kasnije, kada Excel otvori radnu svesku i proceni kriterijume u odnosu na podatke. HotXLS verno zapisuje taj zapis i ništa ne iseca: svaki red koji ste filtrirali i dalje je fizički prisutan u datoteci. Pipeline koji primenjuje filter za odbacivanje odbijenih porudžbina i zatim ponovo čita radnu svesku videće ih sve, uključujući i odbijene, pa je kod tačan prema API-ju, ali pogrešan prema mentalnom modelu autora. Na XLSX radnom listu, SetAutoFilter deklarise filtriranu regiju, a AddAutoFilterColumn pridružuje kriterijume jednom njenom stubcu. Kada poslužiteljski kod treba stvarni ishod, primerice za broj redova u rezimeu ili za prosleđivanje samo podudarnih redova, biblioteka procenjuje kriterijume za vas umesto da se pretvara da se datoteka promenila:

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  R, Visible: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('orders.xlsx');
    Sheet := Book.Sheets[0];

    Sheet.SetAutoFilter('A1:E500');
    // Column id 3 = fourth column INSIDE the filter range (0-based offset)
    Sheet.AddAutoFilterColumn(3, xlsxAfOpGreaterOrEqual, '1000');

    Visible := 0;
    for R := 2 to 500 do
      if Sheet.AutoFilterRowVisible(R) then
        Inc(Visible);
    // Visible now matches what Excel will show after opening the file

    Book.SaveAs('orders-filtered.xlsx');
  finally
    Book.Free;
  end;
end;

Metoda AutoFilterRowVisible daje odgovor po redu, a PreviewAutoFilterRows prolazi kroz celu regiju putem povratnog poziva (callback) kada trebate podudarni skup u jednom prolazu. Postoji slučaj u kojem nijedno od toga nije ispravno rešenje: ako je zahtev da isključeni redovi uopšte ne smeju postojati u datoteci, što je bezbednosni rez, a ne samo prikaz, izbrišite te redove u potpunosti. Filter je tu pogrešan alat, jer ga bilo koji primalac može ukloniti jednim klikom i podaci koje ste hteli da zatajite ponovo su na ekranu

ID kolone je pomak, a ne broj kolone

Komentar u gornjem isečku koda označava zamku koja košta najviše vremena za uklanjanje pogrešaka u ovom API-ju. AddAutoFilterColumn identifikuje svoj cilj prema položaju na bazi 0 unutar raspona filtera, a ne prema koloni radnog lista. Za filter na A1:E500 ta se dva sistema numerisanja slučajno razlikuju za jedan, što je tačno ona vrsta promašaja koja preživi brzi test i puca onog trenutka kada kolega filtrira drugu kolonu. Za filter koji počinje na koloni C, ID 0 znači kolonu C, i nepodudaranje brzo postaje očigledno. Kada se raspon filtera izračunava u vreme izvršavanja, izvedite ID kolone iz iste varijable koja je izgradila niz raspona, nikada iz konstante kolone radnog lista. Svaki stubac prihvata drugi uslov kroz preopterećenje koje prima dva operatora, dva kriterijuma i and/or poveznicu, što odražava Excelov prilagođeni dijaloški okvir filtera. XLS fasada pokriva isto područje sa SetAutoFilter i ApplyAutoFilter, čiji parametri kriterijuma i operatora prate starije konvencije u stilu COM-a i numerišu polje od 1. Promena fasada znači promenu baze indeksa, pa mesto poziva zaslužuje komentar koji govori koja je fasada u igri

Pravila validacije su ugovor pod kojim vaši korisnici uređuju

Od ove tri funkcije, validacija je jedina koja aktivno ograničava budući unos i zaslužuje najviše pažnje pri dizajniranju radnih sveski koje se šalju na popunjavanje i vraćaju na obradu. Varijanta liste (list variant) nosi većinu tog posla:

var
  Idx: Integer;
begin
  Idx := Sheet.AddListValidation('C2:C500', 'New,Approved,Blocked');
  Sheet.DataValidations[Idx].SetPrompt('Status',
    'Pick one of the listed states');
  Sheet.DataValidations[Idx].SetError('Invalid status',
    'Type or paste only listed values', xlsxDvErrStop);
  Sheet.DataValidations[Idx].AllowBlank := False;

  // Quantities: whole numbers, zero or more
  Sheet.AddWholeNumberValidation('D2:D500', xlsxDvOpGreaterOrEqual, '0');
end;

Osim liste i celih brojeva, ista familija pokriva decimale, datume, vremena, dužinu teksta i formule slobodnog oblika putem AddCustomValidation, a generička metoda AddDataValidation izlaže punu matricu tipova i operatora za graditelje pravila vođene konfiguracijom. Stil greške važniji je nego što njegovo ime sugeriše. xlsxDvErrStop direktno odbija loš unos; stilovi upozorenja (warning) i informacija propuštaju vrednost nakon jednog klika. Odaberite po koloni na osnovu toga može li kod koji ponovo čita radnu svesku tolerisati vrednost van pravila. Dve granice pripadaju tekstu upita ili README datoteci koju šaljete sa datotekom. Validacija u Excelu štiti kucanje, ali lepljenje bloka preko validiranog raspona prolazi pored pravila, pa svaki kod koji ponovo čita podatke mora ponovo da sprovede validaciju umesto da veruje ćelijama. Takođe, pravilo pokriva tačan raspon koji ste mu predali, što znači da dodavanje validacije pre nego što saznate konačan broj redova ostavlja dodati rep nezaštićenim. Najpre zapišite podatke, a zatim prilagodite veličinu pravila stvarnom opsegu

Nasleđena fasada nudi iste familije pravila sa jednom ergonomskom razlikom. Metode na XLS strani, odnosno AddWholeNumberValidation, AddDecimalValidation, AddDateValidation, AddTimeValidation, AddTextLengthValidation i AddCustomValidation, vraćaju objekat TDataValidation direktno, a ne indeks, pa se konfiguracija prompta i greške nadovezuje na vraćenu referencu umesto preko pretraživanja. Nabrajanje operatora (xlsDvBetween, xlsDvGreaterThan i ostali) odražava XLSX skup, pa se kod za izgradnju pravila prenosi između fasada bez obzira na razliku u stilu povrata. Sam tekst prompta zaslužuje jednaku pažnju kao i pravilo. Padajući meni koji odbija unos sa praznim okvirom za grešku uči korisnike da pišu IT podršci; onaj koji navodi dopuštena stanja uči ih da poprave ćeliju i nastave dalje

Jedan obrt polariteta koji biblioteka preuzima za vas

Svako ko je ručno čitao OOXML validacijski XML susreo se sa obrnutim atributom showDropDown: u ISO/IEC 29500 istinita vrednost (true) znači 'potisni strelicu padajućeg menija', što je suprotno od onoga kako naziv glasi. HotXLS to interno preokreće, tako da svojstvo ShowDropDown na validacijskom pravilu znači ono što kaže, pri čemu true prikazuje padajući meni. Jedini način da pogrešite jeste mešanje nivoa istine, postavljanjem svojstva iz koda dok kolega proverava sačuvani XML i 'ispravlja' atribut koji mu se čini naopako postavljenim. Odlučite jesu li svojstvo ili sirovi XML merodavni za alate za reviziju i zapišite to preokretanje tamo gde ta odluka živi

Tabele rasponu daju shemu i naziv

Tabela radnog lista, ListObject u Excel terminima, omotava raspon u naziv, tipizirane kolone, trakasto oblikovanje i podršku za strukturirane reference. To je funkcija koja čini da generisana radna sveska izgleda dovršeno čim korisnici počnu da sortiraju i proširuju podatke. Stvaranje je simetrično na obe fasade, pri čemu AddTable prima naziv, raspon i popis kolona:

var
  Cols: TStringList;
begin
  Cols := TStringList.Create;
  try
    Cols.CommaText := 'OrderId,Customer,Status,Amount,Owner';
    Sheet.AddTable('Orders', 'A1:E500', Cols);
  finally
    Cols.Free;
  end;
end;

Na XLSX strani, rezultirajući objekat tabele izlaže svojstvo StyleName (ugrađena familija TableStyleMedium2 i njeni srodnici), prekidače traka i zastavicu reda sa ukupnim vrednostima, pa je primena kućnog stila dodela svojstva radije nego ručni prolaz oblikovanja. U nasleđenim .xls datotekama isti poziv zapisuje BIFF8 zapise tabele, a fasada takođe nudi AddPivotTable za sažete prikaze izgrađene od polja redova, kolona i podataka, što je podsetnik da se 'tabele' u starijem formatu protežu dalje nego što to ListObject u OOXML-u čini. Imenujte tabele onako kako imenujete poglede baze podataka. Kasniji kod koji čita Orders[Amount] pomoću strukturirane reference preživljava promenu redosleda kolona koja lomi pozicijski kod

Dve konvencije štede čišćenje kasnije. Excel zahteva da nazivi tabela budu jedinstveni u celoj radnoj svesci, pa generator koji emituje jedan list po regiji treba shemu poput Orders_EMEA umesto ponovne upotrebe Orders. Duplikat ne uzrokuje neuspeh u vreme zapisivanja; negativno se očituje kao dijaloški okvir za popravku kada korisnik otvori datoteku, što je najgore mesto za njegovo otkrivanje. Druga konvencija odnosi se na red sa ukupnim iznosima: kada je omogućen, on se nalazi direktno ispod raspona podataka, pa bilo koji kod koji kasnije dodaje po principu 'zadnji korišćeni red plus jedan' piše u traku sa ukupnim iznosima umesto nakon nje. Pratite opseg podataka odvojeno od opsega tabele i dodavanja će sleteti tamo gde očekujete

Ove tri funkcije prirodno se spajaju u izlaznim datotekama za unos podataka. Tabela definiše područje koje se može uređivati, validacija ograničava kolone u koje korisnici tipkaju, a unapred postavljeni filter štedi primaocu prvih nekoliko klikova. Postoji valjan argument za slanje već primenjenog filtera kako bi se radna sveska otvorila usredsređena na redove koji su važni, sve dok se sećate da su isključeni redovi i dalje u datoteci i da ih radoznali primalac može otkriti. Efikasno dobijanje rezultata upita u list, što je uzvodna polovina ovog pipeline-a, pokriveno je u članku izvoz rezultata baze podataka u Excel iz Delphija, a radne sveske u kojima formule sažimaju validirane podatke imaju koristi od članka definisani nazivi za stabilne reference među listovima

Validacija, filteri i tabele čine razliku između slanja mreže vrednosti i slanja male aplikacije. Potpuna referenca pravila, filtera i tabela nalazi se na stranici proizvoda HotXLS Component