Teknik Makale

HotXLS ile Delphi'de Excel Belge Özelliklerini Ayarlama

Bir elektronik tablo iki katman kimlik taşır. Bir yanda hücre ızgarası vardır, öbür yanda onunla birlikte yol alan belge meta verisi: başlık, yazar, şirket, anahtar kelimeler, zaman damgaları. Excel bu ikinci katmanı ızgarada hiç göstermez; oysa Windows Search'ün dizinlediği, SharePoint'in bir belgeyi adlandırmak için okuduğu ve bir kayıt yönetimi sisteminin dosyaladığı katman odur. Üretilen bir çalışma kitabı Author ve Title alanlarını kurulduğu şablondan devraldığında, aşağı akıştaki her sistem dört bin müşteri ekstresinin yazarı olarak şablon tasarımcısını kaydeder. Meta veri hiçbir yerde doğru değildir ve her yerde kullanılır

HotXLS bu katmanı her iki motorunda da sıradan çalışma kitabı düzeyi özellikleri olarak sunar: .xls için BIFF cephesi ve .xlsx için OOXML cephesi. Bir dosyayı açtıktan sonra bir alanı okur, kaydetmeden önce bir alanı yazarsınız. Değerin hangi fiziksel kapsayıcıya ineceğine kütüphane karar verir. Bir üretici yazmadan önce anlaşılmaya değer olan şey, her biçimin hangi alanları gerçekten desteklediği, o alanların fiziksel olarak nerede yaşadığı ve bir .xlsx dosyasının hiç meta veri kaydedip etmeyeceğini yöneten tek kapı kuralıdır

İki biçim, iki depolama modeli

Bir elektronik tablo kütüphanesinin iki ayrı meta veri gerçeklemesine ihtiyaç duymasının ve yarım kalmış araçların bir biçimi doğru damgalayıp diğerini unutmasının nedeni, .xls ile .xlsx dosyalarının özelliklerini birbiriyle ilgisiz yerlerde tutmasıdır. Bir BIFF çalışma kitabı bunları OLE bileşik dosya akışlarına, başta Excel'in kendisinden daha eski olan SummaryInformation özellik kümesine yazar; yanında da dosyayı en son kimin kaydettiğini adlandıran akış içi WRITEACCESS kaydı bulunur. Bir OOXML çalışma kitabı ise bunları zip paketi içinde XML parçaları olarak, amaca göre bölünmüş biçimde tutar: docProps/core.xml Dublin Core alanlarını (başlık, oluşturan, konu, anahtar kelimeler, tarihler) barındırır, docProps/app.xml ise ECMA-376 Part 1 uyarınca şirket ve üreten uygulama gibi uygulama düzeyindeki alanları barındırır

HotXLS bu iki depolama modelini de çalışma kitabı nesnesinin doğrudan özelliklerine düzleştirir. Hiçbir zaman bir özellik kümesi akışını açmaz ya da bir XML parçasını elle düzenlemezsiniz. Çalışma kitabına dizgeler ve tarihler atarsınız, hangi biçimi kaydediyorsanız doğru kapsayıcı ona göre oluşur

Excel belge özellikleri için BIFF SummaryInformation depolamasını OOXML docProps parçalarıyla karşılaştıran HotXLS Delphi şeması
HotXLS birbiriyle ilgisiz iki depolama modelini tek bir çalışma kitabı özellik yüzeyine düzleştirir — fiziksel kapsayıcıyı dosya kaydedilirken motor seçer

Üretilen çalışma kitaplarını iş kaydından damgalamak

XLSX tarafında TXLSXWorkbook; Title, Subject, Author, Keywords, Description, Category, LastModifiedBy, Company, Application ve AppVersion alanlarını dizge olarak, ayrıca sıfırın atanmamış anlamına geldiği Created ve Modified alanlarını TDateTime değeri olarak sunar. Devralma açığını kapatan kural tek cümledir: her çalıştırmada her alanı atayın ve değerleri, şablonun rastgele taşıdığı şeye güvenmek yerine iş kaydından alın

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open('statement-template.xlsx') <> 1 then
      raise Exception.Create('Template not available');

    // Her alanın üzerine yazın: dokunulmadan kalan her şey
    // şablonu tasarlayan kişiden devralınır.
    Book.Title := 'Account Statement 2026-06 / ACME Corp';
    Book.Subject := 'Monthly account statement';
    Book.Author := 'Billing Service 4.2';
    Book.LastModifiedBy := 'Billing Service 4.2';
    Book.Company := 'Northwind Financial';
    Book.Category := 'Customer Delivery';
    Book.Keywords := 'statement;billing;2026-06;acct-10024';
    Book.Description := 'Generated document - manual edits are not retained';
    Book.Created := Now;
    Book.Modified := Now;

    Book.SaveAs('statement-10024.xlsx');
  finally
    Book.Free;
  end;
end;

