Teknik Makale

HotXLS: data validation, AutoFilter, and worksheet tables

HotXLS'teki üç özellik bir çalışma sayfasını paylaşır ama tamamen farklı nesneler üzerinde çalışır ve sorun benzer şeyler yaptıklarını varsaydığınızda başlar. Veri doğrulama, bir kullanıcının içine ne yazabileceğini kısıtlayan bir kuralı bir aralığa ekler. Bir AutoFilter, saklanan bir kriter tanımını bir bölgeye ekler ve bir görüntüleyicinin hangi satırları gösterdiğini değiştirir. Bir tablo, bir aralığı bantlı stillendirmeye sahip, adlandırılmış, tipli bir yapıya sarar. Biri girdiyi kısıtlar, biri bir görünümü kaydeder, biri bir şema dayatır. Hiçbiri tek başına tek bir hücre değerini taşımaz ve özellikle AutoFilter insanları kandırır, çünkü sözcük yalnızca bir tanım sakladığı halde bir eylem ima eder. Her çağrının hangi nesneye dokunduğunu ve etkinin gerçekte ne zaman ortaya çıktığını bilmek, Excel'de testlerinizdekiyle aynı davranan bir çalışma kitabı ile sessizce ayrışan bir çalışma kitabı arasındaki farktır

Delphi'de üç HotXLS çalışma sayfası özelliğinin şeması: veri doğrulama girdiyi kısıtlar, AutoFilter bir görünüm tanımı depolar ve tablo bir şema dayatır
Veri doğrulama, AutoFilter ve tablolar HotXLS'de aynı çalışma sayfası aralığına bağlanır; ama her biri farklı bir anda maddelleşir — yazarken, dosya açılırken ve kaydederken

AutoFilter bir tanım saklar, satırları kırpmaz

Kaydedilmiş bir dosyadaki bir AutoFilter bir kriter kaydıdır. Satır gizleme daha sonra, Excel çalışma kitabını açıp kriteri veriye karşı değerlendirdiğinde gerçekleşir. HotXLS bu kaydı sadakatle yazar ve hiçbir şeyi kırpmaz: filtrelediğiniz her satır dosyada fiziksel olarak hâlâ mevcuttur. Reddedilen siparişleri düşürmek için bir filtre uygulayan ve ardından çalışma kitabını geri okuyan bir hat, reddedilenler dahil hepsini görecektir ve kod API tarafından doğru, yazarın zihinsel modeli tarafından yanlıştır. XLSX çalışma sayfasında, SetAutoFilter filtrelenmiş bölgeyi beyan eder ve AddAutoFilterColumn onun bir sütununa kriter ekler. Sunucu tarafı kod gerçek sonuca ihtiyaç duyduğunda, bir özette satır sayısı için ya da yalnızca eşleşen satırları iletmek için, kütüphane dosyanın değiştiğini varsaymak yerine kriteri sizin için değerlendirir:

var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
  R, Visible: Integer;
begin
  Book := TXLSXWorkbook.Create;
  try
    Book.Open('orders.xlsx');
    Sheet := Book.Sheets[0];

    Sheet.SetAutoFilter('A1:E500');
    // Sütun id 3 = filtre aralığının İÇİNDEKİ dördüncü sütun (0 tabanlı ofset)
    Sheet.AddAutoFilterColumn(3, xlsxAfOpGreaterOrEqual, '1000');

    Visible := 0;
    for R := 2 to 500 do
      if Sheet.AutoFilterRowVisible(R) then
        Inc(Visible);
    // Visible artık Excel'in dosyayı açtıktan sonra göstereceğiyle eşleşiyor

    Book.SaveAs('orders-filtered.xlsx');
  finally
    Book.Free;
  end;
end;

AutoFilterRowVisible satır başına yanıt verir ve PreviewAutoFilterRows, eşleşen kümeye tek geçişte ihtiyaç duyduğunuzda tüm bölgeyi bir geri çağırma aracılığıyla gezer. İkisinin de doğru cevap olmadığı bir durum vardır: gereksinim, hariç tutulan satırların bir görünüm değil, bir gizlilik kesimi olarak dosyada hiç var olmaması gerektiğiyse, satırları doğrudan silin. Bir filtre orada yanlış araçtır, çünkü herhangi bir alıcı onu tek tıklamayla temizler ve saklamayı düşündüğünüz veri ekranda geri döner

Sütun id'si bir sütun numarası değil, bir ofsettir

