Tehnički članak

Dupliciranje XLSX radnog lista u Delphiju uz HotXLS

Izradili ste jedan list točno kako treba. Zaglavni pojas je spojen, širine stupaca odgovaraju podacima, prva dva retka su zamrznuta, područje ispisa i margine postavljeni su za čist A4 izvoz, a kartica je obojena kako bi je financije mogle pronaći. Sada izvještaj treba dvanaest takvih, po jedan za svaku regiju, svi počevši od istog rasporeda. Ponovno izgrađivati taj list u kodu dvanaest puta znači da će se uvući suptilni drift: regija 7 dobit će stupac jednu točku uži, regija 11 izgubit će zamrzavanje, a nitko to neće primijetiti dok PDF ne sleti na stol menadžera. Ono što vam zapravo treba programska je verzija Excelova desni klik, Move or Copy, Create a copy: uzmite gotov list i izbacite neovisne duplikate

XLSX engine u HotXLS-u, izvornoj Delphi i C++Builder biblioteci koja čita i piše Excel datoteke bez automatskog upravljanja Excelom, već je mogao premještati listove, brisati listove i kopirati raspon ćelija između listova. Ono što nije mogao sve do v2.91.0 bilo je klonirati cijeli radni list jednim pozivom. To izdanje dodaje dvije ulazne točke: TXLSXWorksheet.CopyFrom, koji kopira stanje na razini lista s jednog radnog lista na drugi, i TXLSXSheets.Duplicate, koji dodaje novi list i pokreće CopyFrom za vas. Zanimljiv dio nije to što kopira stvari. To je namjerna granica između onoga što se dubinski kopira i onoga što ne, i zašto je ta granica baš tu gdje jest

Jedan poziv za kloniranje gotovog lista

Visokonivoična operacija je Duplicate. Dajte joj 1-bazirani indeks izvorišnog lista i vratit će potpuno novi radni list koji zrcali raspored i podatke izvornika. Konvencija indeksa odgovara Items[] na XLSX strani, pa je list jedan indeks 1, a ne 0; proslijedite indeks izvan raspona i dobit ćete nil umjesto iznimke, isti ugovor o neuspjehu koji koristi i ostatak kolekcije XLSX listova

var
  Book: TXLSXWorkbook;
  Template, Copy: TXLSXWorksheet;
begin
  Book := TXLSXWorkbook.Create;
  try
    Template := Book.Sheets.Add('Template');
    Template.Cells[1, 1].Value := 'Quarterly Statement';
    Template.Range['A1:C1'].Merge;
    Template.ColWidth[1] := 18;
    Template.FreezePanes(2, 1);          // freeze top row + first column
    Template.TabColorIsAuto := False;
    Template.TabColor := $FF1F4E79;

    // Clone with an explicit name...
    Copy := Book.Sheets.Duplicate(1, 'Region-North');
    // ...or let it pick the Excel-style default name.
    Copy := Book.Sheets.Duplicate(1);    // -> "Template (2)"

    Book.SaveAs('regions.xlsx');
  finally
    Book.Free;
  end;
end;

Dvije stvari u tom isječku vrijedi malo usporiti. Prvo, FreezePanes uzima argumente red-prvi, FreezePanes(ARow, ACol), pa se poravnava s Cells[Row, Col] indeksiranjem; duplikat nasljeđuje točan razmak zamrzavanja. Drugo, metoda je nazvana Duplicate i ne očiglednijim Copy, i to nije stvar stila. Copy je standardna rutina u System jedinici, koja se stalno koristi za stringove i dinamičke nizove. Metoda nazvana Copy na klasi bi je zasjenila unutar tijela metoda i stvorila upravo onu nejasnoću u razrješenju koja vas ugrize šest mjeseci kasnije. Duplicate zaobilazi cijeli problem i čita se ispravno na mjestu poziva

Zadano ime slijedi Excelovo vlastito pravilo

Kada pozovete overload s jednim argumentom ili proslijedite praznu tekstualnu vrijednost za ime, novi list dobiva ime prema izvornom uz sufiks (2) i taj se sufiks povećava dok ime ne postane jedinstveno. Duplicirajte Template list jednom i dobit ćete Template (2); duplicirajte ga opet i dobit ćete Template (3), jer je Template (2) već zauzeto. To preslikava imena koja Excel generira vlastitom naredbom Create a copy, pa radna knjiga koju vaš kod proizvede izgleda onako kako bi korisnik očekivao da izgleda ručno duplicirana. Provjera jedinstvenosti radi nad živom kolekcijom listova, što znači da preskače i imena koja ste ručno stvorili, a ne samo ona iz ranijih dupliciranja

