Skip to content

rakima/compare_tool

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

75 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

compare_tool

2つの .xlsx.xls.xlsm.csv.json.xml ファイルを比較し、比較結果をExcelファイルとして出力するGUIツールです。元ファイルは変更しません。

compare_tool 起動画面

セットアップと起動

Python 3.10以降で次を実行してください。

python -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install -e ".[test]"
compare-tool

または python -m compare_tool でも起動できます。

機能

  • Excelのセル値、保存済み数式文字列、シート追加・削除の比較
  • .xls をExcelで一時 .xlsx に変換して比較
  • .xlsm をExcelブックとして比較
  • CSVのセル座標形式での比較
  • JSONのJSON Path形式での比較
  • XMLのXPath風パス形式での比較
  • CSVの文字コード・区切り文字指定
  • CSV空行の無視オプション
  • JSONのキー順・配列順序オプション
  • セル座標比較、行追加/削除を考慮した比較、キー列指定比較
  • 行追加、行削除の検出
  • 空文字、空白、大文字小文字の正規化オプション
  • 詳細一覧またはサマリーのみの結果シート
  • 変更セルを黄色、追加セルを緑で表示
  • 詳細一覧から変更・追加セルへの内部リンク
  • ファイル選択およびドラッグ&ドロップ
  • 旧/新ファイルの入れ替え、ファイル履歴クリア
  • 比較中キャンセル
  • 比較完了後の出力ファイル/保存フォルダオープン

数式の再計算は行いません。「セル値を比較」はファイル内に保存済みの計算結果を使用します。Excelで未計算の数式は、数式比較をONにして確認してください。

CSV比較では、CSVを CSV という1シートの表として扱い、結果は .xlsx で出力します。CSVの文字コードと区切り文字は画面から指定できます。

CSV比較の出力では、比較結果シートの右側に読み込み時の文字コード、区切り文字、空行の扱いを記録します。

CSV文字コード:

  • 自動
  • UTF-8 / UTF-8 BOM
  • Shift_JIS

自動 はBOMを確認し、BOMがない場合はUTF-8、Shift_JISの順に読み取りを試します。

CSV区切り文字:

  • 自動
  • カンマ
  • タブ
  • セミコロン

自動 は先頭行をカンマ、タブ、セミコロンで読み比べ、列数が多く安定している区切り文字を選びます。

CSV空行は既定で無視します。空行自体を差分として確認したい場合は CSV空行を無視 をOFFにしてください。

JSON比較では、JSONをJSON Path単位で比較し、結果は .xlsx で出力します。新JSONの内容は JSON シートに整形して出力します。

JSON比較では、オブジェクトのキー順は既定で無視します。キー順自体を差分として確認したい場合は オブジェクトのキー順を無視 をOFFにしてください。

配列は既定ではインデックス順に比較します。要素の並び替えだけを差分にしたくない場合は 配列の順序を無視 をONにしてください。この場合、同じ要素は相殺し、旧JSONにだけ残る要素は削除、新JSONにだけ残る要素は追加として出力します。

オブジェクト配列は JSON配列キーidname などのキー名を指定すると、そのキー値で要素を対応付けて比較できます。配列の順序が変わっても同じキーの要素として比較するため、APIレスポンスやマスターデータのようなJSONで差分が見やすくなります。指定したキーの値が同じ配列内で重複している場合は、誤対応を避けるため比較を停止します。

比較位置は次のようなJSON Pathで表します。

  • $.name
  • $.items[0].price
  • $.items[id="P002"].price
  • $.settings.enabled

検出する差分:

  • 値変更
  • キー追加
  • キー削除
  • 配列要素追加
  • 配列要素削除

XML比較では、XMLをXPath風パス単位で比較し、結果は .xlsx で出力します。新XMLの内容は XML シートに整形して出力します。

子要素は XML要素キー属性id 属性、name 属性、同じ内容のLCSの順に対応付けます。XML要素キー属性code などの属性名を指定すると、その属性値で同じ親要素内の子要素を対応付けます。未指定の場合は id / name を自動使用します。途中に要素が追加・削除されたり、キー付き要素の順序が変わったりしても、後続要素がまとめて変更扱いになりにくい表示にしています。

比較する内容:

  • 要素追加
  • 要素削除
  • テキスト変更
  • 属性追加
  • 属性削除
  • 属性値変更

比較位置はXPath風のパスで表します。

  • /root/name
  • /root/items/item[1]/price
  • /root/settings/@enabled
  • /root/p:item[1]/p:name[1]

同じタグで中身だけが違う子要素は変更として表示します。タグ自体が違う子要素は、削除と追加として表示される場合があります。これはXMLの構造変更を見つけやすくするためです。

キー属性で対応付けるのは、同じ親要素内でキーが一意な場合のみです。キーが重複している場合は誤対応を避けるため、通常のLCS比較へ戻します。