Yukarıdaki kod parçasındaki yorum, bu API'de en çok hata ayıklama süresine mal olan tuzağı işaret ediyor. AddAutoFilterColumn, hedefini çalışma sayfası sütunuyla değil, filtre aralığı içindeki 0 tabanlı konumla tanımlar. A1:E500 üzerindeki bir filtre için iki numaralandırma sistemi tesadüfen birden farklıdır, ki bu tam olarak hızlı bir testi atlatan ve bir meslektaş farklı bir sütunu filtrelediği anda bozulan türden bir yakın kaçıştır. C sütunundan başlayan bir filtre için, id 0, C sütunu anlamına gelir ve uyumsuzluk hızla belirginleşir. Filtre aralığı çalışma zamanında hesaplandığında, sütun id'sini aralık dizesini oluşturan aynı değişkenden türetin, asla bir çalışma sayfası sütunu sabitinden değil. Her sütun, iki operatör, iki kriter ve bir ve/veya bağlacı alan aşırı yükleme aracılığıyla ikinci bir koşulu kabul eder, ki bu Excel'in özel filtre iletişim kutusunu yansıtır. XLS cephesi aynı zemini, kriter ve operatör parametreleri daha eski COM tarzı kurallara uyan ve alanı 1'den numaralandıran SetAutoFilter artı ApplyAutoFilter ile kapsar. Cephe değiştirmek indeks tabanını değiştirmek anlamına gelir, bu yüzden çağrı yeri hangisinin kullanımda olduğunu söyleyen bir yorumu hak eder

HotXLS AutoFilter'ın kaydedilen Excel dosyasında her satırı depoladığını, Delphi önizleme API'sinin ise Excel'in hangi satırları göstereceğini sıfır tabanlı sütun kimliği ofsetiyle değerlendirdiğini gösteren şema
Kaydedilen dosya her satırı korur ve yalnızca ölçütleri kaydeder; Excel ise satırları değerlendirdikten sonra gizler — ve AddAutoFilterColumn, sütunları aralık içinde sıfır tabanlı ofsetle hedefler

Doğrulama kuralları kullanıcılarınızın altında düzenleme yaptığı sözleşmedir

Üç özellikten, doğrulama gelecekteki girdiyi aktif olarak kısıtlayan tek özelliktir ve tamamlanmak üzere dışarı giden ve işlenmek üzere geri gelen çalışma kitaplarında en çok tasarım dikkatini hak eder. Liste varyantı bu işin çoğunu taşır:

var
  Idx: Integer;
begin
  Idx := Sheet.AddListValidation('C2:C500', 'New,Approved,Blocked');
  Sheet.DataValidations[Idx].SetPrompt('Status',
    'Pick one of the listed states');
  Sheet.DataValidations[Idx].SetError('Invalid status',
    'Type or paste only listed values', xlsxDvErrStop);
  Sheet.DataValidations[Idx].AllowBlank := False;

  // Miktarlar: tam sayılar, sıfır veya daha fazla
  Sheet.AddWholeNumberValidation('D2:D500', xlsxDvOpGreaterOrEqual, '0');
end;

Listelerin ve tam sayıların ötesinde, aynı aile ondalık sayıları, tarihleri, saatleri, metin uzunluğunu ve AddCustomValidation aracılığıyla serbest biçimli formülleri kapsar ve genel AddDataValidation, yapılandırma tarafından yönlendirilen kural oluşturucular için tam tür-ve-operatör matrisini açığa çıkarır. Hata stili adının ima ettiğinden daha önemlidir. xlsxDvErrStop kötü girdiyi doğrudan reddeder; uyarı ve bilgi stilleri değerin tek bir tıklamadan sonra geçmesine izin verir. Çalışma kitabını geri okuyan kodun kural dışı bir değere tolerans gösterip gösteremeyeceğine göre sütun başına seçin. İstem metninde ya da dosyayla birlikte gönderdiğiniz README'de yer alması gereken iki sınır var. Excel'de doğrulama yazmayı korur, ama doğrulanmış bir aralığın üzerine bir blok yapıştırmak kuralı atlatır, bu yüzden veriyi geri okuyan herhangi bir kod hücrelere güvenmek yerine yeniden doğrulama yapmalıdır. Ve bir kural size verdiğiniz gerçek aralığı kapsar, bu da doğrulamayı son satır sayısını bilmeden önce eklemenin eklenen kuyruğu korumasız bıraktığı anlamına gelir. Önce veriyi yazın, ardından kuralları gerçek kapsama göre boyutlandırın

Eski cephe, bir ergonomik farkla aynı kural ailelerini sunar. XLS tarafı oluşturucular, yani AddWholeNumberValidation, AddDecimalValidation, AddDateValidation, AddTimeValidation, AddTextLengthValidation ve AddCustomValidation, bir indeks yerine doğrudan TDataValidation nesnesini döndürür, bu yüzden istem ve hata yapılandırması bir arama yerine döndürülen referanstan zincirlenir. Operatör numaralandırması (xlsDvBetween, xlsDvGreaterThan ve gerisi) XLSX kümesini yansıtır, bu yüzden kural oluşturma kodu, bu dönüş stili farkı dışında cepheler arasında taşınır. İstem metninin kendisi kuralı kadar düşünülmeyi hak eder. Boş bir hata kutusuyla girdiyi reddeden bir açılır liste, kullanıcılara BT'ye e-posta göndermeyi öğretir; geçerli durumları adlandıran bir tanesi ise onlara hücreyi düzeltip devam etmeyi öğretir

Kütüphanenin sizin için özümsediği bir kutuplaşma tersine dönmesi

