Bitmiş bir çalışma kitabını bir iş arkadaşınıza veriyor ve ondan bunu yeniden yazmasını değil filtrelemesini istiyorsunuz. Bu yüzden sayfayı korumaya alıyorsunuz. Eski HotXLS derlemelerinde bu hareket dosyaya her seferinde tek bir şey yazıyordu: <sheetProtection sheet="1" objects="1" scenarios="1"/>. Sayfa kilitleniyor, parola özeti ekleniyor ve kullanıcı hiçbir şey yapamıyordu; hatta sizin açık bırakmak istediğiniz sıralama ve filtrelemeyi bile. Excel'in kendi "Sayfayı Koru" iletişim kutusunda tam da bu nedenle on beş onay kutusu vardır ve motor bunların hiçbirini ifade edemiyordu. v2.91.0 koruma modelinin kapattığı boşluk budur
HotXLS, Excel kurulu olmadan XLS ve XLSX okuyup yazan, Delphi ve C++Builder için yerel bir VCL spreadsheet component'tir. Bu makale, çalışma sayfası korumasının XLSX tarafını ele alır: yeni TXLSXSheetProtectionOption enum'u, her izni açıp kapatan AllowOption özelliği ve <sheetProtection> öğesini elle yazan herkesi yanıltan tek OOXML kodlama kuralı
Çalışma sayfası koruması gerçekte neyi korur
Önce sınırdan başlayalım, çünkü buna ne kadar güvenmeniz gerektiğini o belirler. OOXML spreadsheet biçiminde (ECMA-376) çalışma sayfası koruması şifreleme değil, etkileşim ilkesidir. Sayfa koruma altındayken uyumlu bir uygulamaya hangi düzenlemeleri reddedeceğini söyler. Hücre değerleri hâlâ xl/worksheets/sheetN.xml içinde düz metin olarak durur; .xlsx dosyasını zip'ten çıkarırsanız hepsi oradadır. İsteğe bağlı parola, herhangi bir şeyi karıştıran bir anahtar olarak değil, kısa bir eski tip özet olarak saklanır. Dosyanın adını değiştirip parçayı açan ve <sheetProtection> satırını kaldıran herkes her şeyi okur ve düzenler
Dolayısıyla koruma, "iş arkadaşım yanlışlıkla bir formülü bozmasın" sorusuna cevap verir; "bu veriyi niyetli bir kişiden gizli tut" sorusuna değil. Bunlar farklı araçlar gerektiren iki ayrı problemdir. Gizlilik gerekiyorsa, AES korumalı XLSX çıktı bölümünde ele alınan çalışma kitabı düzeyindeki şifrelemeyi istersiniz; gerçekten paketi şifreleyen odur. Sayfa koruması ile çalışma kitabı şifrelemesi birlikte sorunsuz çalışır, ancak gerçek kilit yalnızca ikincisidir. Bu çizgiyi net tutarsanız, sayfanın geri kalanı sadece tesisat işidir
On beş seçenek ve AllowOption özelliği
Artık her çalışma sayfası, sayfa koruma altındayken kullanıcının yine de neler yapabileceğini açıklayan bir TXLSXSheetProtectionOption değerleri kümesi taşır. Üyeler OOXML özniteliklerine ve Excel iletişim kutusundaki onay kutularına bire bir karşılık gelir:
xlsxSpoEditObjects,xlsxSpoEditScenarios— çizim nesnelerini ve what-if senaryolarını düzenlemexlsxSpoFormatCells,xlsxSpoFormatColumns,xlsxSpoFormatRows— hücreleri, sütunları ve satırları yeniden biçimlendirmexlsxSpoInsertColumns,xlsxSpoInsertRows,xlsxSpoInsertHyperlinks— sütun, satır ve bağlantı eklemexlsxSpoDeleteColumns,xlsxSpoDeleteRows— sütun ve satır silmexlsxSpoSelectLockedCells,xlsxSpoSelectUnlockedCells— seçimi kilitli veya kilitsiz hücrelere taşımaxlsxSpoSort,xlsxSpoAutoFilter,xlsxSpoPivotTables— aralıkları sıralama, AutoFilter açılır menülerini kullanma ve PivotTable'larla çalışma
Tek tek bitleri AllowOption üzerinde bulunan dizinli TXLSXWorksheet özelliği üzerinden okuyup yazarsınız. AllowOption[Opt] = True, eylemin izinli olduğu anlamına gelir; bunu False olarak ayarlamak eylemi yasaklar. Kümenin tamamına aynı anda SheetProtectionOptions üzerinden de erişilebilir; bu, bir TXLSXSheetProtectionOptions'tür (düz bir Pascal set of), böylece bunu saklayabilir, geri yükleyebilir veya topluca değiştirebilirsiniz
Varsayılan önemlidir ve bilinçli olarak seçilmiştir: yeni oluşturulan bir çalışma sayfası, tüm seçeneklere izin verilmiş şekilde başlar. Kurucu, SheetProtectionOptions alanını tam aralıkla, yani [Low(TXLSXSheetProtectionOption)..High(TXLSXSheetProtectionOption)] ile doldurur. Sıfırdan bir izin kümesi kurmak yerine, yasaklamak istediğiniz eylemleri çıkararak daraltırsınız. Bu tercih, aşağıdaki yazıcı kodlama kuralının Excel davranışıyla hizalanmasını sağlar
Sayfayı koruyup sıralama ile filtrelemeyi açık bırakmak
Yaygın durumun uçtan uca hali şöyledir: bitmiş bir raporu, düzeni yeniden şekillendirilemesin diye koruyun ama okuyucunun sıralamasına ve filtrelemesine izin verin. Burada Protect ile seçeneklerin bağımsız olduğuna dikkat edin. Protect, sayfayı korumalı duruma geçirir ve isteğe bağlı parola özetini saklar; seçenek kümesine dokunmaz. AllowOption öğesini ayrı olarak ayarlarsınız ve sayfa korunduktan ve kaydedildikten sonra anahtarlar etkisini gösterir
var
wb: TXLSXWorkbook;
sh: TXLSXWorksheet;
begin
wb := TXLSXWorkbook.Create;
try
sh := wb.Sheets.Add('Protected');
sh.Cells[1, 1].Value := 'Region'; sh.Cells[1, 2].Value := 'Units';
sh.Cells[2, 1].Value := 'North'; sh.Cells[2, 2].Value := 120;
sh.Cells[3, 1].Value := 'South'; sh.Cells[3, 2].Value := 98;
// Protect with a password. This only sets the protected state + hash;
// the option set is left at its all-permitted default.
sh.Protect('HotXLS-2026');
// Narrow: keep sort + AutoFilter, forbid reshaping and reformatting.
sh.AllowOption[xlsxSpoSort] := True;
sh.AllowOption[xlsxSpoAutoFilter] := True;
sh.AllowOption[xlsxSpoFormatCells] := False;
sh.AllowOption[xlsxSpoFormatColumns] := False;
sh.AllowOption[xlsxSpoFormatRows] := False;
sh.AllowOption[xlsxSpoInsertRows] := False;
sh.AllowOption[xlsxSpoDeleteRows] := False;
if wb.SaveAs('protection.xlsx') <> 1 then
Writeln('SaveAs failed');
finally
wb.Free;
end;
end;
Bu parçacıkta okunması gereken iki nokta var. Sort ve AutoFilter satırları, her ikisinin varsayılanı da True olmasına rağmen açıkça yazılmıştır; bu işlevsel bir gereksinim değil, bir sonraki bakımcı için belgelendirmedir. Ve varsayılanlar izin verici olduğu için, çıktı dosyasını gerçekten değiştiren tek satırlar bir seçeneği False olarak ayarlayan satırlardır. Bu, API'nin rastlantısal bir sonucu değildir; OOXML kablo biçiminin yüzeye çıkmış hâlidir ve sıradaki bölüm tam olarak budur
Kodlama kuralı: omit izin verir, attr=0 yasaklar
Tüm özelliğin içindeki sezgiye ters düşen tek gerçek budur ve elle yazılmış <sheetProtection> çoğunlukla burada yanlış gider. OOXML'de eylem başına her öznitelik bir yasaklama bayrağıdır ve yokluğu izin anlamına gelir. Eksik bir öznitelik, eyleme izin verildiği anlamına gelir. "0" olarak yazılmış bir öznitelik ise, sayfa korunurken o eylemin yasak olduğu anlamına gelir. Biçimlendirmenin izinli olduğunu anlatmak için düzgün oluşturulmuş bir dosyada formatCells="1" diye bir şey yoktur; özniteliği basitçe dışarıda bırakırsınız. (Eksik özniteliğin varsayılanı OOXML boolean varsayılanı olan true'dur ve bu öznitelikler, "true" karşılık gelen düzenlemenin izinli olduğunu gösterecek şekilde adlandırılmıştır)
HotXLS yazıcısı bunu bire bir yansıtır. Korumayı açmak için sheet="1" yazar, ardından seçenek kümesini dolaşır ve yalnızca attr="0" olarak ayarladığınız seçenekler için False yazar. İzinli eylemler çıktıya hiçbir şey eklemez. Dolayısıyla önceki bölümdeki çalışma kitabı, parola özetiyle birlikte yalnızca yasaklanan eylemleri taşıyan şu tür bir şeye serileştirilir:
// Conceptual output for the snippet above (attributes elided for brevity):
// <sheetProtection sheet="1"
// formatCells="0" formatColumns="0" formatRows="0"
// insertRows="0" deleteRows="0"
// password="...4-hex..."/>
// Note what is NOT there: no sort, no autoFilter, no selectLockedCells.
// Their absence is exactly what tells Excel those actions stay allowed.
Eski sabit kodlanmış dizgeden geldiyseniz ve her özniteliğin açıkça yazıldığını görmeyi bekliyorsanız, bu seyrek, hatta neredeyse yanlış görünür. Oysa doğrudur. sort="1" ve autoFilter="1" öğelerini listeleyen bir dosya, uyumlu bir okuyucu için aynı anlama gelirdi; ama Excel'in kendisi de en küçük, yalnızca yasakları içeren biçimi yazar ve onunla eşleşmek farkları küçük, round-trip işlemlerini de sıkıcı derecede güvenilir tutar. objects ve scenarios öznitelikleri aynı kuralı izler: varsayılan olarak izinli oldukları için, bunlar yalnızca siz yasakladığınızda "0" olarak görünür; bu da eskiden koşulsuz yazılan objects="1" scenarios="1" davranışının tam tersidir
Korumayı geri okuma: round-trip doğruluğu
Yazabildiğiniz ama okuyamadığınız bir izin modeli tek yönlü kapıdır ve bunun alışılmış belirtisi, yükle-düzenle-kaydet döngüsünün sessizce izinleri genişletmesidir. HotXLS bunu kapatır. ParseWorksheetXml bir <sheetProtection> öğesiyle karşılaştığında, sayfayı korumalı olarak işaretler, varsa parola özetini alır ve ardından her eylem başına özniteliği ters yönde aynı kuralla tekrar AllowOption içine çözer: mevcut ve "0" değerine eşit bir öznitelik eylemi yasaklar; eksik öznitelik ise seçeneği izinli varsayılanında bırakır
var
wb: TXLSXWorkbook;
sh: TXLSXWorksheet;
begin
wb := TXLSXWorkbook.Create;
try
wb.LoadFromFile('protection.xlsx');
sh := wb.Sheets[1]; // XLSX sheets are 1-based
if sh.IsProtected then
begin
Writeln('Protected; password hash present: ',
sh.SheetProtectHash <> '');
Writeln('Sort allowed: ', sh.AllowOption[xlsxSpoSort]);
Writeln('AutoFilter allowed: ', sh.AllowOption[xlsxSpoAutoFilter]);
Writeln('FormatCells allowed:', sh.AllowOption[xlsxSpoFormatCells]);
end;
finally
wb.Free;
end;
end;
Yazıcının ürettiği dosyayı yüklerseniz, Sort ile AutoFilter değerlerini yeniden True olarak, FormatCells değerini ise False olarak alırsınız — kaydettiğiniz küme bozulmadan geri gelir. Asıl amaç bu simetridir: korumalı ama kısmen izinli bir sayfada tek bir hücreyi düzenleyip yeniden kaydedin, dokunmadığınız on dört izin eski hepsi-ya-da-hiçbiri varsayılanına çökmez, yaşamaya devam eder
Pratik notlar ve sınırlar
Bunu bir rapor hattına bağlamadan önce bilinmesi faydalı birkaç şey:
- Parola tasarım gereği zayıftır XLSX çalışma sayfası koruması, birlikte çalışabilirlik için burada korunan 16 bitlik eski bir özet saklar (Excel'in onlarca yıldır kullandığı özetin aynısı). Yanlışlıkla yapılan düzenlemeleri caydırır; saldırgana direnmez. Bunu bir sır saklama mekanizması gibi görmeyin. Gerçek koruma için çalışma kitabını şifreleyin
- Koruma etkinleştirilmeden önce seçenekleri ayarlamak sorun değildir
AllowOption, sayfa şu anda korumalı olsun ya da olmasın atanabilir; bu anahtarlar yalnızcaProtectetkin olduğunda korumanın neye izin vereceğini tanımlar.UnProtect, korumalı durumu ve özeti temizler ama seçenek kümenizi bir sonraki kullanım için yerinde bırakır - Kilitli hücre semantiği hâlâ geçerlidir Koruma, yalnızca
Lockedniteliği ayarlanmış hücrelerdeki düzenlemeleri engeller (çalışma kitabı varsayılanı budur). Bir giriş bölgesini düzenlenebilir bırakmak koruma seçeneğinin değil, hücre stilinin işidir; iki katman Excel'dekiyle aynı şekilde birleşir - Bu, XLSX motorudur Seçenek modeli, XLS motorunun daha eski
Allow*özelliklerini yansıtır; ancak buradaki enum ve özellik adları (xlsxSpo*,AllowOption)TXLSXWorksheetbirimine velxHandleXiçeriğine aittir. Aynı sayfalarda yazdırma düzenini de yönetiyorsanız, koruma ve sayfa ayarı anlatımı bu ayarların yazdırma alanları ve üstbilgilerle nasıl yan yana durduğunu açıklar; veri doğrulama, AutoFilter ve tablolar ise kilitli bir rapordaxlsxSpoAutoFilteröğesini açık bırakmakla doğal biçimde eşleşir
İnce taneli koruma modeli ve XLSX okuma/yazma motorunun geri kalanı, Delphi ve C++Builder için HotXLS Component içinde sunulur; ürün sayfası, tam koruma seçeneği başvurusu da dahil olmak üzere eksiksiz çalışma sayfası API'sini içerir