Git
C#
Mercurial
Excel
diff

Excelファイルを比較するツールを作ってみた

はじめに

Excelファイルの比較にはWinMergexdocdiffのプラグインを入れて使っていたのですが、
列が揃ってなかったり、ヘッダを固定できなかったりと少し不便に感じていました。
そんなわけでExcelファイルを比較するツールを自作してみたので、紹介と使い方を書いていこうと思います。

注意

このツールは筆者の仕事環境において必要最低限の要件で作成しています

インストール

ここ から最新の.msiをダウンロードする

SnapCrab_NoName_2017-10-29_16-4-52_No-00.png

ダウンロードしてインストーラーを実行する

※電子署名をしていないので、以下のウィンドウが表示されると思います。「詳細」→「実行」で実行できます。

Nextを選択

インストールするディレクトリと、ユーザーを選択 (特に指定がなければそのままNext)

Nextを選択

起動方法

 ショートカットアイコン

インストールが完了すると、デスクトップにショートカットアイコンが作成されるので、起動して上部メニューの「ファイル」から比較するファイルを選択する

エクスプローラのコンテキストメニュー

エクスプローラでファイルを選択した状態でコンテキストメニューを開き、ExcelMergeを選択する

コマンドライン

コマンドラインからオプションを指定して起動することもできます
オプションに関しては README を参照してください

使い方

差分を抽出する

ファイルを選択している状態で「差分抽出」を実行することで選択中のシートの比較結果が表示されます。

コンテキストメニューやコマンドラインから起動した場合、差分が抽出可能であれば自動で抽出されます。

列ヘッダ、行ヘッダを変更する

デフォルトで列ヘッダは0行目の内容が、行ヘッダは行のインデックスが表示されます。
変更するには変更したい行、または列の任意のセルを選択した状態でコンテキストメニューを開き「列ヘッダに設定」または「行ヘッダに設定」を選択します

デフォルトで表示されている行インデックスから「氏名」に変更する場合

ファイルごとに設定を作成する

毎回列ヘッダや行ヘッダを設定するのは面倒なので、事前にファイルごとに設定を行います
上部メニューの「設定」から「ファイル設定」を選択し、追加ボタンを選択します

設定を追加します

  • 「名前」はファイル名か正規表現で記述します
  • 「行ヘッダインデックス」は-1で行インデックスが表示されます
  • 「行ヘッダ」名は「行ヘッダインデックス」が指定しにくい場合などに、列ヘッダの名前で指定します。※同じ列ヘッダ名が複数存在するときは最初に一致したものを表示します
  • ファイル名を指定した場合は完全一致をチェックします

バージョン管理ツールのDiffツールとして使用する

外部ツールを登録する

バージョン管理ツールのDiffツールとして使用する場合、テキストファイルや画像ファイルなどは通常のDiffツールで開く必要があるので、
サポート対象外のファイルの場合に起動する外部ツールを登録する必要があります。
※ここではWinMergeを外部ツールとして登録します

上部メニューの「設定」から「外部コマンド」を選択し、追加ボタンを選択します

  • 「名前」はこのコマンドの名前を登録します。コマンドラインから起動する際に指定されます
  • 「実行ファイル」は実行するexeなどのパスを指定します
  • 「引数」には実行ファイルに渡す引数を指定します

利用可能な変数

変数 説明
${SRC} 右側のファイルパス
${DST} 左側のファイルパス

Gitの外部ツールとして登録する

.gitconfigにdiffツールを追加します

.gitconfig
[diff]
tool = WinMerge

[difftool "WinMerge"]
cmd = \"C:/Project/Github/excelmerge/ExcelMerge.GUI/bin/Debug/ExcelMerge.GUI.exe\" diff -s \"$LOCAL\" -d \"$REMOTE\" -c WinMerge -i -w -v -k 
  • -c で先ほど登録した外部ツール(WinMerge)を指定しています
  • -i で .xls .xlsx .csv 以外のファイルの場合はダイアログなしで外部ツールが起動するように指定しています
  • -v で拡張子のチェックをします (-v 指定がないと例外が発生→外部ツール起動 となります)
  • -w で外部ツールのプロセス終了を待つようにします (プロセスを待たないと一時ファイルが削除されるため)

これでSourceTreeからも使用が可能になります

Mercurialの外部ツールとして登録する

mercurial.iniにdiffツールを追加します

mercurial.ini
[merge-tools]
excelmerge.executable = C:\Program Files (x86)\ExcelMerge\ExcelMerge.GUI.exe
excelmerge.diffargs = diff -s $parent1 -d $child -c WinMerge -i -w -v -e empty -k

[tortoisehg]
vdiff = excelmerge

[extdiff]
#extdiffはコメントアウトする
#cmd.wmdiff = C:\Program Files\WinMerge\WinMergeU.exe
#opts.wmdiff = /r /e /x /ub

Gitの場合とオプションはほぼ同じですが、追加、削除のステータスのファイルを比較するときにemptyというファイル名で空のファイル名が渡されるので
-e で空のファイル名を指定しています

変更ログを出力する

コミットログなどに記載する際に、変更点をログとして出力できます。
変更点をログとして出力したいセルを範囲選択します。(全部の場合はCtrl + A)で全選択
コンテキストメニューの「ログを出力」を選択します

ログのフォーマットは「差分抽出設定」から変更可能です。

ショートカットキー

キー 説明
Ctrl + → 次の変更されたセルに移動
Ctrl + ← 前の変更されたセルに移動
Ctrl + ↓ 次の変更された行に移動
Ctrl + ↑ 前の変更された行に移動
Ctrl + K 次の追加された行に移動
Ctrl + I 前の追加された行に移動
Ctrl + L 次の削除された行に移動
Ctrl + O 前の削除された行に移動
Ctrl + F セルを検索
F9 次の検索結果に一致するセルに移動
F8 前の検索結果に一致するセルに移動
Ctrl + C 選択したセルをタブ区切りでコピー(エクセルへの貼り付け)
Ctrl + Shift + C 選択したセルをカンマ区切りでコピー
Ctrl + D コンソールを表示(隠す)
Ctrl + B 選択範囲の差分をログとして出力

問題点

列の追加、削除が複数ある場合、列の並び順が想定通りにならないことがあります。
この場合、コンテキストメニューから正しい列ヘッダ(できるだけ一意なヘッダ)を指定して差分を取ると正常に表示されることがあります。

プロジェクト

プロジェクトはGitHub で公開しています

Gridはパフォーマンスを優先するため FastWpfGrid を使用しています

おわりに

今回作成したツールを実際に業務で少し使ってみましたが、
コミット前の差分確認やコンフリクトの解消にかかる時間とストレスを少し軽減できたような気がします。
最終的にはマージする機能を実装することなので、今後も更新していくつもりです。

※この記事で使用したExcelファイルは こちら のサイトを利用しました