名前空間付きの要素や属性は、XML内のprefixを使って p:item@p:code のように表示します。prefixのない既定名前空間は、読みやすさを優先してローカル名で表示します。

XML専用オプション:

  • 属性順を無視
    • 既定ON
    • XMLでは属性順に意味がないため、通常は差分にしません。
  • 空白のみのテキストを無視
    • 既定ON
    • インデントや改行だけの差分を抑えるため、空白のみのテキストノードは比較対象から外します。

比較方式

セル座標比較

同じシート名、同じセル座標の値または数式を比較します。もっとも単純で高速な方式です。

行追加や行削除がある場合は、後続行が大量の変更として検出されることがあります。

行追加/削除を考慮

行全体の内容から同じ行をLCSで対応付け、対応できなかった行を 行追加 / 行削除 として検出します。

行全体が同じ場合に強く、単純な行挿入や行削除で後続行が大量変更になるのを抑えられます。一方で、行内の一部セルが変わった行は同じ行として対応できない場合があります。

キー列で比較

指定した列の値をキーとして行を対応付けます。行の並び替えや移動があっても、同じキーの行として比較できます。

キー列は A または A,C のような列記号、または 商品ID のような1行目のヘッダー名で指定します。A1 のようなセル座標は指定できません。キー列入力欄は、比較方式で キー列で比較 を選んだときだけ有効になります。キー値が重複している場合は、誤対応を避けるため比較を停止します。

設計

Comparer が形式非依存の比較戦略、Difference / CompareResult が共通結果モデルです。Excel固有処理は ExcelReaderExcelComparerExcelReportWriter、CSV固有処理は CsvReaderCsvComparerCsvReportWriter、JSON固有処理は JsonReaderJsonComparerJsonReportWriter、XML固有処理は XmlReaderXmlComparerXmlReportWriter に分離しています。GUIは CompareUseCase のみを呼び出します。

入力Excelは WorkbookPreparer を通してから比較します。.xlsx / .xlsm はそのまま比較し、.xls はWindows版Excelを使って一時 .xlsx に変換してから既存のExcel比較処理へ渡します。

テスト

python -m pip install -e ".[dev]"
python -m ruff check .
python -m ruff format --check .
python -m mypy
python -m pytest -q

手動確認用のExcel/CSV/JSON/XMLサンプルは次のコマンドで samples フォルダに作成できます。

python tools\create_sample_files.py

.xlsx.csv.json.xml のサンプルはPythonだけで作成できます。.xls / .xlsm サンプルは、作成した .xlsx サンプルをWindows版Excelで保存し直して作成します。Excelまたはpywin32が使えない環境では、.xls / .xlsm サンプルだけスキップされます。

XMLサンプルには code 属性で対応付ける確認用要素も含まれます。XML比較で XML要素キー属性code を指定すると、順序が変わった要素を code 値で対応付けて比較できます。

同じ品質チェックはGitHub ActionsでもPython 3.10/3.12(Windows)に対して自動実行されます。

大容量・疎なExcelの性能回帰テストは、通常テストと分けて次のコマンドで実行できます。

python -m pytest -m performance -q

GitHub Actionsでは毎週日曜日3時(日本時間)に実行され、必要なときは手動でも開始できます。

Windows向け配布

PyInstallerで単体の実行ファイルを作成できます。

python -m pip install -e ".[dev]"
python -m PyInstaller compare_tool.spec --noconfirm --clean

作成された実行ファイルは dist\compare_tool.exe です。配布前には、別フォルダへコピーして起動し、サンプルExcel/CSV/JSON/XMLで比較できることを確認してください。.xls 対応を確認する場合は、Windows版Excelが入っている環境で .xls の旧/新サンプルを比較し、比較結果 .xlsx が出力されることと、元の .xls が変更されないことを確認してください。

GitHub Actionsの Build Windows App は手動実行、または v* タグのpushでWindows実行ファイルをビルドし、compare_tool-v<version>-windows artifactとして保存します。

v* タグのpush時は、compare_tool-v<version>-windows.zip をGitHub ReleaseのAssetsにもアップロードします。zipには compare_tool.exeREADME.mdLICENSEdocs が含まれます。

リリース前の確認項目は docs/RELEASE_CHECKLIST.md にまとめています。

既知の制限

現在、実際に比較できる対象は .xlsx / .xls / .xlsm のExcel同士、.csv 同士、.json 同士、または .xml 同士です。.xls の比較にはWindows版Excelが必要です。

.xlsx.csv.csv.json.json.xml のように異なる形式同士の比較には対応していません。

Excelの比較対象はセル値、数式文字列、行追加、行削除、シート追加、シート削除です。書式、コメント、図形、画像、行高、列幅、テーブル定義、VBA/マクロは比較しません。.xlsm の比較結果も .xlsx として出力します。出力ファイルにはVBA/マクロは含まれません。