Keywords alanı genelde gördüğünden daha fazla düşünmeye değer. Arama altyapısı onu harfi harfine dizinler, Windows Search, SharePoint ve çoğu DMS ürünü aynı şekilde; dolayısıyla hesap numarasını ve dönemi taşıyan noktalı virgülle ayrılmış bir gelenek, teslim edilen her çalışma kitabını hiçbir veritabanı gidiş dönüşü olmadan bulunabilir bir kayda çevirir. Aynı erişim mesafesi işin püf noktasıdır da. Özellikler dosyanın her kopyasıyla birlikte, onları yazan sistemin erişim denetimlerinin çok ötesine seyahat eder; bu yüzden kişisel veri oraya ait değildir

Zaman damgası çifti, alışkanlığa bırakmak yerine politikada sabitlemeye değer bir anlam taşır. Created, hattınızın belgeyi ürettiği anı işaretlemeli ve sonra donmuş kalmalıdır. Modified ise bir alıcı dosyayı her kaydettiğinde Excel'in güncellediği alandır; dolayısıyla teslimden sonra ikisi arasındaki ayrışma, birinin çalışma kitabını aşağı akışta düzenlediğinin olumlu kanıtıdır ve bu, iletilen bir elektronik tablonun gerçekte kimin sayılarını taşıdığına dair birden çok anlaşmazlığı çözer. Bir tuzak atanmamış durumda saklıdır: bu durum bir istisna ya da null değil, düpedüz sıfır değeridir; bu yüzden denetim kodunun açıkça sıfır sınaması yapması gerekir. Atanmamış bir TDateTime değerini bu koruma olmadan biçimlendirin, günlükleriniz kendinden emin biçimde yanlış bir 1899 Aralık tarihiyle dolar

DocPropsTouched: docProps olmadan gönderilen çalışma kitabı

Salt okunur bir bayrak olan DocPropsTouched, XLSX özellik yazıcısına kapı tutar. Hiçbir özelliğin atanmadığı bir çalışma kitabı hiçbir docProps parçası üretmez; HotXLS boş bir meta veri iskeleti yazmayı reddeder. Davranış derli topludur ve tasarımda hesaba katmaya değer iki sonucu vardır

Tüketen taraftaki giriş kodu, her pakette core.xml bulunduğunu varsaymamalıdır. Onu katı biçimde şart koşan bir araç, kusursuz geçerli en küçük dosyaları reddeder. Uyum duruşunuz her giden belgenin en azından bir üretici kimliği taşımasını gerektiriyorsa, bu gereklilik biçimin bir özelliği değil kodun sorumluluğu olur: kaydetme yolunda Application ve Author alanlarını koşulsuz atayın; çünkü dokunulmamış bir çalışma kitabı belirtim açısından tümüyle yasaldır ve bu arada politikanızı sessizce çiğner

Kaydedilen XLSX çalışma kitaplarında docProps çıktısına kapı tutan DocPropsTouched bayrağını gösteren HotXLS Delphi akış şeması
DocPropsTouched, XLSX docProps yazıcısına kapı tutar — politika üretici kimliği gerektirdiğinde Application ve Author alanlarını koşulsuz atayın

Eski XLS yüzeyi ve Comments tuzağı

BIFF cephesi daha eski ve daha küçük alan kümesini taşır: Title, Subject, Author, Keywords, Comments, Company ve Manager; ayrıca UserName alanının takma adı olan ve başka bir kullanıcı dosyayı kilitlediğinde Excel'in gösterdiği WRITEACCESS kaydını yazan LastSavedBy

var
  Legacy: IXLSWorkbook;     // başvuru sayımlı arayüz: elle Free yok
begin
  Legacy := TXLSWorkbook.Create;
  if Legacy.Open('archive-1999.xls') <= 0 then
    raise Exception.Create('Cannot open archive file');

  Legacy.Title := 'FY1999 ledger (migrated copy)';
  Legacy.Author := 'Archive Migration Batch';
  Legacy.Company := 'Northwind Financial';
  Legacy.Comments := 'Migrated 2026-06-11; source retained in cold storage';
  Legacy.LastSavedBy := 'migration-svc';   // BIFF WRITEACCESS kaydı

  Legacy.SaveAs('archive-1999-stamped.xls');
end;

Bir adlandırma çakışması yinelenen karışıklığa yol açar. Buradaki belge düzeyindeki Comments özelliği, dosyanın özellik iletişim kutusunda gösterilen serbest metin notudur. Tümüyle ayrı bir API üzerinden aralıklara iliştirilen çizim katmanı nesneleri olan hücre yorumlarıyla hiçbir ilgisi yoktur. "Zaten Comments yazıyoruz" ifadesini hangisinin kastedildiğini denetlemeden kabul eden bir kod incelemesi, yanlış özellik hakkında bir iddiayı kabul etmiş olur ve bu, paylaşılan adın düşündüreceğinden daha sık olur. İkisi dört harf paylaşır, tek bayt depolama paylaşmaz

Girişte meta veri okumak ve yoklama boşluğu

