Teknik Makale

HotXLS Arama Taramaları ve Sahte Döngüsel Başvurular

=VLOOKUP(A1,B:B,1) formülünü B sütunundaki bir hücreye koyun ve Excel şikâyetsiz hesaplar. Aynı çalışma kitabını bir bağımlılık grafiği yeniden hesaplama motoruna verin ve büyük olasılıkla bir döngüsel başvuru hatası alırsınız; çünkü formül, formülü içeren bir aralığa bağımlıdır. HotXLS tam olarak bunu v2.361.98'e kadar bildirdi. Düzeltme, tüm sütun aralıkları için özel bir durum değildir; bir elektronik tablo motorunun gereksinim duyduğu ve düz yönlü bir grafiğin bulunmadığı iki bağımlılık kenarı türü arasındaki ayrımdır

Arama ailesinin arama dizisi argümanı —LOOKUP, MATCH, HLOOKUP, VLOOKUP, XLOOKUP ve XMATCH— artık bir tarama başvurusu olarak işaretlenir. Bir tarama başvurusu kirliliği yine de tohumlar, yani aralık içindeki bir hücreyi düzenlemek formülü yeniden hesaplatır, ama hiçbir zaman döngü saptamasına ya da değerlendirme sıralamasına katkı vermez. Gerçek döngüler yine bulunur; sahte olanlar gitmiştir

Excel bir arama aralığının formülü içermesine neden izin verir?

Çünkü o argüman, bir aritmetik işlenenin tüketildiği şekilde tüketilmez. Arama ailesi, aralığı önbelleğe alınmış değerler için tarar ve bir eşleşme döndürür; aralığın önce tamamlanmış olarak değerlendirilmiş olmasını gerektirmez. Excel, kendi üstüne binen bir arama aralığını, o hücrelerin şu anda tuttuğu her şeyi okumak olarak ele alır; bu, her yinelemesiz çalışma kitabına uyguladığı anlam ile aynıdır: bu geçişte yeniden hesaplanmamış hücreler son hesaplanan değerlerini verir

Tüm sütun başvuruları bunu egzotik değil olağan durum kılar. Satırların eklendiği bir sayfada "arama tablosunun tamamı" yazmanın deyimsel yolu B:B'dir ve B sütununda yaşayan her formül bundan sonra kendi arama aralığının içindedir. Finansal modeller, mutabakat sayfaları ve denetim çalışma kitapları bunu sürekli yapar; genellikle aralığın üst üste bindiğini kimse fark etmeden

B7 hücresi VLOOKUP(A1,B:B,1) formülünü kendi tüm sütunluk B:B arama aralığının içinde tutar; Excel, kendi üstüne binen bu örtüşmeyi önbelleğe alınmış değerlerden şikâyetsiz hesaplar
Tüm sütunluk arama aralıkları, kendi üstüne binmeyi finansal modellerde ve denetim çalışma kitaplarında egzotik bir köşe değil olağan durum kılar

Bir bağımlılık grafiği aynı formülle ne yapar

HotXLS artımlı olarak yeniden hesaplar; bu, gerçek bir bağımlılık grafiği gerektirir: hücreler için düğümler, başvurular için kenarlar, değerlendirme için bir topolojik sıra ve döngüleri sınıflandırmak için bir güçlü bağlı bileşen geçişi. O makine artımlı yeniden hesaplama makalesinde betimlenir ve sahte pozitifin ortaya çıkmasının nedeni de tam olarak budur

B7 hücresindeki =VLOOKUP(A1,B:B,1) formülünden bağımlılıkları çıkarın ve ikinci argüman, B7'nin kendisini içeren bir aralık verir. Grafiğin artık bir öz döngüsü vardır. O düğümün giriş derecesi hiç sıfıra ulaşmaz; dolayısıyla topolojik geçiş onu hiçbir zaman planlayamaz ve bileşen geçişi onu bir döngü olarak sınıflandırır. Motor, kendisine verilen grafik hakkında doğru akıl yürütüyor. Grafik yanlış modeldir, çünkü elektronik tabloda iki olan kenar türünden birini kodluyor

B:B arama aralığı grafik düğümü B7'ye bir öz döngü verir; giriş derecesi hiç sıfıra ulaşmaz ve v2.361.98 öncesi HotXLS sahte bir döngüsel başvuru bildirir
Yeniden hesaplama motoru, kendisine verilen grafik hakkında doğru akıl yürüttü; grafik, bir elektronik tablo için yanlış modeldi

İki kenar sınıfı, tek grafik

Değişiklik, çözümlenmiş başvuru kaydına bir bayrak ekler: TXLSDepRange.LookupScan; bağımlılık çıkarıcısı altı işlevden birinin arama dizisi argümanında yürürken onu ayarlar. Aşağı akışta o başvurulardan kaynaklanan kenarlar sıradan kenarlardan ayrı saklanır: grafik düğümü, normal bağımlı ve öncül listelerinin yanında ScanDependents ve ScanPrecedents listelerini tutar

Ayrım, anlamı doğru kılan şeydir. Tarama kenarları kirli yayılımı ile dolaşılır, yani B:B içindeki bir düzenleme B7'yi yine kirli işaretler ve B7 yeniden hesaplar. Tarama kenarları hiçbir zaman giriş derecesine sayılmaz ve bileşen kurucusuna hiç girmez; dolayısıyla topolojik bir kilitlenme üretemezler ve bir döngü olarak sınıflandırılamazlar. Kitaplıktaki her iki grafik uygulaması da —klasik çalışma kitabı başına grafik ve bileşen analizini taşıyan çalışma kitapları arası çalışma alanı grafiği— birlikte değiştirildi; onların sapmasına izin vermek, tek başına mı yoksa bir çalışma alanının parçası olarak mı açıldığına göre farklı hesaplanan bir çalışma kitabı üretirdi

