Teknik Makale

HotXLS ile Delphi'de İki Excel Çalışma Kitabının Farkını Alma

HotXLS, iki çalışma kitabını TXLSXWorkbookCompare üzerinden karşılaştırır; bu sınıf, çalışma sayfalarını ada göre eşleştirir, her çiftin doldurulmuş hücrelerinde gezinir ve neyin farklılaştığını yapılandırılmış bir fark kaydı listesi olarak ve istendiğinde her fark için okunabilir bir satır olarak bildirir. Hiçbir Excel kurulumu gerekmez ve karşılaştırma tamamen Delphi veya C++Builder'daki yüklü nesne modeli üzerinde çalışır

İhtiyaç genellikle birinin neyin değiştiğini sorduğu ilk anda ortaya çıkar. Bir finans çalışma kitabı incelemeden geri döner, bir gecelik dışa aktarma bir kod değişikliğinden sonra yeniden üretilir veya iki departman aynı şablonun sürümlerini gönderir. İkisini yan yana açmak bir sayfa için işe yarar, yirmisi için başarısız olur. Dosyaları bayt bayt karşılaştırmak ise hiçbir şeye cevap vermez, çünkü aynı çalışma kitabının iki kaydı, kimsenin umursamadığı yollarla farklılaşır

Ne bir fark olarak sayılır?

Karşılaştırma sekiz tür bildirir ve küme bilinçli olarak küçüktür: eklenen veya kaldırılan bir sayfa, eklenen veya kaldırılan doldurulmuş bir hücre, değeri değişen bir hücre, formülü değişen bir hücre ve eklenen veya kaldırılan bir birleştirilmiş aralık. Her şey, temel alınan sol çalışma kitabına göre ifade edilir, bu yüzden eklenen bir öğe yalnızca sağda, kaldırılan bir öğe ise yalnızca solda var olur

Sayfalar konuma göre değil ada göre eşleştirilir. Bu yüzden çalışma sayfalarını yeniden sıralamak hiçbir fark üretmez; bu neredeyse her zaman istediğiniz davranıştır: bir kullanıcının bir sekmeyi sürüklemesi bir veri değişikliği değildir. Yalnızca bir tarafta bulunan bir sayfa, içindeki her doldurulmuş hücreyi genişletmek yerine tek bir sayfa düzeyinde girdi bildirir; bu, yapısal olarak farklı iki çalışma kitabının raporunu binlerce satır yerine okunabilir tutar

Değer mi formül mü ve her biri nasıl karşılaştırılır?

Her hücre bir imza katkısında bulunur ve kural basittir: bir formül taşıyan hücre, başında eşittir işareti olan formül metnine göre karşılaştırılır, formülü olmayan bir hücre ise metne dönüştürülmüş değerine göre karşılaştırılır. Bu ayrım ilk göründüğünden daha önemlidir. İki hücre, biri sabit değer diğeri formül olsa bile aynı görüntülenen sayıyı taşıyabilir ve bunları eşit saymak, incelenen bir çalışma kitabında yakalanmaya en değer olan düzenlemeyi tam olarak gizlerdi

Bu aynı zamanda, metni değişmemiş bir formülün, önbelleğe alınmış sonucu farklı olsa bile hiçbir fark bildirmediği anlamına gelir; bu, yazılmış içeriği karşılaştırmak için doğru davranıştır ve yeniden hesaplama kaymasını (drift) tespit etmeye çalışıyorsanız yanlış davranıştır. O ikinci soru için, karşılaştırmadan önce her iki çalışma kitabını da yeniden hesaplayın, böylece karşılaştırdığınız değerler formüllerin bugün gerçekten ürettiği değerler olur

Bir karşılaştırma çalıştırmak

Compare, iki yüklü çalışma kitabını alır ve bulunan fark sayısını döndürür. Fark listesi ardından indekse göre kullanılabilir veya herhangi bir TStrings'e dökülebilir:

uses
  lxHandleX, lxCompare;

var
  Left, Right: TXLSXWorkbook;
  Cmp: TXLSXWorkbookCompare;
  Lines: TStringList;
begin
  Left := TXLSXWorkbook.Create;
  Right := TXLSXWorkbook.Create;
  Cmp := TXLSXWorkbookCompare.Create;
  Lines := TStringList.Create;
  try
    if (Left.Open('baseline.xlsx') <> 1) or
       (Right.Open('reviewed.xlsx') <> 1) then
      Exit;

    if Cmp.Compare(Left, Right) = 0 then
      Writeln('workbooks are equivalent')
    else
    begin
      Cmp.Report(Lines);              // fark başına okunabilir bir satır
      Lines.SaveToFile('workbook-diff.txt');
      Writeln(Format('%d difference(s) written', [Cmp.Count]));
    end;
  finally
    Lines.Free;
    Cmp.Free;
    Right.Free;
    Left.Free;
  end;
end;

Report tarafından üretilen bir satır, value changed: Data!A2: 10 -> 99 şeklinde okunur; bu bir incelemeci için yeterlidir ve bir commit mesajı için de yeterlidir. Bu, insana yönelik yüzeydir. Programatik yüzey ise fark kaydının kendisidir ve karşılaştırma bir belgeyi değil bir kararı beslediğinde kullanılması gereken budur

Yapılandırılmış farklardan mantık yürütmek

Her fark; türünü, sayfa adını, hücre düzeyi girdiler için bir tabanlı satır ve sütunu, birleştirme düzeyi girdiler için bir A1 referansını ve sol ile sağ metni açığa çıkarır. Sayfa düzeyi ve birleştirme düzeyi girdiler, satır ve sütunu sıfır olarak bildirir; bunları türü incelemeden ayırt etmenin yolu budur:

var
  I: Integer;
  D: TlxCompareDiff;
  FormulaEdits: Integer;
begin
  FormulaEdits := 0;
  for I := 0 to Cmp.Count - 1 do
  begin
    D := Cmp.Diff(I);
    case D.Kind of
      lckFormulaChanged:
        begin
          Inc(FormulaEdits);
          Writeln(Format('%s R%dC%d: %s => %s',
            [D.Sheet, D.Row, D.Col, D.LeftText, D.RightText]));
        end;
      lckSheetAdded, lckSheetRemoved:
        Writeln(Format('structure: %s', [D.Describe]));
      lckMergeAdded, lckMergeRemoved:
        Writeln(Format('layout: %s at %s', [D.Describe, D.Ref]));
    end;
  end;

  // Yalnızca formül düzenlemelerinde engelleyen bir inceleme ilkesi
  if FormulaEdits > 0 then
    raise Exception.CreateFmt(
      '%d formula change(s) need sign-off', [FormulaEdits]);
end;

Ona karşı iddialar (assertion) yazmadan önce çıktının iki özelliğini bilmeye değer. Hücre düzeyi girdilerin sırası, hücre deposunun dahili gezinme sırasını izler, bu yüzden testler sıradan bağımsız yazılmalıdır. Ve formül imzası kendi baş eşittir işaretini taşır, bu da birleştirme (concatenation) ile oluşturulan bir açıklama dizesinin ikili bir == gösterebileceği anlamına gelir; sonuç mantığı yönlendirdiğinde açıklama satırını ayrıştırmak yerine alan değerlerini denetleyin

Çalışma kitabı farkının nerede işe yaradığı

Üç kullanım bu özelliği tek başına haklı çıkarır. Bir rapor üretecinin regresyon testi: bilinen iyi bir çalışma kitabını tutun, yeniden üretin, karşılaştırın ve beklenmeyen herhangi bir farkta derlemeyi (build) başarısız kılın. Değişiklik incelemesi: bir incelemeciye iki dosya yerine okunabilir raporu verin. Ve geçiş (migration) doğrulaması: bir grup eski çalışma kitabını dönüştürdükten sonra, hiçbir şeyin kaybolmadığını kanıtlamak için her sonucu kaynağıyla karşılaştırın

O üçüncü durum, çalışma kitabı denetimi ve dönüştürme çalışma tezgahı yazısında anlatılan envanter ve denetim geçişleriyle doğal olarak eşleşir; burada bir çalışma kitabının neler içerdiğini saymak dönüşümden önce, karşılaştırma ise sonra gerçekleşir. Farklarınız eklenen satırlar etrafında kümeleniyorsa, ekleme ve silmede formül referansı düzeltmesi yazısındaki referans yeniden yazma kuralları, değişmemiş görünen formüllerin neden değişmiş olarak bildirildiğini açıklar

Sınırlar, açıkça belirtilmiş

Karşılaştırma; değerleri, formülleri, birleştirmeleri ve sayfa varlığını kapsar. Sayı biçimlerini, yazı tiplerini, dolguları, koşullu biçimlendirme kurallarını, veri doğrulamalarını, grafikleri, görüntüleri veya tanımlı adları karşılaştırmaz. Değeri aynı olan ama biçimi Genel'den Para Birimi'ne değişen bir hücre hiçbir fark bildirmez; bu, bir veri karşılaştırması için doğrudur ve bir biçimlendirme incelemesi için yetersizdir

Tarih değerli hücreler özel bir uyarıyı hak eder: metin dönüşümleri olarak karşılaştırılırlar, bu yüzden 1904 tarih sisteminde saklanan bir çalışma kitabı ile 1900 sisteminde saklanan bir çalışma kitabı, temel alınan seri numaraları farklıysa sizi şaşırtacak şekillerde eşit veya eşit değil olarak karşılaştırılabilir. Tarih sistemi kuralları tarih seri numaraları ve 1904 sistemi yazısında ele alınmıştır. Biçimlendirme veya nesne düzeyi sadakat sorunun bir parçası olduğunda, farkı, her iki taraftaki bu özellikleri sayan bir denetim geçişiyle birleştirin

Çalışma kitabı karşılaştırması, denetimi ve dönüştürmesinin hepsi Delphi ve C++Builder için aynı motor üzerinde çalışır; eksiksiz özellik listesi HotXLS Delphi elektronik tablo bileşeni sayfasındadır