Ako generirate jedan list po regiji ili po mjesecu, radije se oslonite na overload s eksplicitnim nazivom. Predvidljiva Region-North, Region-South shema je kasnije lakša za adresiranje od niza (2), (3) sufiksa, i drži vaše definirane nazive i formule između listova čitljivima

Što CopyFrom dubinski kopira

Ispod haube, Duplicate dodaje list i zatim poziva CopyFrom(ASource), koji također možete pozvati izravno kada želite klonirati na list koji ste već stvorili. CopyFrom se unaprijed štiti od dvaju degeneriranih slučajeva: kopiranje s nil, ili kopiranje lista na samog sebe, oboje odmah vraća i ne radi ništa. Sve nakon toga je samo kopiranje i namjerno je široko

Prvo dolaze podaci ćelija. CopyFrom traži od izvora svoj UsedRange, čvrsti ograničavajući okvir popunjenih ćelija i spojenih područja, i ponovno koristi postojeću CopyRangeTo mehaniku kako bi prenio svaku vrijednost, formulu i indeks stila po ćeliji u cilj, počevši na A1. Povrh ćelija, reproducira cijeli sloj stanja na razini lista koji predlošku daje dovršen izgled:

  • Spojene raspone, ponovno stvorene prema koordinatama tako da banner pokriva isti pravokutnik
  • Širine stupaca i visine redaka, plus popisi skrivenih, sažetih i outline razina, kopirani doslovno tako da se nedefoltni redci i stupci poravnaju točno
  • Freeze panes i stanje prikaza: razina zumiranja, prikaz mrežnih linija i nultih vrijednosti, smjer zdesna nalijevo i tip prikaza
  • Stanje zaštite s opcijama dopuštenja po radnji, tako da zaključani predložak ostane zaključan na isti način
  • Cijeli blok postavki stranice: margine, orijentacija, veličina papira, skaliranje i fit-to-page, područje ispisa, naslovi ispisa, zaglavlja i podnožja te zastavice print-gridlines i print-headings
  • Raspon AutoFiltera, boja kartice i vidljivost lista

Rezultat je list koji ispisuje, filtrira i prikazuje se identično izvoru. A budući da se ćelije, spajanja i liste dimenzija fizički ponovno stvaraju na novom listu umjesto da se aliasiraju, duplikat je potpuno neovisan. Zapišite 999 u ćeliju na kopiji i izvor zadržava svoju izvornu vrijednost; ta neovisnost je najvažnije svojstvo klona namijenjenog paralelnim regionalnim izvještajima, a isporučeni SheetCopy demo to izričito potvrđuje

Što CopyFrom ostavlja plitkim i zašto

Sada iskreni dio. Grafikoni, ugrađene slike, XLSX tablice, validacije podataka i pravila uvjetnog formatiranja nisu kopirani. To je dokumentirana, namjerna granica, a ne propust, i vrijedi razumjeti obrazloženje kako biste planirali oko nje umjesto da vas iznenadi

Svaka od tih kolekcija nosi identitet i reference koje ne preživljavaju naivno kopiranje polja. Grafikon pokazuje na izvorni raspon podataka i posjeduje odnos crtanja u OOXML paketu; kloniranje objekta bez preslikavanja odnosa i referenci serija proizvodi grafikon koji se prikazuje nad pogrešnim podacima ili paket koji Excel označi kao potreban za popravak. Tablica ima ime koje mora biti jedinstveno unutar radne knjige, zaglavni red vezan uz određene stupce i vlastiti automatski generirani odnos. Uvjetna formatiranja i validacije podataka priključuju se na koordinatne raspone i, u slučaju validacije, mogu referencirati druge raspone formulom. Dubinsko kopiranje bilo čega od ovoga ispravno znači prepisivanje referenci i stvaranje svježih identiteta, što je stvaran posao sa stvarnim načinima kvara. Napraviti to napola, kopiranjem objekta ali ne i njegovih referenci, gore je nego ne kopirati uopće: dobivate datoteku koja se otvara s upitom za popravak i tiho gubi sadržaj. Zato engine kopira stvari koje može čisto kopirati i ostavlja kolekcije koje nose reference pozivatelju, koji zna na što cilj treba pokazivati

