Tre grupper av kalkylbladsinställningar har ingenting att göra med cellvärdena och allt att göra med hur filen beter sig när den lämnar din kod. Bladskydd avgör vilka celler en användare kan redigera efter att du har lämnat över arbetsboken. Sidinställningar fastställer orientering, pappersstorlek och marginaler. Utskriftsinställningarna (upprepade rubrikrader, skalning och manuella sidbrytningar) styr hur ett rutnät av godtycklig längd landar på papper. Ingen av de tre syns när du ögnar igenom datan i en visare, och alla tre går sönder tyst ute i fält när de är fel. HotXLS, ett nativt kalkylbibliotek för Delphi och C++Builder, exponerar hela ytan för .xls och .xlsx, vilket innebär att det också återger varje kontraintuitiv Excel-regel inbakad i den ytan
Den första av dessa regler snubblar nästan alla på första gången de skyddar ett genererat blad. Anropa Protect och plötsligt kan ingen skriva i någon cell alls, inklusive de indatakolumner som du byggde arbetsboken kring. Inget i din kod rörde de kolumnerna, och det är precis därför det händer
Varje cell föds låst
ECMA-376 definierar locked som en del av en cells formateringspost, inte som en egenskap hos skyddet i sig, och den är som standard sann. Bladskydd är bara omkopplaren som gör flaggan verkställbar. Så hela rutnätet bär en låsflagga från det ögonblick det finns, vilande, och anropet till Protect aktiverar dem alla på en gång. Lösningen är att sätta ordningen medvetet: bygg layouten, lås upp explicit de områden användarna måste redigera, och skydda sist
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Timesheet');
// ... rubrikrad, namnkolumn och avgiftsformler skrivs här ...
Sheet.Range['B2:B50'].SetLocked(False); // personal skriver timmar här
Sheet.Range['F2:F50'].SetFormulaHidden(True); // håll avgiftsberäkningen privat
Sheet.Protect('review-2026'); // nu biter låsflaggorna
Book.SaveAs('timesheet.xlsx');
finally
Book.Free;
end;
SetFormulaHidden gör något separat och lätt att missa: medan skyddet är aktivt visar cellen fortfarande sitt beräknade värde, men formelfältet visar ingenting. Det spelar roll när en formel bäddar in faktureringsräntor, marginaler eller poängviktningar som du hellre inte vill lämna ut till varje mottagare som klickar på en summa. På XLS-fasaden uttrycks samma avsikt per område via IXLSRange.Locked och FormulaHidden. Kalkylbladet där bär också femton Allow*-flaggor (AllowSort, AllowAutoFilter, AllowFormatCells, och resten), så att ett skyddat blad ändå kan sorteras och filtreras i stället för att frysas till ett förseglat utställningsobjekt
Vad skyddslösenordet faktiskt skyddar
Båda formaten lagrar blad- och arbetsboksskyddslösenordet som en äldre hash på 4 hexsiffror. Sexton bitar innebär att otaliga strängar kolliderar med vilket givet lösenord som helst, och borttagningsverktyg är en sökning bort. Behandla skydd som ett säkerhetsbälte mot oavsiktliga redigeringar, inte som åtkomstkontroll. Det är rätt verktyg för att hindra granskare från att skriva över formelkolumnen och fel verktyg för allt som involverar ordet konfidentiellt
Ett steg upp låser ProtectWorkbook på XLSX-fasaden arbetsbokens struktur, vilket förhindrar att lägga till, byta namn på, ta bort eller ändra ordning på blad. Sätt den när bladlistan i sig är ett kontrakt med en nedströmsparser som indexerar blad efter namn eller position. Ett omdöpt blad förstör importen på andra sidan precis lika säkert som en borttagen kolumn gör. XLS-fasaden speglar lagerindelningen med TXLSWorkbook.Protect på arbetsboksnivå och per-blad-anrop av Protect, plus en egenskap isProtected för kod som behöver inspektera en ärvd fil innan den ändrar något
När kravet är verklig konfidentialitet ändras mekanismen helt. SaveAsEncrypted producerar ett AES-krypterat paket enligt ECMA-376:s Standard Encryption-schema, som behandlas ingående i guiden om AES-skyddad XLSX-utdata, och den äldre XLS-fasaden skriver och läser RC4-krypterade .xls-filer via EncryptionPassword och lösenordsöverlagringen av Open. Skillnaden är inte akademisk. Ett skyddat blad färdas i klartext, så vilket zip-verktyg som helst kan läsa dess cellvärden, medan ett krypterat paket är oläsbart utan lösenordet. En revisionsrad som säger "lönefilen måste skyddas" betyder nästan alltid kryptering, oavsett vilket ordval den råkar använda
Sidinställningar är en del av dokumentkontraktet
Utskriftsbeteende är osynligt på skärmen, vilket är varför det så ofta levereras trasigt. I samma stund en kund skriver ut arbetsboken, eller exporterar den till PDF åt en revisor, förvandlas marginaler, skalning och upprepade rubriker till funktionella krav som ingen testade. På XLSX-fasaden hänger dessa inställningar direkt på kalkylbladet:
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'; // ren referens: inget bladnamn här
Sheet.PrintTitleRows := '$1:$1'; // rubrikraden upprepas på varje sida
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // växer nedåt allteftersom datan växer
Sheet.PrintGridlines := False;
Två av de raderna döljer fällor. Rubrik- och sidfotssträngarna använder Excels formateringskoder: &P för aktuell sida, &N för totalantalet, med &L, &C och &R för att adressera de tre sektionerna explicit. Den andra fällan är PrintArea, som avsiktligt tar en ren cellreferens. HotXLS lagrar den okvalificerad och lägger till bladnamnet som prefix när den skriver filen, så om du själv skickar in 'Timesheet!$A$1:$F$60' uppstår en dubbelt kvalificerad, felformad referens. Samma försiktighet gäller ett lager djupare: utskriftsområden och utskriftsrubriker sparas som de inbyggda definierade namnen _xlnm.Print_Area och _xlnm.Print_Titles, så lägg aldrig till _xlnm.*-poster via DefinedNames för hand, annars kommer de två mekanismerna att slåss om samma plats
Skalning som överlever produktionens datavolymer
Kombinationen FitToWidth := 1 med FitToHeight := 0 läses som "passa alltid kolumnerna över en sida, ta sedan så många sidor nedåt som datan behöver," och det är standardvalet för alla rapporter vars radantal varierar. Fällan är att finjustera en fast procentsats eller ett fit-to-page-par mot en testfil med trettio rader: mata samma inställningar med sexhundra produktionsrader och utdatan exploderar antingen i dussintals beskurna sidor eller krymper under läsbarhetsgränsen. Skala bredden, låt längden växa, och upprepa rubrikraden via PrintTitleRows så att sidan sjutton fortfarande är läsbar på egen hand
Manuella brytningar följer samma regenereringsdisciplin som allt annat i en genererad arbetsbok. AddRowBreak(BeforeRow) startar en ny sida före en sektionsgräns, men när generatorn körs igen och raderna förskjuts hamnar en föråldrad brytning mitt i tabellen. Anropa ClearAllPageBreaks först, lägg sedan till brytningar beräknade från generatorns egna radräknare i stället för att lappa gamla positioner. På XLS-fasaden bor de motsvarande kontrollerna på Sheet.PageSetup (orientering, pappersstorlek, marginaler, rubrik- och sidfotssträngar, fit-to-pages), med RepeatRows och RepeatColumns som täcker utskriftsrubrikerna
Kontrollera resultatet innan en kund gör det
Skydds- och utskriftsbuggar delar en egenskap: de är triviala att verifiera för hand och verifieras nästan aldrig. Öppna den genererade filen i Excel och lägg nittio sekunder på den. Skriv i en indatacell och bekräfta att den accepterar knapptryckningen; skriv i en låst cell och bekräfta att skyddsprompten visas; kontrollera att en dold formel lämnar formelfältet tomt. Kör sedan Förhandsgranskning mot en produktionsstor datamängd, inte ett trettioradsurval, och läs av sidantalet, den upprepande rubrikraden och sidfotens numrering. Förhandsgranskningen är steget som betalar sig självt, eftersom utskriftsgeometrin beror på inställningar utan skärmrendering, och förutom en fysisk skrivare är det den enda platsen där ett skalningsfel någonsin blir synligt
En sista inställning avrundar granskningen. FreezePane(ACol, ARow) håller rubrikblocket synligt medan en granskare rullar. Det är skärmbeteende snarare än utskriftsbeteende, men en granskare bedömer hela leveransen på en gång. Och en arbetsbok som börjar sitt liv som en designerunderhållen layout får det mesta av detta gratis: arbetsflödet för mallbaserad rapportgenerering håller sidinställningarna i mallen, där en människa har finjusterat dem mot en verklig skrivare, och lämnar åt koden att fylla i datan och återapplicera skyddet när layouten har satt sig
HotXLS är ett nativt Object Pascal-kalkylbibliotek för Delphi och C++Builder; den fullständiga API-referensen för skydd och sidinställningar finns på produktsidan för HotXLS Delphi Component