CSVの比較対象は各フィールドの文字列です。文字コード、区切り文字、空行の扱いは比較オプションで指定します。

JSONの比較対象は値、キー、配列要素です。配列は既定ではインデックスで比較します。配列の順序を無視 をONにすると、同じ要素の並び替えは差分にしません。JSON配列キー を指定すると、オブジェクト配列をキー値で対応付けます。

XMLの比較対象は要素、テキスト、属性です。属性順は既定で無視し、空白のみのテキストも既定で無視します。XML要素キー属性 を指定すると、同じ親要素内の子要素を属性値で対応付けます。

行追加/削除を考慮 は、行全体が同じ場合の対応付けを目的にした初期版です。行内の一部セルが変わった行の対応付けには、キー列比較を推奨します。

キー列で比較 は、キー値が空の行を対応付け対象から除外します。キー値が重複している場合は比較を停止します。ヘッダー名で指定した場合は、旧/新それぞれの1行目から該当ヘッダーを探してキー列として使用します。

数式の再計算は行いません。数式の計算結果はExcelファイル内に保存済みの値を使用します。

JSONの配列LCS対応、JSON Lines、JSON5、スキーマ比較は将来検討とします。

XMLのコメント、処理命令、DTD/XSD検証、名前空間URIの高度な正規化、XML整形差分は対象外です。

よくあるエラー

  • 旧ファイルと新ファイルに同じファイルが指定されています。: 異なる2つのExcelファイルを指定してください。
  • .xlsx、.xls、.xlsm、.csv、.json、.xml のいずれかを指定してください。: 入力ファイルには対応している拡張子のファイルを指定してください。現時点で実際に比較できるのは .xlsx / .xls / .xlsm のExcel同士、.csv 同士、.json 同士、または .xml 同士です。
  • 旧ファイルと新ファイルは同じ形式を指定してください。: .xlsx.csv のような異なる形式同士の比較には対応していません。
  • .xls ファイルをExcelで .xlsx に変換できませんでした。: .xls ファイルが破損していないか、パスワード付きではないか、Windows版Excelで開けるか確認してください。
  • CSVファイルの文字コードを自動判定できません。: 対応している自動判定候補はUTF-8 / UTF-8 BOM / Shift_JISです。別の文字コードのCSVはUTF-8またはShift_JISで保存し直してください。
  • CSVファイルを ... として読み取れません。: CSV文字コードの指定が実際のファイルと異なる可能性があります。自動 で失敗する場合は UTF-8 / UTF-8 BOM または Shift_JIS を選び直してください。
  • CSVファイルの形式を読み取れません。: 引用符や改行を含むフィールドが壊れている可能性があります。Excelなどで開けるか確認し、必要ならCSVとして保存し直してください。
  • CSV区切り文字は1文字で指定してください。: CSV区切り文字には自動、カンマ、タブ、セミコロンを指定してください。区切り文字が違うと、列が分かれず正しい差分にならないことがあります。
  • JSONファイルの形式を読み取れません。: 表示された行・列付近でJSON構文が壊れている可能性があります。カンマ、引用符、コロン、括弧の対応を確認してください。
  • JSONファイルをUTF-8として読み取れません。: JSONをUTF-8 / UTF-8 BOM付きで保存し直してから再実行してください。
  • XMLファイルの形式を読み取れません。: 表示された行・列付近でXML構文が壊れている可能性があります。開始タグと終了タグの対応、属性の引用符、特殊文字のエスケープを確認してください。
  • XMLファイルをUTF-8として読み取れません。: XMLをUTF-8 / UTF-8 BOM付きで保存し直してから再実行してください。
  • Excelファイルが破損しているか、読み取れません。: Excelで開けるか確認し、必要なら別名保存してから再実行してください。
  • パスワード付きExcelは比較できません。: パスワードを解除したコピーを指定してください。
  • 出力ファイルを保存できません。: 出力先ファイルをExcelで開いていないか、保存先フォルダへ書き込めるか確認してください。
  • キー列比較ではキー列を指定してください。: 比較方式に キー列で比較 を選んだ場合は、キー列に AA,C商品ID などを指定してください。
  • キー列は列記号または1行目のヘッダー名を指定してください。: A1 のようなセル座標ではなく、A のような列記号、または1行目のヘッダー名を指定してください。
  • 1行目にキー列ヘッダー ... が見つかりません。: ヘッダー名で指定したキー列が旧/新どちらかの1行目に存在しません。表記揺れや空白を確認してください。
  • キー列 ... の値が重複しています。: キー値が重複しているため、どの行同士を比較すべきか決められません。キー列を変更するか、重複を解消してください。
  • .xlsm のVBA/マクロが出力に含まれません。: .xlsmはセル値・数式のみ比較します。比較結果は.xlsx` で作成するため、VBA/マクロは出力対象外です。

About

Desktop GUI tool for comparing Excel and CSV files, with Excel report output.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages