HotXLS, Delphi ve C++Builder için yerel bir elektronik tablo bileşenidir ve 2.209.0 sürümünden itibaren Excel'in normalde kendine sakladığı soruyu yanıtlayabilir: bu tam hücre için, hangi koşullu biçimlendirme kuralları tetiklenir ve bunlar hangi dolgu, font, veri çubuğu veya simgeye çözülür. Bu cevap, çıktınız bir HTML raporu, bir PDF veya kendinizin boyadığı bir ızgara olduğu anda ihtiyaç duyduğunuz şeydir
Bu, kural oluşturmaktan farklı bir problemdir. İki daha önceki not, yazarlık tarafını kapsar: koşullu biçimlendirme ve zengin metin stilleri, bir aralığa kurallar ve fark biçimleri eklemeyi ele alır ve bağlantılı koşullu biçimleri bölümleme, satırlar ve sütunlar eklendiğinde veya silindiğinde bir kural aralığına ne olduğunu ele alır. İkisi de yapısaldır. Bu makale ise anlambilim hakkındadır: zaten kurallar taşıyan bir çalışma kitabı verildiğinde, vurgulamayı hesaplayın
Dosya formatı hangi hücrelerin yandığını neden söylemez
Kısa cevap, ECMA-376 ve ISO 29500-1'in depolamayı tanımladığı, değerlendirmeyi değil. Bir conditionalFormatting elemanı (§18.3.1.18) bir sqref ve bir cfRule alt öğe listesi (§18.3.1.10) taşır ve her kural bir type, isteğe bağlı bir operator, bir priority, bir stopIfTrue bayrağı, bir veya iki formula alt öğesi ve görsel aileler için bir dizi cfvo eşiği taşır. Bunların her biri kullanıcının yapılandırdığı şeyi sadakatle tanımlar ve hiçbiri bir algoritma değildir. Kural türlerinin yarısı için bu boşluk önemli değildir: operator="greaterThan" olan cellIs, büyüktür anlamına gelir ve containsText, alt dizenin mevcut olduğu anlamına gelir. Boşluk toplam ailelerde açılır. 27 doldurulmuş sayısal hücre üzerinde rank="10" ve percent="1" olan bir top10 kuralı kaç hücreyi vurgular? İki nokta yedi bir sayı değildir. Yuvarla, aşağı yuvarla veya yukarı yuvarla — spesifikasyon sessizdir ve yanlış seçmek, PDF'inizin müşterinin yanında açık tuttuğu çalışma kitabıyla uyuşmadığı anlamına gelir
Tek hücreli kurallar ve TCondFormatRule.Evaluate'in durduğu yer
HotXLS önce ucuz yarıyı aldı. lxCondFormat.pas'daki, 2.199.0'da eklenen TCondFormatRule.Evaluate, aralığın geri kalanı hakkında hiçbir şey bilmeden bir kuralın bir hücre için tetiklenip tetiklenmediğini yanıtlar. cellIs'in arkasındaki sekiz BIFF karşılaştırma operatörünü (arasında, arasında değil, eşit, eşit değil, büyük, küçük, büyük eşit, küçük eşit), göreceli referansların doğru yeniden temellendirilmesi için hücrede değerlendirilen serbest biçimli expression kurallarını, dört metin yüklemini ve boş ve hata yüklemlerini işler. Eşikler, hücre konumunda TXLSCalculator.GetRangeValue üzerinden çözülen FFormula1 ve FFormula2'den gelir ve tersine dönmüş sınırlar reddedilmek yerine yer değiştirilir
var
I: Integer;
Rule: TCondFormatRule;
Value: Variant;
begin
Value := Sheet.Cells[Row, Col].Value;
for I := 0 to CondFormat.RuleCount - 1 do
begin
Rule := CondFormat.Rule(I);
// Single-cell verdict only. Aggregate and visual kinds answer False.
if Rule.Evaluate(Calculator, SheetIndex, Row, Col, Value) then
ApplyHighlight(Row, Col, Rule.Style);
end;
end;
Bu yöntemin dürüst kısmı, tahmin etmeyi reddettiği şeydir. top10, aboveAverage, belowAverage, duplicateValues ve uniqueValues, zor oldukları için değil, tek bir hücreden karar verilemedikleri için False döndürür — her biri tüm alan üzerinde bir istatistiğe ihtiyaç duyar. Dört görsel aile, dataBar, colorScale2, colorScale3 ve iconSet, farklı bir nedenle False döndürür: hiçbir zaman bir boolean üretmezler, bir render yükü üretirler ve bir Boolean dönüş türü onlar için yanlış şekildir
Bir sayfa düzeyi değerlendirici sayfayı yeniden taramaktan nasıl kaçınır?
Her paylaşılan miktarı yalnızca bir kez, inşa sırasında hesaplayarak ve bir daha asla hesaplamayarak. lxHandleX.pas'daki TXLSXConditionalFormatEvaluator, TXLSXWorksheet.CreateConditionalFormatEvaluator üzerinden inşa edilen, bir çalışma sayfası için değişmez bir anlık görüntüdür ve tüm tasarımı, her boyanan hücrenin tam aralık taramasını tetiklediği saf uygulamaya karşı bir savunmadır
Yapıcıda dört şey gerçekleşir. Her farklı çok bölgeli sqref, bir TXlsxCfRangeSnapshot'a tam olarak bir kez ayrıştırılır, dolayısıyla bir aralığı paylaşan on kural bir ayrıştırmayı ve bir istatistik geçişini paylaşır. O geçiş, doldurulmuş hücreler üzerinde ortalamayı, popülasyon sapmasını, minimumu ve maksimumu tek bir yürüyüşte akıtır ve yalnızca bir Top/Bottom veya yüzdelik kural gerçekten sıralama istatistiklerine ihtiyaç duyduğunda sıralı bir sayısal dizi tutar. Tekrarlanan ve benzersiz anahtarlar Unicode-güvenli olarak inşa edilir ve arama başına değil toplu olarak bir kez sıralanır. Sonra satır ekseni her bölge sınırında bantlara kesilir, dolayısıyla EvaluateCell bir bandı ikili aramayla bulur ve yalnızca aralıkları o satıra ulaşabilen kuralları ziyaret eder
Dördüncüsü ölçekte en çok önem taşıyan şeydir. =A1>AVERAGE($A$1:$A$100) gibi göreceli bir kural formülü, alanın her hücresinde farklı bir şey ifade eder ve bariz uygulama hücre başına taze bir söz dizimi ağacı derler. TXlsxCfRulePlan onu bir kez derler ve aynı ağacı tersine çevrilebilir koordinat ofsetleri üzerinden yeniden değerlendirir, ki bu hücre başına bir söz dizimi ağacı tahsisi olmadan Excel çıpa davranışını korur. Kurallar sonra priority'ye göre katmanlanır ve StopIfTrue'u ayarlanmış bir kuraldaki bir eşleşme, tam olarak Excel'in kısa devre yaptığı gibi döngüyü kırar
var
Evaluator: TXLSXConditionalFormatEvaluator;
Res: TXLSXCfCellResult;
begin
Evaluator := Sheet.CreateConditionalFormatEvaluator;
try
if Evaluator.EvaluateCell(Row, Col, Res) then
begin
if Res.HasFillColor then
Canvas.Brush.Color := TColor(Res.FillColor);
if Res.HasIcon then
// IconIndex is zero-based inside Res.IconSetType
DrawIcon(Res.IconSetType, Res.IconIndex, Res.IconCount);
if Res.HasDataBar then
// DataBarAxis and DataBarEnd are normalised to 0..1
DrawBar(Res.DataBarAxis, Res.DataBarEnd, Res.DataBarColor);
if not Res.ShowCellValue then
Exit; // showValue="0" on the rule hides the number
end;
finally
Evaluator.Free;
end;
end;
Excel bir Top 10 yüzde kuralını gerçekte nasıl yuvarlar?
Aşağı yuvarlar, en az bir ile, ve kesme noktasındaki beraberlikleri dahil eder. Bu, ISO 29500-1'de hiçbir yerde yazılı değildir — elle inşa edilmiş çalışma kitaplarıyla Excel 16'yı yoklayarak ve uygulamanın hangi hücreleri vurguladığını geri okuyarak sabitlenmiştir. HotXLS tam olarak bunu uygular: sıra sayısı Floor(Count * Min(Rank, 100) / 100)'dür, sıfıra düştüğünde 1'e yükseltilir, doldurulmuş sayıya sınırlandırılır ve kesme değeri sonra >= ile karşılaştırılır, dolayısıyla sınıra eşit her hücre, bu istenen sayıyı aşsa bile vurgulanır. Yirmi yedi değer ve yüzde 10 kural iki hücreyi vurgular, artı ikinciyle bağlantılı herhangi bir başka hücre
Ortalama-üstü kuralları ikinci bir belirsizliği gizledi: stdDev="1" olan aboveAverage, ortalamanın bir standart sapma üstündeki hücreleri seçer, ama örnek ve popülasyon sapması Bessel düzeltmesiyle farklılaşır ve küçük aralıklarda görünür şekilde uyuşmazlar, ki koşullu biçimlendirmenin kullanıldığı yer tam olarak burasıdır. Excel 16 popülasyon sapmasını kullanır ve HotXLS ona eşleşir, equalAverage bayrağı katı karşılaştırmayı yalnızca hiçbir sapma bandı devrede olmadığında kapsayıcı hâle getirir. Tekrarlanan ve benzersiz kurallar bunun yerine anahtar kimliğine döndü. Bir hücre 100 sayısını tutuyorsa ve diğeri "100" metnini tutuyorsa, Excel onları aynı tekrarlanan anahtar olarak ele alır, dolayısıyla HotXLS sayısal metni ham dizeleri karşılaştırmak yerine sayısal anahtar uzayına normalleştirir. Boş hücreler ayna durumdur: gerçek bir boş hücre aralık sayımına katılır ama kendisi biçimlendirilmez, dolayısıyla bir sütundaki boş hücreler birbirlerinin tekrarı olarak hepsi yanmaz
Renk skalaları ve simge setleri: enterpolasyon ve sınır kuralları
Görsel aileler boolean'lar yerine render'a hazır sayılara çözülür ve kenar davranışları aynı şekilde sabitlendi. Açık sayısal eşikleri olan bir renk skalası için HotXLS, konum kesirini kapalı sıfır-bir aralığına sabitler, sonra her kanalı yuvarlama yerine kesme ile enterpolasyon yapar — minimumun altındaki bir değer ekstrapolasyonlu bir renk yerine minimum rengi alır, üç durak bir skala çiftini orta durakla karşılaştırarak seçer ve iki ucu aynı eşiği taşıyan dejenere bir skala, sıfıra bölmek yerine en üst renge çöker. Simge setleri tersi türden bir özen gerektirdi, çünkü ilkinden sonraki her cfvo kendi karşılaştırma katılığını taşır: HotXLS eşik başına ThresholdEqualsInclude'u okur ve buna göre >= veya > uygular, yukarı doğru yürüyerek en yüksek karşılanan eşik simge indeksini kazanır. Tersine çevrilmiş bir set, eşikleri değil çözülen indeksi çevirir, simge başına geçersiz kılmalar farklı bir aileden bir glif çekebilir ve herhangi bir geçersiz eşik, makul görünen yanlış bir simge üretmek yerine kuralı iptal eder
Tek bir sonuçtan bir ızgara, bir HTML export'u ve bir PDF beslemek
EvaluateCell, tam olarak çözülmüş bir TXLSXCfCellResult döndürdüğü için — tema tonu zaten uygulanmış fark dolgusu ve font rengi, kalın, italik, altı çizili, sayı biçimi kimliği, yönlü pozitif ve negatif çubuk uzantıları, eksen konumu, simge ailesi ve indeksi — her tüketici aynı kaydı okur ve hiçbiri kural iç yapısını anlamak zorunda değildir. HotXLS bu tek yolu HTML export, PDF export ve etkileşimli görüntüleyici için kullanır, ki bu üç renderer'ın birbirinden uzaklaşmasını önlemenin tek pratik yoludur. 2.210.0 sürümü bunu TXLSWorkbookViewer'a bağladı, ki bu her etkin çalışma sayfası için hazırlanmış bir değerlendiriciyi önbelleğe alır ve onu kaydırma, seçim ve yeniden boyama boyunca yeniden kullanır, çalışma kitabı veya çalışma sayfası değiştiğinde serbest bırakır — anlık görüntüyü her Paint'te yeniden inşa etmek, tüm inşa-zamanı tasarımını yenerdi. O önbellek aynı zamanda TXLSWorkbookViewer.RefreshConditionalFormats'ın neden var olduğudur: anlık görüntü değişmezdir, dolayısıyla bağlı çalışma kitabını yerinde değiştirirseniz, toplam istatistikler ve çözülmüş eşikler onu çağırana kadar eskimiştir
// Editing behind a live viewer: the cached snapshot must be invalidated.
Sheet := Viewer.XlsxWorkbook.Sheets[1];
Sheet.Cells[5, 2].Value := 4200; // changes mean, min, max, ranking
Viewer.RefreshConditionalFormats; // drop evaluator, repaint
Değerlendiricinin sizin için yapmayacağı şeyler
Açıkça belirtmeye değer üç sınır vardır. Klasik tek hücreli TCondFormatRule.Evaluate ve sayfa düzeyi TXLSXConditionalFormatEvaluator, farklı yeteneklere sahip farklı yüzeylerdir ve tek hücreli olan, toplam ve görsel aileleri yaklaştırmak yerine kasıtlı olarak reddeder — Top/Bottom veya bir renk skalasına ihtiyacınız varsa, değerlendiriciyi inşa edin. Göreceli tarih dönemleri, değerlendirme anındaki makine saatine bağlıdır, dolayısıyla bir timePeriod kuralı, bugün üretilen bir PDF'de ve gelecek hafta üretilen bir PDF'de farklı render edilir, ki bu doğru davranıştır ve arşivinizin byte-kararlı olması bekleniyorsa hâlâ bekleyen bir destek talebidir. Üçüncüsü teknik olmaktan çok dilbilgiseldir: koşullu-biçim formül dilbilgisi yapılandırılmış tablo referanslarını yasaklar, dolayısıyla bir kural bir çalışma sayfası formülünün yapabileceği gibi bir tablo sütununa isimle hitap edemez ve bu, uygulamanın değil formatın bir kısıtlamasıdır
Rapor çıktısı, bir export boru hattı veya Excel ile hücre hücre uyuşması gereken özel bir ızgara inşa ediyorsanız, aynı çözülmüş sonuç bu blogda başka bir yerde anlatılan özel VCL elektronik tablo ızgarasını da yönlendirir. HotXLS Delphi elektronik tablo bileşeni için tam API dokümantasyonu, kural modeli ve deneme indirmeleri ürün sayfasında mevcuttur