Teknik Makale

HotXLS: Delphi'de Excel AutoFilter'ları Excel'siz Çalıştırma

HotXLS, bir XLSX dosyasına hâlihazırda saklanmış AutoFilter ölçütlerini Excel'i başlatmadan değerlendirir. v2.384.136'dan itibaren TXLSXWorksheet.PreviewAutoFilterRows, ApplyAutoFilter ve AutoFilterRowVisible, donmuş bir referans tarihi ve açık kaynak sınırları altında değer listelerini, tarih gruplarını, Top/Bottom-n ve yüzde filtrelerini, göreli tarih ve ortalama filtrelerini, dolgu ile yazı tipi renk filtrelerini ve koşullu biçimlendirme simge filtrelerini çalıştırır

Olağan tetikleyici, birinin Excel'de filtrelediği bir çalışma kitabı ve üzerinde işlem yapmak zorunda olan bir sunucudur. Biri sipariş tarihine "Gelire göre Top 10" ile "Bu ay" filtrelerini ve gecikmiş satırlara kırmızı bir dolgu koyar, kaydeder ve dosyayı yükler. Delphi servisinizin artık Excel'in göstereceği satır kümesine ihtiyacı vardır: onu saymak, dışa aktarmak ya da dosyayı doğru satırlar gizliyken geriye yazmak için. Dosya yalnızca tanımı taşır. Bu sürümden önce HotXLS sıradan özel ölçütleri değerlendirebiliyordu ama gelişmiş türler saklanan XML'de duruyor, onları çalıştıran hiçbir şey yoktu; dürüst yanıt "Excel'de açın" oluyordu

HotXLS saklanmış bir AutoFilter'dan gerçekte neyi çalıştırır?

HotXLS sütun başına bir filtre türü çalıştırır; bunları Excel'in yazdığı filterColumn öğesinden alır ve sütunları AND ile birleştirir; tıpkı Excel açılır menüleri gibi. Öğeler ECMA-376 Part 1 §18.3.2'deki AutoFilter grubundan gelir ve her biri ayrı bir değerlendirme yoluna eşlenir:

Delphi'de HotXLS AutoFilter yürütümü, saklanan her filterColumn öğesini beş değerlendirme yolundan birine sevk eder — filters, customFilters, top10, dynamicFilter, colorFilter ya da iconFilter — ve başka her şey için EXLSXAutoFilterUnsupported fırlatır
HotXLS, ECMA-376 Part 1'in AutoFilter grubundan sütun başına bir filtre türü değerlendirir ve sütunları AND ile birleştirir; görünür satır kümesi böylece Excel açılır menülerinin göstereceğiyle eşleşir
  • Alt öğeleri filter ve dateGroupItem olan filters: işaretli bir değer listesi, isteğe bağlı bir boş girdi ve yıldan saniyeye inen takvim tarih grupları; OR ile birleşik
  • customFilters: AND ya da OR ile birleştirilmiş bir ya da iki karşılaştırma ölçütü; zaten var olan yol
  • top10: Top ya da Bottom n öğe ya da yüzde n; val 1-500 öğe ya da 1-100 yüzde ile sınırlı
  • dynamicFilter: bugün, dün, yarın; bu/geçen/gelecek hafta, ay, çeyrek ve yıl; yıl başından bu yana; M1-M12, Q1-Q4; ortalamanın üzerinde ve altında
  • colorFilter ve iconFilter: differential style üzerinden çözülen etkin dolgu ya da yazı tipi rengi; simge kümesi ve sıfır tabanlı simge kimliğine göre koşullu biçimlendirme simgeleri

Listenin dışındaki her şey, tahmin edilmiş bir satır kümesi üretmek yerine EXLSXAutoFilterUnsupported ile başarısız olur. Buna ST_DynamicFilterType'in standart sapmanın üzerinde ve altında türleri, Gregoryen olmayan calendarType değerleri, bilinmeyen uzantı öğeleri, çözülemeyen dxfId referansları ve bir şekilde aynı anda iki filtre türü taşıyan bir sütun dahildir. Sessizce "yaklaşık doğru" satırlar döndüren bir filtre motoru, reddedenden daha kötüdür; yanlış müşterilerle bir rapor çıkana dek kimse fark etmez

Önce önizleme, sonra uygulama