Okuma simetriktir. Open çağrısından sonra aynı özellikler dosyadan doldurulmuş olarak geri gelir; bu da gelen çalışma kitaplarının meta veri denetimini kısa bir döngüye çevirir

var
  Book: TXLSXWorkbook;
begin
  Book := TXLSXWorkbook.Create;
  try
    if Book.Open(FileName) = 1 then
    begin
      Writeln(Format('%s | title="%s" author="%s" created=%s',
        [ExtractFileName(FileName), Book.Title, Book.Author,
         FormatDateTime('yyyy-mm-dd', Book.Created)]));
      if Book.Created = 0 then
        Writeln('  no creation date recorded');
    end;
  finally
    Book.Free;
  end;
end;

Bunu yaparken bir kısıtı hesaba katın. Yalnızca özellikleri okuyan bir yoklama yoktur. GetSheetNames bir çalışma kitabını yüklemeden sayfaları listeleyebilir ama Title ya da Author okumak tam bir Open demektir; dolayısıyla büyük bir arşivde meta veri triyajı her dosyada tam ayrıştırma bedelini öder. BIFF tarafında bu bedeli salt okunur denetimler için, açmadan önce _DisableGraphics değerini true yaparak kısabilirsiniz; bu çizim katmanını tümüyle atlar. Yalnızca özellikleri ve hücre istatistiklerini okuyan bir döngüye uyar ve aynı örneğin kayıt yapabileceği anda tam anlamıyla yanlıştır; çünkü atlanan çizim içeriği düşürülür. Kümeyi yalnızca sayfa yapısı önceden süzebildiğinde, ki atlanacak en bariz şey tek sayfalık dışa aktarımlardır, sayfa listeleme ve hafif inceleme üzerine yazımızdaki ucuz teknikler pahalı geçişe kaç dosyanın ulaştığını azaltır. Binlerce çıktının incelenmek yerine yazıldığı toplu damgalama işlerinde ise yığın işleri için akışlı yazma üzerine yazımızdaki yazma tarafı verim desenleri olduğu gibi geçerlidir; çünkü özellik ataması kaydetme süresine ölçülebilir hiçbir şey eklemez

Biçimler arası geçiş ve sızıntıyı sınırlamak

Özellikler tek bir cephe içinde temiz biçimde gidip gelir: bir .xlsx açın, düzenleyin, kaydedin; küme eksiksiz geri gelir. Eşitlik varsayımının kırıldığı yer biçimler arası geçiştir; çünkü BIFF ve OOXML alan kümeleri bire bir hizalanmaz. BIFF tarafında Manager vardır ve zaman damgası yoktur; OOXML tarafında Category, Description ve Created ile Modified çifti vardır. Körü körüne kopyalayan bir dönüştürücü, hedef biçimin tutamadığı ne varsa kaybeder; bu yüzden alanları açıkça eşleyin ve bu eşlemeyi dönüşüm kontrol listenize, yolculuğu atlatamayan diğer her şeyin yanına koyun

XLS ile XLSX arasındaki biçimler arası dönüşümde hangi Excel belge özelliklerinin hayatta kaldığını gösteren HotXLS Delphi alan haritası
Körü körüne yapılan bir biçimler arası kopya, hedefin tutamadığı her alanı düşürür — BIFF ve OOXML özellik kümelerini dönüşüm kontrol listesinde açıkça eşleyin

Şablon devralmasının açtığı sızıntı ters yöne akar: hiç göndermek istemediğiniz bilgi. Yazar adları, anahtar kelimelere park edilmiş iç proje etiketleri, kimsenin onaylamadığı bir taslak başlığı. Yukarıdaki üreticiden gelen her şeyin üzerine yazma disiplini savunmanın tamamıdır ve bunu bir yabancının yapacağı gibi doğrulamaya değer: her müşterinin ulaşabileceği Özellikler iletişim kutusunu açarak ya da .xlsx dosyasını açıp docProps/core.xml parçasını doğrudan paketten okuyarak. Orada gördüğünüz şey, aşağı akıştaki her dizinleyicinin gördüğünün aynısıdır

Aşağı akıştaki bu görünürlük, birkaç alanın diğerlerinden fazla özen hak etmesinin de nedenidir. Title, Author, Keywords (Etiketler olarak görünür) ve Comments ya da Description alanları SharePoint ile Windows Search içindeki dizinleme ağırlığının çoğunu taşır. Belge başına gerçekten ayırt edici olan, dönemi ve hesabı taşıyan bir Title, üstüne yığılan herhangi bir klasör adlandırma düzeninden daha fazlasını bulunabilirlik için yapar ve kaydetme başına tek bir atamaya mal olur

Belge özellikleri, üretilen bir çalışma kitabının taşıyabileceği en ucuz profesyonel cilalamadır ve sahibi olmadığında en sık gönderilen kusurdur. Burada anlatılan her iki özellik yüzeyi de HotXLS Delphi Component parçasıdır ve bunları XLS ile XLSX için Excel otomasyonu olmadan yerel olarak yazar