U praksi to znači da je radni tok za bogatiji predložak: duplicirajte list da dobijete ćelije, raspored i postavu ispisa, a zatim ponovno izgradite grafikon, tablicu, validacije ili uvjetna formatiranja na kopiji istim API-jem kojim ste ih prvi put stvorili. Budući da ih stvarate protiv vlastitih raspona duplikata, reference izlaze točne po konstrukciji. Za grafikon koji čita A1:C10 podatke, dodajte novi grafikon na kopiji koji pokazuje na kopijin A1:C10; za AutoFilter koji želite živ, znajte da se raspon filtra i dalje prenosi, pa samo ponovno primijenite kriterije stupaca. Pravila uvjetnog formatiranja i validacije podataka koja biste ponovno dodali kroz iste pozive opisane u članku o spojenim ćelijama i rasporedu predložaka izvještaja, koji prolazi kroz tablicu spajanja i model raspona koje duplikat nasljeđuje.Gdje dupliciranje sjeda u izvještajni cjevovod

Dupliciranje radnog lista prirodan je pratilac generiranja vođenog mjestodržateljima. Pristup s tokenima koji je usidren u

vodič za generiranje izvještaja na temelju predložaka u Delphiju rješava problem upisivanja podataka u raspored koji uređuju drugi ljudi; dupliciranje rješava problem potrebe za tim rasporedom mnogo puta u jednoj radnoj knjizi. Spojite ih i obrazac je čist: zadržite jedan netaknuti list sa svojim tokenima, spajanjima i postavom ispisa, a zatim za svaku regiju ili period pozovite Template, ispunite tokene klona tim komadom podataka i nastavite dalje. Netaknuti predložak nikad se ne mijenja, pa ostaje pouzdan izvor za sljedeći klon, a svaki izlazni list počinje od rasporeda identičnog bajt za bajtom.DuplicateJedna napomena o slijedu spašava čitavu klasu zabune. Duplicirajte list

prije nego što u njega ulijete podatke, a ne nakon. Predložak bi trebao držati strukturu i oblikovanje, a ne brojeve iz prošlog kvartala, i kloniranje praznog stiliziranog lista znači da svaki duplikat kreće čist. Ako duplicirate list koji već nosi podatke, ti podaci dolaze s njim, jer dosljedno kopira iskorišteni raspon; to je ponekad ono što želite, ali za izvještaj koji se širi obično nije.CopyFrom dosljedno kopira iskorišteni raspon; to je ponekad ono što želite, ali za izvještaj koji se širi obično nije

Brza navika provjere

Budući da je podjela između dubinskog i plitkog kopiranja nevidljiva dok je ne tražite, ubacite provjeru od pet redaka u posao umjesto da vjerujete da je sve prešlo kako treba. Nakon dupliciranja, pročitajte natrag strukturne signale koje klon treba naslijediti i potvrdite da se podudaraju s izvorom

Copy := Book.Sheets.Duplicate(1, 'Region-North');
WriteLn(Format('merged=%d  colA=%.1f  freezeRow=%d  tabAuto=%d',
  [Copy.MergedCells.Count, Copy.ColWidth[1],
   Copy.FreezeRow, Integer(Copy.TabColorIsAuto)]));
// Prove independence: mutate the copy, confirm the source is untouched.
Copy.Cells[2, 2].Value := 999;
// Template.Cells[2, 2].Value is still whatever it was.

Broj spojenih raspona, širina stupca, red zamrzavanja i zastavica boje kartice govore vam da je sloj koji se kopira doista stigao. Odvojeno, u svakom listu koji je nosio grafikon, tablicu, validacije ili uvjetna formatiranja, tretirajte ih kao popis za ponovno izgraditi na kopiji: njihovo odsustvo je namjerno, a popravak je nekoliko poziva, a ne prijava greške. Taj mentalni model, dubok ondje gdje je sigurno i plitak ondje gdje bi reference pukle, cijela je priča o tome kako dobro koristiti ovu značajku

Dupliciranje radnog lista i CopyFrom kopiranje stanja lista opisano ovdje dolaze u v2.91.0 izvorne HotXLS Delphi spreadsheet komponente, zajedno s pokretljivim SheetCopy uzorkom koji provodi ciklus kloniraj i izmijeni od početka do kraja