HotXLS işi salt okunur bir önizleme ile işlemsel bir uygulamaya böler ve ikisi de aynı TXLSXAutoFilterExecutionOptions kaydını alır. PreviewAutoFilterRows, eşleşen veri satırı sayısını döndürür ve satır görünürlüğüne hiç dokunmaz. ApplyAutoFilter(AResetVisible, Options) önce her satır kararını hazırlar ve yeni gizli satır kümesini ancak o zaman tek adımda yayımlar; hazırlık sırasında bir istisna, sayfayı tam olarak bırakıldığı gibi bırakır

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  Options: TXLSXAutoFilterExecutionOptions;
  Matching: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('orders-filtered-by-sales.xlsx');
    Sheet := Book.Sheets[1];   // Sheets indeksleyicisi 1 tabanlıdır

    // Daima varsayılanlardan başlayın, sonra tek tek alanları değiştirin
    Options := XLSDefaultAutoFilterExecutionOptions;
    Options.ReferenceDate := EncodeDate(2026, 10, 19);

    Matching := Sheet.PreviewAutoFilterRows(nil, Options);  // yalnızca sayım
    WriteLn('Rows Excel would show: ', Matching);

    // True: eşleşen satırlar daha önce gizli olsalar bile görünür olur
    Sheet.ApplyAutoFilter(True, Options);
    Book.SaveAs('orders-applied.xlsx');
  finally
    Book.Free;
  end;
end;

Kaydı her seferinde XLSDefaultAutoFilterExecutionOptions ile başlatın. Fonksiyon kaydı sıfırla doldurur ve sonra her sınırı ayarlar; yürütme bağlamı, sınırların hepsi pozitif olmayan bir kaydı EXLSXAutoFilterLimit ile reddeder. Yığında bildirilip alan alan doldurulan bir kayıt, unuttuğunuz alanlarda genellikle çöp ya da sıfır taşır. Parametresiz aşırı yüklemeler (ApplyAutoFilter(True), PreviewAutoFilterRows(Callback), AutoFilterRowVisible(Row)) aynı varsayılanları kullanır; referans olarak geçerli tarihle

AResetVisible bayrağı, filtrede geçen ama hâlihazırda gizli olan satırlara ne olacağına karar verir. True her eşleşen satırı görünür yapar; yeniden uyguladığınızda Excel'in yaptığı da budur. False eşleşen satırlardaki önceki elle gizlemeyi korur ve yalnızca geçemeyen satırlar için gizleme ekler. AutoFilter aralığının dışındaki satırlar her iki durumda da durumlarını korur. Çalışma kitabı hazırlık ile yayım arasında değiştiyse ApplyAutoFilter, bayat veriden hesaplanmış kararları yayımlamak yerine istisna fırlatır

Değer listeleri yıldız ve soru işaretlerini neden yok sayar?

Bir filters öğesindeki değer listesi girdileri harfi harfine görüntü belirteçleridir; HotXLS * ile ?'yi sıradan karakterler olarak karşılaştırır. Açılır menüde işaretli bir A* girdisi, hücrenin tam olarak A* gösterdiği anlamına gelir; "A ile başlar" değil. Joker karakterler customFilters'a aittir; "ile başlar" ile "içerir" gerçekten desendir ve onlar HotXLS'in Excel joker ölçütleriyle tilde kaçışlarını nasıl eşlediği makalesindeki ayrı kuralları izler. İki anlamı karıştırmak, parça numarası sütununu en hızlı anlamsızlığa filtreleme yoludur

Karşılaştırma görüntülenen değere karşı yapılır; bu da hangi görüntü sorusunu doğurur. HotXLS hücreyi, saklanan stil katmanları dahil, taban sayı biçimiyle biçimler ve koşullu biçimlendirmenin üzerine koyduğu sayı biçimini bilerek yok sayar. HotXLS test setindeki yerli Excel kontrolleri belirtecin neden önemli olduğunu gösterir: sayısal 1 ile metin "1" bir 1 seçimine ikisi de eşleşir; 0.0 olarak biçimlenmiş sayısal 1 ise metin "1.0" ile birlikte 1.0'a eşleşir ve metin "01" ikisinden de ayrı kalır. Tarih görünümlü metin asla tarihe çözülmez; "2026-10-19" tutan bir metin hücresi bir tarih grubuna düşmez

Top 10, ortalama ve dinamik tarih filtreleri nasıl karar verir?

