Trei grupuri de setări ale foii nu au nimic de-a face cu valorile din celule și totul de-a face cu felul în care se comportă fișierul odată ce iese din codul dumneavoastră. Protecția foii decide ce celule poate edita un utilizator după ce predați registrul de lucru. Configurarea paginii fixează orientarea, dimensiunea hârtiei și marginile. Setările de tipărire (rânduri de titlu repetate, scalare și întreruperi manuale de pagină) controlează cum aterizează pe hârtie o grilă de lungime arbitrară. Niciuna dintre cele trei nu se vede când priviți datele într-un vizualizator, iar toate trei se strică în tăcere pe teren atunci când sunt greșite. HotXLS, o bibliotecă nativă de foi de calcul pentru Delphi și C++Builder, expune întreaga suprafață pentru .xls și .xlsx, ceea ce înseamnă că reproduce și fiecare regulă Excel contraintuitivă coaptă în acea suprafață
Prima dintre acele reguli îi pune piedică aproape oricui, prima dată când protejează o foaie generată. Apelați Protect și deodată nimeni nu mai poate scrie în nicio celulă, inclusiv în coloanele de intrare în jurul cărora ați construit registrul. Nimic din codul dumneavoastră nu a atins acele coloane, și exact de aceea se întâmplă
Fiecare celulă se naște blocată
ECMA-376 definește locked ca parte a înregistrării de formatare a unei celule, nu ca proprietate a protecției în sine, iar valoarea implicită este true. Protecția foii este doar comutatorul care face indicatorul să poată fi impus. Așadar toată grila poartă un indicator de blocare din clipa în care există, adormit, iar apelul lui Protect le activează pe toate deodată. Remedierea este să stabiliți ordinea în mod deliberat: construiți aspectul, deblocați explicit intervalele pe care utilizatorii trebuie să le editeze și protejați la final
Book := TXLSXWorkbook.Create;
try
Sheet := Book.Sheets.Add('Timesheet');
// ... rândul de antet, coloana de nume și formulele de tarif se scriu aici ...
Sheet.Range['B2:B50'].SetLocked(False); // aici își trec angajații orele
Sheet.Range['F2:F50'].SetFormulaHidden(True); // păstrați privat calculul tarifului
Sheet.Protect('review-2026'); // acum mușcă indicatorii de blocare
Book.SaveAs('timesheet.xlsx');
finally
Book.Free;
end;
SetFormulaHidden face ceva separat și ușor de trecut cu vederea: cât timp protecția este activă, celula își arată în continuare valoarea calculată, dar bara de formule nu arată nimic. Asta contează când o formulă înglobează tarife de facturare, marje sau ponderi de punctaj pe care ați prefera să nu le dați fiecărui destinatar care dă clic pe un total. Pe fațada XLS, aceeași intenție este exprimată per interval prin IXLSRange.Locked și FormulaHidden. Foaia de acolo poartă și cincisprezece indicatori Allow* (AllowSort, AllowAutoFilter, AllowFormatCells și restul), deci o foaie protejată poate fi totuși sortată și filtrată, în loc să fie înghețată într-un exponat sigilat
Ce protejează de fapt parola de protecție
Ambele formate stochează parola de protecție a foii și a registrului ca un hash clasic de 4 cifre hexazecimale. Șaisprezece biți înseamnă că nenumărate șiruri se ciocnesc cu orice parolă dată, iar uneltele de eliminare sunt la o căutare distanță. Tratați protecția ca pe o centură de siguranță împotriva editărilor accidentale, nu ca pe un control de acces. Este unealta potrivită ca să oprească recenzenții să scrie peste coloana de formule și unealta greșită pentru orice implică cuvântul confidențial
Cu un nivel mai sus, ProtectWorkbook de pe fațada XLSX blochează structura registrului, ceea ce împiedică adăugarea, redenumirea, ștergerea sau reordonarea foilor. Setați-o ori de câte ori lista de foi este ea însăși un contract cu un analizor din aval care indexează foile după nume sau poziție. O foaie redenumită strică importul de partea cealaltă la fel de sigur ca o coloană ștearsă. Fațada XLS oglindește stratificarea prin TXLSWorkbook.Protect la nivel de registru și apeluri Protect per foaie, plus o proprietate isProtected pentru codul care trebuie să inspecteze un fișier moștenit înainte de a modifica ceva
Când cerința este confidențialitate reală, mecanismul se schimbă complet. SaveAsEncrypted produce un pachet criptat AES sub schema Standard Encryption din ECMA-376, tratată în detaliu în ghidul de ieșire XLSX protejată cu AES, iar fațada XLS clasică scrie și citește fișiere .xls criptate RC4 prin EncryptionPassword și supraîncărcarea cu parolă a lui Open. Diferența nu este academică. O foaie protejată călătorește în clar, deci orice unealtă zip îi poate citi valorile din celule, în timp ce un pachet criptat este ilizibil fără parolă. O linie de audit care spune „fișierul de salarii trebuie protejat” înseamnă aproape întotdeauna criptare, indiferent de vocabularul pe care se întâmplă să îl folosească
Configurarea paginii face parte din contractul documentului
Comportamentul la tipărire este invizibil pe ecran, motiv pentru care ajunge stricat în producție atât de des. În clipa în care un client tipărește registrul, sau îl exportă în PDF pentru un auditor, marginile, scalarea și titlurile repetate devin cerințe funcționale pe care nu le-a testat nimeni. Pe fațada XLSX, aceste setări atârnă direct de foaie:
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'; // referință simplă: fără nume de foaie aici
Sheet.PrintTitleRows := '$1:$1'; // rândul de antet se repetă pe fiecare pagină
Sheet.FitToWidth := 1;
Sheet.FitToHeight := 0; // crește în jos pe măsură ce cresc datele
Sheet.PrintGridlines := False;
Două dintre acele linii ascund capcane. Șirurile de antet și de subsol folosesc codurile de formatare din Excel: &P pentru pagina curentă, &N pentru numărul total, cu &L, &C și &R pentru a adresa explicit cele trei secțiuni. Cealaltă capcană este PrintArea, care primește intenționat o referință simplă de celule. HotXLS o stochează necalificată și prefixează numele foii când scrie fișierul, deci dacă transmiteți dumneavoastră 'Timesheet!$A$1:$F$60' produceți o referință dublu calificată și malformată. Aceeași precauție se aplică cu un strat mai jos: zonele de tipărire și titlurile de tipărire sunt păstrate ca numele definite încorporate _xlnm.Print_Area și _xlnm.Print_Titles, deci nu adăugați niciodată manual intrări _xlnm.* prin DefinedNames, altfel cele două mecanisme se vor bate pe același loc
Scalare care supraviețuiește volumelor de date din producție
Combinația FitToWidth := 1 cu FitToHeight := 0 se citește ca „încadrează întotdeauna coloanele pe lățimea unei pagini, apoi ia câte pagini în jos are nevoie datele” și este valoarea implicită corectă pentru orice raport al cărui număr de rânduri variază. Capcana este să reglați un procent fix sau o pereche de încadrare pe pagină față de un fișier de test de treizeci de rânduri: dați acelorași setări șase sute de rânduri de producție și ieșirea fie explodează în zeci de pagini tăiate, fie se micșorează sub pragul lizibilității. Scalați lățimea, lăsați lungimea să crească și repetați rândul de antet prin PrintTitleRows, ca pagina șaptesprezece să rămână lizibilă pe cont propriu
Întreruperile manuale urmează aceeași disciplină de regenerare ca orice altceva dintr-un registru generat. AddRowBreak(BeforeRow) începe o pagină nouă înaintea unei limite de secțiune, dar când generatorul rulează din nou și rândurile se deplasează, o întrerupere învechită aterizează în mijlocul tabelului. Apelați mai întâi ClearAllPageBreaks, apoi readăugați întreruperi calculate din propriile contoare de rânduri ale generatorului, în loc să peticiți poziții vechi. Pe fațada XLS, controalele echivalente stau pe Sheet.PageSetup (orientare, dimensiune de hârtie, margini, șiruri de antet și subsol, încadrare pe pagini), cu RepeatRows și RepeatColumns acoperind titlurile de tipărire
Verificarea rezultatului înaintea clientului
Defectele de protecție și de tipărire au o proprietate comună: sunt banal de verificat manual și aproape niciodată verificate. Deschideți fișierul generat în Excel și acordați-i nouăzeci de secunde. Scrieți într-o celulă de intrare și confirmați că acceptă tastarea; scrieți într-o celulă blocată și confirmați că apare solicitarea de protecție; verificați că o formulă ascunsă lasă bara de formule goală. Apoi rulați Print Preview pe un set de date de mărime de producție, nu pe un eșantion de treizeci de rânduri, și citiți numărul de pagini, rândul de titlu repetat și numerotarea din subsol. Previzualizarea este pasul care se plătește singur, pentru că geometria de tipărire depinde de setări fără nicio randare pe ecran, iar în lipsa unei imprimante fizice este singurul loc în care o greșeală de scalare devine vreodată vizibilă
O ultimă setare completează revizuirea. FreezePane(ACol, ARow) menține blocul de antet în câmpul vizual în timp ce un recenzent derulează. Acesta este comportament de ecran, nu de tipărire, dar un recenzent judecă tot livrabilul deodată. Iar un registru care își începe viața ca aspect întreținut de un designer primește mare parte din toate acestea gratis: fluxul de generare de rapoarte din șablon ține configurarea paginii în șablon, unde un om a reglat-o față de o imprimantă reală, și lasă codul să umple datele și să reaplice protecția după ce aspectul se așază
HotXLS este o bibliotecă nativă de foi de calcul în Object Pascal pentru Delphi și C++Builder; referința completă a API-ului de protecție și de configurare a paginii se află pe pagina de produs HotXLS Delphi Component