HotXLS palygina dvi darbaknyges per TXLSXWorkbookCompare, kuri suporuoja darbalapius pagal pavadinimą, apeina kiekvienos poros užpildytus langelius ir praneša, kas skiriasi, kaip struktūrizuotą skirtumų įrašų sąrašą, o paprašius – ir kaip po vieną skaitomą eilutę kiekvienam skirtumui. Jokia Excel diegtis nedalyvauja, o palyginimas vyksta visiškai su įkeltu objektų modeliu Delphi arba C++Builder aplinkoje
Poreikis paprastai atsiranda tada, kai kažkas pirmą kartą paklausia, kas pasikeitė. Finansų darbaknygė grįžta po peržiūros, kasnaktinis eksportas perkuriamas po kodo pakeitimo, arba du padaliniai atsiunčia to paties šablono versijas. Abu failus atidaryti greta veikia vienam lapui ir nebeveikia dvidešimčiai. Failų palyginimas baitas po baito neatsako į nieką, nes du to paties darbaknygės išsaugojimai skiriasi būdais, kurie niekam nerūpi
Kas laikoma skirtumu?
Palyginimas praneša aštuonias rūšis, ir šis rinkinys sąmoningai nedidelis: pridėtas arba pašalintas lapas, pridėtas arba pašalintas užpildytas langelis, langelis, kurio reikšmė pasikeitė, langelis, kurio formulė pasikeitė, ir pridėtas arba pašalintas sujungtas diapazonas. Viskas išreiškiama kairiosios darbaknygės kaip bazinės atžvilgiu, todėl pridėtas elementas egzistuoja tik dešinėje, o pašalintas – tik kairėje
Lapai suporuojami pagal pavadinimą, o ne pagal poziciją. Todėl darbalapių pertvarkymas iš vietos į vietą apskritai neduoda jokių skirtumų, o tai beveik visada yra tokia elgsena, kokios ir norite: vartotojas, tempiantis skirtuką, nėra duomenų pakeitimas. Lapas, esantis tik vienoje pusėje, praneša vieną lapo lygio įrašą, o ne išplečia kiekvieną jame užpildytą langelį, todėl dviejų struktūriškai skirtingų darbaknygių ataskaita lieka skaitoma, o ne tūkstančių eilučių ilgio
Reikšmė ar formulė, ir kaip kiekviena lyginama
Kiekvienas langelis suformuoja parašą, ir taisyklė paprasta: langelis su formule lyginamas pagal savo formulės tekstą su pradiniu lygybės ženklu, o langelis be jos lyginamas pagal savo reikšmę, paverstą tekstu. Šis skirtumas svarbesnis, nei atrodo iš pirmo žvilgsnio. Du langeliai gali rodyti tą patį skaičių, kai vienas yra literalas, o kitas – formulė, ir jų traktavimas kaip lygių paslėptų būtent tą redagavimą, kurį svarbiausia pastebėti peržiūrimoje darbaknygėje
Tai taip pat reiškia, kad formulė, kurios tekstas nepakito, skirtumo nepraneša, net jei jos talpykloje saugomas rezultatas skiriasi – tai teisinga elgsena lyginant sukurtą turinį, bet neteisinga elgsena, jei bandote aptikti perskaičiavimo nuokrypį. Antram klausimui perskaičiuokite abi darbaknyges prieš lygindami, kad lygintumėte reikšmes, kurias formulės iš tikrųjų duoda šiandien
Palyginimo vykdymas
Compare priima dvi įkeltas darbaknyges ir grąžina rastų skirtumų skaičių. Skirtumų sąrašas tada prieinamas pagal indeksą arba gali būti išpiltas į bet kokį TStrings:
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); // po vieną skaitomą eilutę kiekvienam skirtumui
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;
Eilutė, kurią sukuria Report, atrodo kaip value changed: Data!A2: 10 -> 99, ir to pakanka peržiūrėtojui bei pakanka commit pranešimui. Tai žmogui skirtas paviršius. Programinis paviršius yra pats skirtumo įrašas, ir jį reikia naudoti, kai palyginimas maitina sprendimą, o ne dokumentą
Logikos valdymas iš struktūrizuotų skirtumų
Kiekvienas skirtumas atskleidžia savo rūšį, lapo pavadinimą, nuo vieneto skaičiuojamą eilutę ir stulpelį langelio lygio įrašams, A1 nuorodą sujungimo lygio įrašams, bei kairįjį ir dešinįjį tekstą. Lapo lygio ir sujungimo lygio įrašai eilutę ir stulpelį praneša kaip nulį – taip juos galima atskirti netikrinant rūšies:
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;
// Peržiūros politika, blokuojanti tik dėl formulių pakeitimų
if FormulaEdits > 0 then
raise Exception.CreateFmt(
'%d formula change(s) need sign-off', [FormulaEdits]);
end;
Dvi rezultato savybes verta žinoti prieš rašant patikrinimus (assertions) prieš jį. Langelio lygio įrašų tvarka seka vidinę langelių saugyklos apėjimo tvarką, todėl testai turėtų būti rašomi nepriklausomai nuo tvarkos. Ir formulės parašas neša savo pradinį lygybės ženklą, o tai reiškia, kad sujungimu sukurta apibūdinimo eilutė gali parodyti sudvigubintą ==; kai rezultatas valdo logiką, tikrinkite lauko reikšmes, o ne analizuokite apibūdinimo eilutę
Kur darbaknygių lyginimas atsiperka
Trys panaudojimo atvejai patys savaime pateisina šią funkciją. Ataskaitų generatoriaus regresijos testavimas: laikykite žinomą tinkamą darbaknygę, perkurkite, palyginkite ir sužlugdykite kūrimą dėl bet kokio netikėto skirtumo. Pakeitimų peržiūra: paduokite peržiūrėtojui skaitomą ataskaitą vietoj dviejų failų. Ir migracijos patikrinimas: konvertavus senų darbaknygių partiją, palyginkite kiekvieną rezultatą su jo šaltiniu, kad įrodytumėte, jog nieko neprarasta
Tas trečiasis atvejis natūraliai dera su inventorizacijos ir audito perėjimais, aprašytais straipsnyje darbaknygių audito ir konvertavimo darbastalis, kur darbaknygės turinio suskaičiavimas vyksta prieš konvertavimą, o palyginimas – po jo. Jei jūsų skirtumai telkiasi apie įterptas eilutes, nuorodų perrašymo taisyklės straipsnyje formulių nuorodų koregavimas įterpiant ir šalinant paaiškina, kodėl nepakitusiomis atrodančios formulės praneša kaip pakitusios
Ribos, pasakytos tiesiai
Palyginimas apima reikšmes, formules, sujungimus ir lapų buvimą. Jis nelygina skaičių formatų, šriftų, užpildų, sąlyginio formatavimo taisyklių, duomenų tikrinimo, diagramų, vaizdų ar apibrėžtų vardų. Langelis, kurio reikšmė identiška, bet formatas pasikeitė iš General į Currency, skirtumo nepraneša – tai teisinga duomenų palyginimui ir nepakankama formatavimo peržiūrai
Datos tipo langeliai nusipelno vienos konkrečios pastabos: jie lyginami pagal savo teksto konversiją, todėl darbaknygė, saugoma 1904 metų datos sistemoje, ir kita, saugoma 1900 metų sistemoje, gali lygintis kaip lygios arba nelygios būdais, kurie nustebins, jei pagrindiniai serijos numeriai skiriasi. Datos sistemos taisyklės aprašytos straipsnyje datos serijos numeriai ir 1904 sistema. Kai formatavimo ar objektų lygio tikslumas yra klausimo dalis, sujunkite skirtumų palyginimą su audito perėjimu, kuris kiekvienoje pusėje suskaičiuoja tas funkcijas
Darbaknygių palyginimas, auditas ir konvertavimas visi veikia tame pačiame variklyje Delphi ir C++Builder aplinkoms; pilnas funkcijų sąrašas pateikiamas HotXLS Delphi skaičiuoklės komponento puslapyje