HotXLS sıralama ve ortalama eşiklerini, başka bir filtrenin görünür bıraktığı satırlar üzerinde değil, kaynak sütunun tamamı üzerinde bir kez hesaplar. Yalnızca sonlu sayılar popülasyona girer; yani "100" gibi sayı görünümlü metin dışlanır ve popülasyon, hiçbir satır kararı verilmeden önce toplanır. Yerli kontrol çalışma kitabında ortalamanın üzerinde filtresi, ikinci bir sütun 50 değerini gizledikten sonra bile bütün sütunda 27 ortalamasını korur; kalan satırların 21.25 ortalamasına geçmez

Beraberlikler eşikte dahil edilir; Excel'de olduğu gibi. İki girdisi 20'de beraber olan değerler üzerindeki bir Top 3 filtresi dört satır seçer. Yüzde modu, sayısal popülasyonun kırpmış payını alır ve tek öğelik bir taban uygular; beş değerde Top 50 yüzde, 30 eşiğiyle iki değer seçer. Bottom varyantları karşılaştırmayı aynalar. Bu sayılar HotXLS test setlerine kaydedilmiş Excel'in kendi satır kümelerinden gelir; spesifikasyonu okumaktan değil, çünkü spesifikasyon çoğunda sessizdir

Delphi'de HotXLS, Excel AutoFilter Top 10, yüzde ve ortalama-üstü eşiklerini kaynak sütunun tamamı üzerinde bir kez hesaplar; gizli değerleri popülasyonda ve beraberlikleri eşikte sonuçta tutar
Ortalama-üstü, kalan satırların 21.25 ortalaması yerine bütün sütunun 27 ortalamasını korur ve iki girdisi 20'de beraber olan değerler üzerindeki bir Top 3 filtresi dört satır seçer

Dinamik tarihler donmuş bir referans tarihi ister

TXLSXAutoFilterExecutionOptions.ReferenceDate, "bugün"ün anlamını bütün bir işlem için dondurur. Bu hafta ya da geçen çeyrek gibi göreli filtreler ile renk filtrelerini besleyen koşullu biçimlendirme tarih kuralları, hepsi o tek tarihe karşı değerlendirilir; 23:59:59'daki bir önizleme ile bir saniye sonraki uygulama böylece uyuşur. Sıfır değer, işlem başladığında geçerli tarihi bir kez seçer; serial değerler çalışma kitabının 1900 ya da 1904 tarih sistemine uyar; M2 ile Q1 filtreleri için 1900 sistemindeki Excel'in uydurma serial 60'ı dahil

Pencereler yarı açık takvim aralıklarıdır: bu hafta Pazar'dan izleyen Pazar'a kadar; bu çeyrek çeyreğin ilk gününden sonrakinin ilk gününe kadar; yıl başından bu yana ise 1 Ocak'tan referans gününün sonuna kadar. Toplu işte ya da testte çalışan her şeyde ReferenceDate'yi açıkça sabitleyin. Gece yarısını geçen bir gece işi ya da Ekim'de yazılıp Ocak'ta da geçmesi gereken bir birim testi, aksi hâlde görünürde hiçbir nedeni olmayan farklı satır kümeleri üretir

Delphi'de HotXLS, Excel dynamicFilter göreli tarih kurallarını tek bir donmuş TXLSXAutoFilterExecutionOptions.ReferenceDate'e karşı değerlendirir; yarı açık bu hafta, çeyrek ve yıl başından bu yana pencereleriyle
Referans tarihini dondurmak, 23:59:59'daki önizleme ile bir saniye sonraki uygulamayı uyuşturur ve M2 ile Q1 filtrelerini etkileyen 1900 sistemli serial 60 garabetini sabitler

Formül hücreleri önbelleklenmiş değerleri üzerinden filtrelenir. Filtre motoru çalışma kitabını sessizce yeniden hesaplamaz; önbelleklenmiş sonuç bırakmayan bir yazıcı tarafından kaydedilmiş dosya, filtrenin anlamlı sayı ya da tarihleri görebilmesi için açık bir hesaplama geçişi ister

Bir renk filtresi hangi renkleri görür?