TXLSDepRange.LookupScan'den gelen tarama kenarları, kirli yayılımını ScanPrecedents ve ScanDependents'e yürütür ama hiçbir zaman giriş derecesine ya da döngülere sayılmaz
B:B içindeki düzenlemeler formülü yine kirli işaretler; yine de tarama kenarları topolojik geçişi kilitleyemez ya da bir döngü imal edemez
var
  Book: TXLSXWorkbook;
  Sheet: TXLSXWorksheet;
begin
  Book := TXLSXWorkbook.Create;
  try
    Sheet := Book.Sheets.Add('Ledger');
    Sheet.Cells[1, 1].Value := 'ACC-4471';
    Sheet.Cells[1, 2].Value := 1200.00;
    // Arama aralığı B sütununu kapsar ve bu formül onun içinde yaşar
    Sheet.Cells[7, 2].Formula := 'VLOOKUP(A1,B:B,1)';

    case Book.Recalculate of
      lxOk:
        // v2.361.98 öncesinde bu dal bu sayfa için ulaşılamazdı
        SaveReport(Book);
      lxErrorRef:
        LogWarning('Genuine circular reference - review model inputs');
    end;
  finally
    Book.Free;
  end;
end;

Tarama kenarlarını sıralamadan dışlamakla vazgeçtiğiniz şey

Tam olarak tek şey ve saklamak yerine açıkça söylemeye değer. Tarama kenarları topolojik sıraya katılmadığı için bir arama formülü, arama aralığındaki bazı hücreler yeniden hesaplanmadan aynı geçişte değerlendirilebilir ve onların önceki değerlerini okur. Sonuç, sonraki yeniden hesaplamada yakınsar

Bu kabul edilebilirdir, çünkü Excel'in yaptığı tam olarak budur. Yinelemeli hesaplama etkinleştirilmemiş bir çalışma kitabı için Excel'in geçerli geçişte henüz yeniden hesaplanmamış bir değere kendi cevabı, son hesaplanan değerdir; dolayısıyla bu davranışı yeniden üreten motor, referans uygulamayı yaklaşıklaştırmıyor, ona örtüşüyor. Kendine başvuran bir model üzerinde gerçekten yakınsamış bir cevaba ihtiyacınız varsa bunun mekanizması, açık bir yineleme sınırıyla yinelemeli hesaplamadır; yinelemeli hesaplama makalesinde kapsanır ve tarama örtüşmelerine değil gerçek döngülere uygulanır

Düzeltmenin içinde saklanan gerileme tehlikesi

TXLSDepRange'e LookupScan eklemek, aramalarla hiç ilgisi olmayan ama Pascal'la her şeyi olan bir risk getirdi. TXLSDepRange yönetilmeyen bir kayıttır; dolayısıyla o türden bir yerel değişken sıfırla başlatılmaz. Veri tablosu bağımlılık blokları ve birkaç test yardımcısı dahil, kod tabanında elle bir tane kuran her yerin yeni alanı açıkça ayarlayacak şekilde güncellenmesi gerekti. Birini kaçırdığınızda, yığında tesadüfen bulunan hangi bayt varsa o, o başvurunun bir tarama kenarı olarak ele alınıp alınmayacağına karar verir; bu da ilgisiz kod değişiklikleriyle beliren ve kaybolan bir yeniden hesaplama hatası üretir

// Yönetilmeyen bir kayıttaki yeni bir Boolean alanı, elle yapılan her
// kurulum noktasını gizli bir hata kılar. İki güvenli deyim:
var
  R: TXLSDepRange;
begin
  FillChar(R, SizeOf(R), 0);      // önce her şeyi sıfırla, sonra doldur
  R.Sheet1 := SheetIndex;
  R.Sheet2 := SheetIndex;
  R.Row1 := Row; R.Col1 := Col;
  R.Row2 := Row; R.Col2 := Col;

  // ya da her noktada, yenisi dahil her alanı ayarla
  R.LookupScan := False;
end;

Bunun kazandırdığı genel kural: birkaç yerden fazla yerde yığında kurulan bir kayda alan eklemek, göründüğünden daha yüksek riskli bir değişikliktir ve derleyici, noktaları bulmanıza yardım etmez. Kayıt, sıcak bir yoldan erişilebilirse her çağrı noktasının güncelleneceğine güvenmek yerine onu eksiksiz başlatan bir yardımcıyı tercih edin

Gerçek döngüyü tarama örtüşmesinden ayırt etmek

Bu değişikliğin hiçbir yanı döngü saptamasını zayıflatmaz. B7'deki =B7+1 hâlâ bir döngüdür, kendine kapanan üç formüllü bir zincir hâlâ bir döngüdür ve ikisi de, döngü üyeleri önceki önbelleğe alınmış değerlerini tutarken döngünün dışındaki her şey güncel kalacak şekilde yeniden hesaplama sonucu üzerinden bildirilmeye devam eder. Değişen tek şey, arama dizisi argümanının artık Excel'in görmediği döngüleri imal etmemesidir

Bir çalışma kitabını denetliyorsanız ve motorun gerçekte hangi başvuruları hangi sırayla çözdüğünü bilmek istiyorsanız değerlendirme izleyicisi bunun aracıdır; formül değerlendirme izleyicisi makalesi çıktısının nasıl okunacağını kapsar. HotXLS, Excel kurulu olmadan XLS, XLSX, ODS ve CSV okuyup yazan yerel bir Delphi ve C++Builder elektronik tablo bileşenidir ve yeniden hesaplama motoru her biçimde aynıdır; güncel işlev ve motor kapsamı HotXLS Delphi spreadsheet component ürün sayfasında listelenir