OOXML doğrulama XML'ini elle okuyan herkes ters çevrilmiş showDropDown özniteliğiyle karşılaşmıştır: ISO/IEC 29500'de true bir değer "açılır ok'u bastır" anlamına gelir, ki bu adının okunduğunun tam tersidir. HotXLS bunu dahili olarak tersine çevirir, bu yüzden bir doğrulama kuralındaki ShowDropDown özelliği, true açılır listeyi gösterirken, tam olarak söylediği anlama gelir. Yanabileceğiniz tek yol, gerçeklik seviyelerini karıştırmaktır: özelliği koddan ayarlamak, bir meslektaş kaydedilmiş XML'i denetlerken ve kendisine ters görünen özniteliği "düzeltirken". İnceleme araçları için özelliğin mi yoksa ham XML'in mi yetkili olduğuna karar verin ve tersine çevirmeyi bu kararın yaşadığı yere yazın

Tablolar bir aralığa bir şema ve bir ad verir

Excel terimleriyle ListObject olan bir çalışma sayfası tablosu, bir aralığı bir ada, tipli sütunlara, bantlı stillendirmeye ve yapılandırılmış referans desteğine sarar. Kullanıcılar sıralamaya ve genişletmeye başladığında, üretilen bir çalışma kitabını bitmiş hissettiren özelliktir. Oluşturma cepheler arasında simetriktir, AddTable bir ad, bir aralık ve bir sütun listesi alır:

Delphi'de türlü sütunlu, yapılandırılmış referanslı, çalışma kitabı-benzersiz adlı bir HotXLS çalışma sayfası tablosunun ve toplamlar-satırı ekleme tuzağının şeması
Bir HotXLS tablosu aralığını bir adla, türü belirli sütunlarla ve şeritli stillendirmeyle sarar; toplam satırı ise verinin hemen altında, naif son-satır eklemesinin düştüğü yerde durur
var
  Cols: TStringList;
begin
  Cols := TStringList.Create;
  try
    Cols.CommaText := 'OrderId,Customer,Status,Amount,Owner';
    Sheet.AddTable('Orders', 'A1:E500', Cols);
  finally
    Cols.Free;
  end;
end;

XLSX tarafında ortaya çıkan tablo nesnesi, yerleşik TableStyleMedium2 ailesini ve kardeşlerini içeren StyleName'i, şerit anahtarlarını ve bir toplamlar satırı bayrağını açığa çıkarır, bu yüzden şirket içi stillendirme uygulamak manuel bir biçimlendirme geçişi değil bir özellik atamasıdır. Eski .xls dosyalarında aynı çağrı BIFF8 tablo kayıtlarını yazar ve cephe ayrıca satır, sütun ve veri alanlarından oluşturulan özet görünümler için AddPivotTable sunar, ki bu, eski biçimdeki "tabloların" OOXML ListObject'inden daha ileri gittiğinin bir hatırlatıcısıdır. Tabloları veritabanı görünümlerini adlandırdığınız gibi adlandırın. Orders[Amount]'u yapılandırılmış referansla okuyan aşağı akış kodu, konumsal kodu bozan sütun yeniden sıralamasından sağ çıkar

İki kural sonraki temizliği kurtarır. Excel, tablo adlarının tüm çalışma kitabı genelinde benzersiz olmasını gerektirir, bu yüzden bölge başına bir sayfa üreten bir üreticinin Orders'ı yeniden kullanmak yerine Orders_EMEA gibi bir şemaya ihtiyacı vardır. Bir kopya yazma zamanında başarısız olmaz; kullanıcı dosyayı açtığında bir onarım iletişim kutusu olarak ortaya çıkar, ki bu onu keşfetmek için en kötü yerdir. Diğer kural toplamlar satırıyla ilgilidir: etkinleştirildiğinde, doğrudan veri aralığının altına oturur, bu yüzden daha sonra "son kullanılan satır artı bir" ile ekleme yapan herhangi bir kod, ondan sonrasına değil toplamlar bandına yazar. Veri kapsamını tablo kapsamından ayrı izleyin, eklemeler beklediğiniz yere iner

Üç özellik veri girişi teslimatlarında doğal olarak birleşir. Bir tablo düzenlenebilir bölgeyi tanımlar, doğrulama kullanıcıların yazdığı sütunları kısıtlar ve önceden ayarlanmış bir filtre alıcıyı ilk birkaç tıklamadan kurtarır. Çalışma kitabının önemli satırlara odaklanmış olarak açılması için önceden uygulanmış bir filtreyle göndermek için makul bir argüman vardır, hariç tutulan satırların hâlâ dosyada olduğunu ve meraklı bir alıcının onları ortaya çıkarabileceğini hatırladığınız sürece. Sorgu sonuçlarını verimli bir şekilde sayfaya almak, bu hattın yukarı akış yarısı, Delphi'den Excel'e veritabanı sonuçlarını dışa aktarma makalesinde ele alınmıştır ve formüllerin doğrulanmış veriyi özetlediği çalışma kitapları, kararlı sayfalar arası referanslar için tanımlı adlardan faydalanır

Doğrulama, filtreler ve tablolar, bir değer ızgarası göndermek ile küçük bir uygulama göndermek arasındaki farktır. Eksiksiz kural, filtre ve tablo referansı HotXLS Delphi Component ürün sayfasındadır