Kolme laskentataulukon asetusryhmää eivät liity mitenkään soluarvoihin, vaan kaikkeen siihen, miten tiedosto toimii poistuttuaan koodistasi. Taulukon suojaus määrittää, mitä soluja käyttäjä voi muokata, kun työkirja luovutetaan eteenpäin. Sivun asetukset määrittävät suunnan, paperikoon ja marginaalit. Tulostusasetukset (toistuvat otsikkorivit, skaalaus ja manuaaliset sivunvaihdot) ohjaavat sitä, miten mielivaltaisen pituinen ruudukko päätyy paperille. Mikään näistä kolmesta ei näy, kun tietoja silmäilee katseluohjelmassa, ja jokainen niistä rikkoutuu hiljaisesti käytössä, jos se on väärin. HotXLS, Delphin ja C++Builderin natiivi laskentataulukkokirjasto, tarjoaa täydellisen rajapinnan .xls- ja .xlsx-tiedostoille, joten se toistaa myös kaikki tähän rajapintaan sisäänrakennetut Excelin epäintuitiiviset säännöt
Ensimmäinen näistä säännöistä yllättää lähes kaikki, kun he suojaavat tuotetun taulukon ensimmäisen kerran. Kutsu Protect-metodia, ja yhtäkkiä kukaan ei voi kirjoittaa mihinkään soluun, edes niihin syötesarakkeisiin, joiden varaan työkirja rakennettiin. Koodisi ei koskenut niihin sarakkeisiin, ja juuri siksi näin tapahtuu
Jokainen solu syntyy lukittuna
ECMA-376 määrittelee locked-asetuksen osaksi solun muotoilutietuetta eikä suojauksen ominaisuudeksi, ja sen oletusarvo on true. Taulukon suojaus on vain kytkin, joka tekee lipusta toimeenpantavan. Koko ruudukossa on siis lukituslippu sen syntyhetkestä alkaen lepotilassa, ja Protect-kutsu aktivoi ne kaikki kerralla. Korjaus on määrittää järjestys tarkoituksella: rakenna asettelu, avaa nimenomaisesti lukitus niiltä alueilta, joita käyttäjien on muokattava, ja suojaa vasta lopuksi
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Timesheet');
// ... otsikkorivi, nimisarake ja kurssikaavat kirjoitetaan tähän ...
Sheet.Range['B2:B50'].SetLocked(False); // henkilöstötyypin tunnit tässä
Sheet.Range['F2:F50'].SetFormulaHidden(True); // pidä kurssilaskenta yksityisenä
Sheet.Protect('review-2026'); // nyt lukitusliput astuvat voimaan
Book.SaveAs('timesheet.xlsx');
finally
Book.Free;
end;
SetFormulaHidden tekee jotain erillistä, mikä jää helposti huomaamatta: kun suojaus on käytössä, solu näyttää edelleen lasketun arvonsa, mutta kaavarivi ei näytä mitään. Tämä on tärkeää, kun kaava sisältää laskutusveloituksia, katteita tai pisteytyspainoja, joita et halua antaa jokaiselle vastaanottajalle, joka napsauttaa yhteissummaa. XLS-rajapinnassa sama tarkoitus ilmaistaan aluekohtaisesti IXLSRange.Locked- ja FormulaHidden-asetuksilla. Siellä laskentataulukossa on myös viisitoista Allow*-lippua (AllowSort, AllowAutoFilter, AllowFormatCells ja muut), joten suojattu taulukko voidaan silti lajitella ja suodattaa sen sijaan, että se jäädytettäisiin sinetöidyksi näyttelyesineeksi
Mitä suojauksen salasana todella suojaa
Molemmat muodot tallentavat taulukon ja työkirjan suojauksen salasanan 4 heksadesimaalin merkin pituisena vanhanaikaisena tiivisteenä. Kuusitoista bittiä tarkoittaa, että lukemattomat merkkijonot törmäävät mihin tahansa tiettyyn salasanaan, ja poistotyökalut ovat yhden haun päässä. Käsittele suojausta turvavyönä vahinkomuokkauksia vastaan, ei pääsynhallintana. Se on oikea työkalu estämään tarkistajia kirjoittamasta kaavasarakkeen päälle ja väärä työkalu kaikkeen, missä esiintyy sana luottamuksellinen
Yhtä tasoa ylempänä XLSX-rajapinnan ProtectWorkbook lukitsee työkirjan rakenteen, mikä estää lisäämästä, nimeämästä uudelleen, poistamasta tai järjestämästä uudelleen laskentataulukoita. Aseta se aina, kun taulukkoluettelo on itsessään sopimus jatkojäsentäjän kanssa, joka indeksoi taulukot nimen tai sijainnin perusteella. Uudelleennimetty taulukko rikkoo toisessa päässä olevan tuonnin yhtä varmasti kuin poistettu sarake. XLS-rajapinta vastaa kerrostukseen työkirjatason TXLSWorkbook.Protect-metodilla ja taulukkokohtaisilla Protect-kutsuilla sekä isProtected-ominaisuudella koodille, jonka on tutkittava peritty tiedosto ennen kuin se muokkaa mitään
Kun vaatimuksena on todellinen luottamuksellisuus, mekanismi muuttuu kokonaan. SaveAsEncrypted tuottaa AES-salatun paketin ECMA-376 Standard Encryption -järjestelmällä, jota käsitellään perusteellisesti AES-suojattujen XLSX-tulosteiden oppaassa, ja vanha XLS-rajapinta kirjoittaa ja lukee RC4-salattuja .xls-tiedostoja EncryptionPassword-asetuksella sekä Open-metodin salasanaylikuormituksella. Ero ei ole akateeminen. Suojattu taulukko kulkee selväkielisenä, joten mikä tahansa zip-työkalu voi lukea sen soluarvot, kun taas salattua pakettia ei voi lukea ilman salasanaa. Auditointirivi, jossa sanotaan "palkkatiedosto on suojattava", tarkoittaa lähes aina salausta riippumatta siitä, mitä sanastoa siinä satutaan käyttämään
Sivun asetukset ovat osa asiakirjasopimusta
Tulostuskäyttäytyminen on näytöllä näkymätöntä, minkä vuoksi se toimitetaan niin usein rikkinäisenä. Heti kun asiakas tulostaa työkirjan tai vie sen PDF-muotoon tarkastajaa varten, marginaaleista, skaalauksesta ja toistuvista otsikoista tulee toiminnallisia vaatimuksia, joita kukaan ei testannut. XLSX-rajapinnassa nämä asetukset ovat suoraan laskentataulukossa:
Sheet.PageLandscape := True;
Sheet.PaperSize := xlsxPaperA4;
Sheet.SetPageMargins(0.5, 0.5, 0.75, 0.75, 0.3, 0.3);
Sheet.CenterHeader := 'Monthly Timesheet';
Sheet.RightFooter := 'Page &P of &N';
Sheet.PrintArea := '$A$1:$F$60'; // paljas viittaus: ei arkin nimeä tässä
Sheet.PrintTitleRows := '$1:$1'; // otsikkorivi toistuu jokaisella sivulla
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // kasva alaspäin datan kasvaessa
Sheet.PrintGridlines := False;
Kaksi näistä riveistä kätkee ansan. Ylätunniste- ja alatunnistemerkkijonot käyttävät Excelin muotoilukoodeja: &P nykyiselle sivulle, &N kokonaissivumäärälle sekä &L, &C ja &R kolmen osion nimenomaiseen osoittamiseen. Toinen ansa on PrintArea, joka ottaa tarkoituksella pelkän solureferenssin. HotXLS tallentaa sen ilman tarkennetta ja lisää taulukon nimen tiedostoa kirjoittaessaan, joten jos annat itse arvon 'Timesheet!$A$1:$F$60', tuloksena on kahdesti tarkennettu, virheellinen viittaus. Sama varovaisuus pätee yhtä tasoa alempana: tulostusalueet ja tulostusotsikot säilytetään sisäänrakennettuina määriteltyinä niminä _xlnm.Print_Area ja _xlnm.Print_Titles, joten älä koskaan lisää _xlnm.*-merkintöjä käsin DefinedNames-kokoelman kautta, tai kaksi mekanismia kilpailee samasta paikasta
Skaalaus, joka kestää tuotantodatan määrät
Yhdistelmä FitToWidth := 1 ja FitToHeight := 0 tarkoittaa "sovita sarakkeet aina yhdelle sivulle ja käytä sitten niin monta sivua pystysuunnassa kuin data tarvitsee", ja se on oikea oletus kaikille raporteille, joiden rivimäärä vaihtelee. Ansana on säätää kiinteä prosenttiosuus tai sovita-sivulle-pari 30 rivin testitiedostolla: anna samoille asetuksille 600 tuotantoriviä, ja tuloste joko leviää kymmeniksi rajatuiksi sivuiksi tai kutistuu lukukelvottomaksi. Skaalaa leveys, anna pituuden kasvaa ja toista otsikkorivi PrintTitleRows-asetuksella, jotta sivu 17 on edelleen luettavissa itsenäisesti
Manuaaliset vaihdot noudattavat samaa uudelleentuottamisen kurinalaisuutta kuin kaikki muukin tuotetussa työkirjassa. AddRowBreak(BeforeRow) aloittaa uuden sivun ennen osion rajaa, mutta kun generaattori suoritetaan uudelleen ja rivit siirtyvät, vanhentunut vaihto päätyy keskelle taulukkoa. Kutsu ensin ClearAllPageBreaks ja lisää sitten uudelleen generaattorin omista rivinlaskureista lasketut vaihdot sen sijaan, että paikkaisit vanhoja sijainteja. XLS-rajapinnassa vastaavat säätimet ovat Sheet.PageSetup-objektissa (suunta, paperikoko, marginaalit, ylä- ja alatunnistemerkkijonot, sovitus sivuille), ja RepeatRows sekä RepeatColumns kattavat tulostusotsikot
Tuloksen tarkistaminen ennen asiakasta
Suojaus- ja tulostusvirheillä on yhteinen ominaisuus: ne on helppo tarkistaa käsin, mutta niitä ei juuri koskaan tarkisteta. Avaa tuotettu tiedosto Excelissä ja käytä siihen 90 sekuntia. Kirjoita syötesoluun ja varmista, että se hyväksyy näppäinpainalluksen; kirjoita lukittuun soluun ja varmista, että suojauskehote ilmestyy; tarkista, että piilotettu kaava jättää kaavarivin tyhjäksi. Aja sitten tulostuksen esikatselu tuotantokokoisella tietojoukolla, ei 30 rivin näytteellä, ja tarkista sivumäärä, toistuva otsikkorivi ja alatunnisteen numerointi. Esikatselu on vaihe, joka maksaa itsensä takaisin, koska tulostusgeometria riippuu asetuksista, joilla ei ole näytöllä renderöintiä, ja ilman fyysistä tulostinta se on ainoa paikka, jossa skaalausvirhe koskaan tulee näkyväksi
Yksi viimeinen asetus täydentää tarkistuksen. FreezePane(ACol, ARow) pitää otsikkolohkon näkyvissä, kun tarkistaja vierittää. Tämä on näytön käyttäytymistä eikä tulostuskäyttäytymistä, mutta tarkistaja arvioi koko toimituksen kerralla. Ja työkirja, joka aloittaa elämänsä suunnittelijan ylläpitämänä asetteluna, saa suurimman osan tästä valmiina: malliraporttien tuotantotyönkulku säilyttää sivun asetukset mallissa, jossa ihminen on säätänyt ne oikeaa tulostinta vasten, ja jättää koodin täyttämään tiedot sekä ottamaan suojauksen uudelleen käyttöön, kun asettelu vakiintuu
HotXLS on Delphin ja C++Builderin natiivi Object Pascal -laskentataulukkokirjasto; täydellinen suojaus- ja sivuasetus-API:n viite on HotXLS Delphi Component -tuotesivulla