Bir HotXLS renk filtresi, doğrudan hücre biçimlendirmesinden ve onunla eşleşen koşullu biçimlendirme geçersiz kılmalarından gelen etkin rengi görür; yalnızca tablo stilinden gelen hiçbir şeyi görmez. Excel aynı davranır: yerleşik bir tablo stilinin açık maviye boyadığı şeritli bir satır, filtre açılır menüsüne "açık mavi" değildir. Yerli kontrollerde koşullu biçimlendirmenin kırmızıya boyadığı bir hücre kırmızı dolgu filtresiyle seçilir; doğrudan kırmızı biçimlenmiş ama etkin bir sarı kuralca ezilmiş hücre ise dışlanır

İzleyen sürümlerde üç iyileştirme geldi. 2.384.138 sürümü, lineer ve path gradyan dolgularını hem düz renklerden hem dolgusuzluktan ayrı sayar; gradyan, duraklarından biri tam o rengi taşısa bile asla düz renk ölçütüyle eşleşmez. 2.384.140 sürümü zengin metin için yazı tipi renk filtrelemesi ekledi: boş olmayan herhangi bir run istenen RGB, otomatik ya da miras alınan rengi taşıyorsa hücre eşleşir. 2.384.150 sürümü koşullu zengin metin kararlarını tamamladı; tuhaf olanın o olduğu ortaya çıktı

Yerli Excel, aynı metne, aynı taban stile ve aynı eşleşen koşullu kural yoluna sahip bir zengin metin hücresi ile düz bir hücre arasında renk kararını yeniden kullanabilir; görünür satır kümesi bu yüzden o hücrelerin sırasına bağlı olabilir. HotXLS bunu, tam veri aralığını artan satır sırasıyla hazırlayarak yeniden üretir; AutoFilterRowVisible'a yalnızca tek bir satırı sorsanız bile. 40. satırı incelemek bu yüzden aralık üzerinde bir geçişe mal olur ama satır incelemesi, önizleme ve uygulama aynı satır için daima aynı yanıtı verir

Her kaynağın bir sınırı vardır ve yakalanacaklar

HotXLS, bir AutoFilter işlemindeki her iş türünü TXLSXAutoFilterExecutionOptions içindeki kendi alanıyla sınırlar; çünkü bir yükleme formundan gelen filtreli çalışma kitabı güvenilmeyen bir girdidir. Varsayılanlar: MaxXmlCharacters için 1048576, MaxXmlNodes için 16384, MaxFilterItems için 4096, MaxExaminedCells için 4000000, MaxEffectiveFormatCells ile MaxPopulationValues için her biri 1000000, MaxContextBytes için 67108864 bayt ve MaxConditionalSteps için 16000000. MaxContextBytes süreç belleğini değil tutulan mantıksal durumu ve rezerve edilmiş geçici zarfları ölçer

type
  TFilterJob = class
  public
    Deadline: TDateTime;
    VisibleRows: TList<Integer>;
    procedure HandleRow(Sender: TObject; SheetIndex, Row: Integer;
      Visible: Boolean; var Cancel: Boolean);
    procedure HandleWork(Sender: TObject; ACompleted: Int64;
      var ACancel: Boolean);
  end;

procedure TFilterJob.HandleRow(Sender: TObject; SheetIndex, Row: Integer;
  Visible: Boolean; var Cancel: Boolean);
begin
  // Her veri satırı için çağrılır; Visible, filtre kararıdır
  if Visible then
    VisibleRows.Add(Row);
end;

procedure TFilterJob.HandleWork(Sender: TObject; ACompleted: Int64;
  var ACancel: Boolean);
begin
  // ACompleted incelenen hücreleri sayar; biçimlendirme sırasında sabit kalabilir
  ACancel := Now > Deadline;
end;

PreviewAutoFilterRows'in satır callback'i her veri satırını kararıyla birlikte alır; yalnızca eşleşenleri değil ve fonksiyon yine de eşleşen sayısını döndürür. Cancel parametresini ayarlamak ziyareti istisnasız erkenden durdurur. OnWork iptal kanca noktasıdır: ACancel'i True yapmak EXLSXAutoFilterCancelled fırlatır. İşlem kararları hazırlarken çalışma kitabı üzerinde bir okuma kiralaması tutar; iki callback de o çalışma kitabını değiştiremez

Options := XLSDefaultAutoFilterExecutionOptions;
Options.ReferenceDate := Date;
Options.MaxExaminedCells := 500000;   // yüklenen dosyalar için daha sıkı tavan
Options.OnWork := Job.HandleWork;
try
  Sheet.PreviewAutoFilterRows(Job.HandleRow, Options);
  Sheet.ApplyAutoFilter(True, Options);
except
  on E: EXLSXAutoFilterUnsupported do
    Log('Filter needs Excel: ' + E.Message);
  on E: EXLSXAutoFilterLimit do
    Log('Filter exceeded a budget: ' + E.Message);
  on E: EXLSXAutoFilterCancelled do
    Log('Filter cancelled at deadline');
  on E: EXLSXAutoFilterExecution do
    Log('Filter state invalid: ' + E.Message);
end;

Üç özel istisna da EXLSXAutoFilterExecution'den türetilir; o da desteklenen takvimin dışında bir referans tarihi ya da yayımdan önce değişmiş bir çalışma kitabı gibi geçersiz durumları kapsar; taban sınıfı bu yüzden en sona koyun. Her durumda sayfanın satır görünürlüğü değişmez; bu da "günlüğe yaz, atla, dosyayı elle inceleme için işaretle"yi güvenli bir varsayılan politika yapar

Sınırların nerede olduğu

Kapsam geniştir ama müşteriye denklik sözü vermeden önce bilinmeye değer birkaç kenar vardır:

  • Doğrulanmış bir politika var olana dek standart sapma dinamik filtreleri reddedilir; numaralandırmanın onlar için değerleri olsa bile
  • Hafta pencereleri Pazar günü başlar; başka bir hafta başlangıcına dayanan çalışma kitapları modellenmez
  • Formül sonuçları yalnızca saklanan önbellekten gelir; filtre çağrısı içinde yeniden hesaplama yoktur
  • Tablo stili renkleri tasarım gereği ve Excel ile uyum içinde asla bir renk filtresiyle eşleşmez
  • Bilinmeyen zengin metin yapısı ya da bilinmeyen renk üst verisi açıkça başarısız olur; font family gibi bilinen renk dışı özellikler bir renk eşleşmesini engellemez
  • XLS cephesi ve onun BIFF8 deposu ayrı bir yoldur; HotXLS'in BIFF8 AutoFilter DOPER ölçütlerini nasıl yazdığı makalesinde işlenir

Kendinizin ürettiği bir çalışma kitabında AutoFilter tanımları, veri doğrulama ve tabloların nasıl ilişkili olduğuna hâlâ karar veriyorsanız HotXLS veri doğrulama, AutoFilter ve tablolar (Delphi) ile başlayın; SetAutoFilter, sütun kimlikleri ve bir filtrenin ne zaman fiilen etkin olduğu orada anlatılır

SSS

PreviewAutoFilterRows hangi satırların gizli olduğunu değiştirir mi?

Hayır. PreviewAutoFilterRows yalnızca saklanan ölçütleri değerlendirir ve kararları dönüş değeriyle isteğe bağlı callback'i üzerinden bildirir. Yeni gizli satır kümesini yalnızca ApplyAutoFilter yayımlar ve bunu bütün kararlar hazırlandıktan sonra yapar; bir başarısızlık özgün görünürlüğü bozulmadan bırakır

Göreli bir tarih filtresi neden farklı günlerde farklı satırlar verir?

Bugün, bu hafta ya da geçen ay gibi filtreler geçerli tarihe göre tanımlanır; tıpkı Excel'deki gibi. Tekrarlanabilir sonuçlara ihtiyaç duyduğunuzda TXLSXAutoFilterExecutionOptions içindeki ReferenceDate'yi sabit bir tarihe ayarlayın; sıfır değer, işlemin başladığı tarih demektir

HotXLS, tablo stilinden gelen renklerle filtre uygulayabilir mi?

Hayır; Excel de yapamaz. HotXLS renk filtreleri yalnızca doğrudan hücre biçimlendirmesiyle ve desteklenen koşullu biçimlendirme geçersiz kılmalarıyla eşleşir. Yalnızca yerleşik ya da özel bir tablo stiliyle boyanmış renkler katılmaz; renk filtresi sonucu böylece Excel açılır menüsünün seçeceğiyle uyuşur

Gelişmiş AutoFilter yürütümü, v2.384.136'dan itibaren Excel dosyalarını Excel olmadan okuyup yazan Delphi elektronik tablo bileşeni HotXLS'in XLSX çalışma sayfası API'siyle gelir; gradyan, zengin metin ve koşullu zengin metin renk işlemesi v2.384.150'ye kadar eklendi