HotXLS, Excel 365 dinamik dizi taşma (spill) formüllerini Delphi ve C++Builder'da yerel olarak değerlendirir: hücreleri XLOOKUP veya FILTER içeren bir çalışma kitabını ona verirsiniz ve formül motoru sonuç kümesini hesaplayıp Excel'in üreteceği değerlerin aynısını bağlı çıktı dikdörtgenine taşır. HotXLS Delphi Excel bileşeni, bir taşma formülünü hesaplamanın sahibi olan tek bir kök hücre artı ondan geri okuma yapan bağımlı hücre bloğu olarak modeller; bu, kod yazmaya başlamadan önce ihtiyacınız olan resmin tamamıdır
Bu model önemlidir çünkü günlük görev soyut değildir. Bir müşteri Excel 365'te oluşturulmuş bir .xlsx dosyası gönderir, sayfaları =FILTER(...) ve =XLOOKUP(...) ile doludur ve servisinizin aynı sayıları Excel kurulu olmayan bir makinede arka planda (headless) üretmesi, ardından taşan değerleri okuması veya kendi oluşturduğunuz yeni bir taşma bölgesine yazması gerekir. Dinamik diziler formül sözleşmesini "bir formül, bir hücre"den "bir formül, bir hücre dikdörtgeni"ne dönüştürdü ve HotXLS motoru bu sözleşmeyi önceden genişletilmiş bir ızgara ile taklit etmek yerine doğrudan takip eder
Delphi'de XLOOKUP ve FILTER'ı nasıl değerlendirirsiniz?
HotXLS, her dinamik dizi işlevini lxCalc.pas içindeki tek bir değerlendirici giriş noktası olan CalcDynArrayFunc aracılığıyla yönlendirir, böylece tüm aile tek bir taşma kod yolunu paylaşır. Desteklenen küme; XLOOKUP ve FILTER (orijinal ikisi), bunların yanına katılan XMATCH, SORT, UNIQUE ve SEQUENCE işlevleridir. Her biri bir skalar değer yerine 2 boyutlu bir variant dizi döndürür: SEQUENCE(3;2;1;1) eylemi 3'e 2'lik bir ızgara verir, SORT satırları herhangi bir anahtar sütuna göre artan veya azalan şekilde yeniden sıralar, UNIQUE ilk oluşumu koruyarak yinelenen satırları daraltır ve XMATCH, XLOOKUP ile tam olarak aynı tam eşleşme, joker karakter, bir sonraki en küçük ve bir sonraki en büyük eşleşme modlarında bir değerin 1 tabanlı konumunu raporlar. Her çağrıda bir sayı döndüren skalar istatistiksel dağılım işlevlerinin aksine, bu işlevler bütün bir şekil geri verir
Halihazırda bu formülleri taşıyan bir çalışma kitabını hesaplamak için onu açın, bir kez Recalculate çağırın ve taşmanın düştüğü hücreleri okuyun. TXLSXWorkbook.Recalculate bağımlılık grafiğini tarar ve her kirli formülü topolojik sırada değerlendirir, böylece bir taşma kökü tek bir kez hesaplanır ve elemanları doğrudan üye hücrelere yazılır
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
r, c: Integer;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('from-customer.xlsx');
Book.Recalculate; // evaluate every formula, spills included
Sheet := Book.Sheets[1]; // Sheets is 1-based
// Read back the block the XLOOKUP / FILTER spilled into, say D2:F9.
for r := 2 to 9 do
for c := 4 to 6 do
Writeln(Sheet.Cells[r, c].Text);
finally
Book.Free;
end;
end;
Çalışma kitabı motorun sunmadığı bir işleve ihtiyaç duyarsa, aynı değerlendirici, özel çalışma sayfası işlevleri bağlantısı aracılığıyla kendi mantığınızı takmanıza olanak tanıyan ve özel bir işlev, yerleşik olanlar gibi taşması için bir variant dizi döndürmekte serbesttir
SetArrayFormula ile taşma aralığını bağlama
HotXLS, bir taşmanın ne kadar büyük olması gerektiğini asla tahmin etmez: çıktı dikdörtgenini siz belirlersiniz ve TXLSRange.SetArrayFormula formülü ona bağlar. Yöntem formülü bir kez derler, söz dizimi ağacını sol üst kök hücrede bağlı aralıkla birlikte saklar ve dikdörtgendeki diğer her hücreye köke zayıf başvuru yapan hafif bir formül verir. Yeniden hesaplamada kök bir kez değerlendirilir ve matris elemanları doğrudan her bir üye hücreye yayınlanır; bu aynı zamanda bir taşma kökünün artan yeniden hesaplama bağımlılık grafiğinde tek bir düğüm olarak görünme şeklidir. Bu, göreviniz dosyadan bir taşma okumak yerine dosyaya bir taşma bölgesi yazmak olduğunda izlenecek yoldur
var
Book: TXLSXWorkbook;
Sheet: TXLSXWorksheet;
begin
Book := TXLSXWorkbook.Create;
try
Book.Open('report.xlsx');
Sheet := Book.Sheets[1];
// Size the rectangle to the result: a 3-row by 2-column grid.
if Sheet.Range['A1:B3'].SetArrayFormula('=SEQUENCE(3;2;1;1)') > 0 then
Book.Recalculate; // fill A1:B3 with 1..6 down the rows
Book.SaveAs('report-out.xlsx');
finally
Book.Free;
end;
end;
Açık bağlamanın sonucu, açıkça belirtilmeye değer bir sınırdır: HotXLS, etkileşimli Excel'in yaptığı gibi bir taşmayı otomatik olarak yeniden boyutlandırmaz. Excel, girdileri değiştikçe taşan bölgeyi büyütüp küçültür ve hedef hücreler dolu olduğunda #SPILL! hatası verir. HotXLS'te, SetArrayFormula'ya geçirdiğiniz dikdörtgen elde ettiğiniz dikdörtgendir, bu yüzden bunu beklediğiniz sonuca göre boyutlandırırsınız ve eğer bir işlev bağladığınızdan daha fazla satır üretirse, fazlalığın ineceği hiçbir yer yoktur
Operatörler genelinde eleman bazında dizi yayını
HotXLS, işlemin herhangi bir tarafı bir dizi olduğunda aritmetik operatörleri eleman eleman uygular. Yardımcı ApplyArrayBinaryOp, 1 boyutlu ve 2 boyutlu variant diziler üzerinde +, -, *, / ve ^ operatörlerini kapsar: bir skalar işlenen her elemana yayınlanır, iki dizinin şekli eşleşmelidir aksi takdirde işlem reddedilir ve sıfıra bölme çökmek yerine bir hata olarak yayılır. Skalar aritmetik yolu dokunulmamış olarak kalır, bu nedenle bu yalnızca işlenenlerden en az biri gerçekten bir dizi olduğunda (taşan bir aralık veya bir matris işlevi sonucu gibi) etkinleşir. Bu, bir sütuna bağlanan =D2:D13*1.1 gibi bir formülün her bir elemanı sırayla çarptığı ve =D2:D13*E2:E13 formülünün eşit şekilli iki sütunu konum konum çarptığı anlamına gelir
// Scalar broadcast: every cell of the anchor gets D(n) * 1.1.
Sheet.Range['F2:F13'].SetArrayFormula('=D2:D13*1.1');
// Two arrays of identical shape multiply element by element.
Sheet.Range['G2:G13'].SetArrayFormula('=D2:D13*E2:E13');
Book.Recalculate;
CSE dizisine karşı @ operatörü ne yapar?
HotXLS, açık bir @ işaretini canlı Excel'in satır seçen örtük kesişimi olarak değil, başvuru kesişim operatörü olarak okur. Motorda, A1:A3 @ B1:B3 iki aralığın kesiştiği tek hücreyi döndürür ve operatör ^'den daha sıkı, %'den daha gevşek bağlanır. Bununla ilgili dürüst bir not: örtük boşlukla ayrılmış kesişim formu henüz belirteçlere (tokenize) ayrılmamıştır, çünkü sözcük analizi (lexer) hala boşlukları atlar, bu nedenle kesişimi yalnızca açık @ simgesi aracılığıyla elde edersiniz
Daha derin ayrım, eski bir CSE dizi formülü ile modern bir dinamik dizi arasındadır ve HotXLS'te her ikisi de aynı bağlama mekanizmasından akar. Klasik bir dizi formülü, önceden boyutlandırılmış bir seçim üzerinde Ctrl+Shift+Enter ile girilen {=...} bloğudur; her hücre bir derlenmiş formülü paylaşır. Dinamik bir dizi ise sonucu kendi şeklini belirleyen tek bir formüldür. HotXLS bunları SetArrayFormula altında birleştirir: dikdörtgeni her zaman siz adlandırırsınız, kök derlenmiş ağaca sahiptir ve formül ister eski tarz bir matris ifadesi ister yeni bir SORT olsun, üyeler ona başvurur. Asla elde edemeyeceğiniz şey Excel'in bölgenin sessizce yeniden büyümesini sağlayan otomatik dalgalanmasıdır ve bu çizgiyi akılda tutmak iki zihinsel modelin bulanıklaşmasını önler
Dinamik dizi desteğinin durduğu yer
Sınırları bilmek sizi bir öğleden sonra hata ayıklamaktan kurtarır. SORT, varsayılan olarak artan ve düzen parametresi negatif olduğunda azalan şekilde anahtar bazında bir yönü destekler; karşılaştırma yönü, kendi anahtar sütunlarınızı Excel'e karşı test etmeye değer bir yerdir, çünkü ters çevrilmiş bir karşılaştırma başarısız olmak yerine satırları sessizce ters sırada döndürür. UNIQUE, motorun ham bir kopya sayısına güvenmek yerine önceki satırları tarayarak onayladığı her bir belirgin satırın ilk oluşumunu korur. TABLE işlevi (Durum Analizi veri tabloları) tanınır, böylece dosya aracılığıyla karşılıklı aktarılır, ancak bir yer tutucuya çözümlenir çünkü gerçek ikame sonuçları Excel'in zaten saklamış olduğu önbelleğe alınmış değerlerdir ve HotXLS durum analiz ızgarasını yeniden çalıştırmaz
Belirtilmesi gereken en keskin sınır LET işlevidir. HotXLS, LET işlevini kaydeder ve onun için bir değerlendirme yolu taşır, ancak ayrıştırıcı zaten tanımlanmış bir ad olmayan çıplak bir adı reddeder, bu nedenle =LET(x;10;x) değerlendiriciye hiç ulaşmadan ayrıştırma sırasında başarısız olur. Ayrıştırıcı bağlı adları için kapsam farkındalığı kazanana kadar LET işlevini desteklenmeyen bir işlev olarak değerlendirin. Küçük bir taşınabilirlik notu: bu örneklerdeki formül dizeleri motorun liste ayırıcısını, yani noktalı virgülü kullanır; bu nedenle formül metnini birleştirirken derlemenizin beklediği ayırıcıyı eşleştirin. XLOOKUP ve FILTER'dan SORT, UNIQUE, SEQUENCE ve XMATCH'e kadar burada ele alınan dinamik dizi işlevleri, formül referansında tam işlev kataloğunu ve her işlevin desteklenen parametre modlarını listeleyen HotXLS Delphi Excel Bileşeni'nde gönderilir