ホーム / お役立ち記事 / マクロ入りのブックを比べると全部「違う」と出る理由|VBAのコードはソースで差分比較する

Knowledge

マクロ入りの​ブックを​比べると​全部​「違う」と​出る​理由|​VBAの​コードは​ソースで​差分比較する

マクロ入りの Excel ブック(.xlsm)を何冊か比べると、マクロが同じでも vbaProject.bin のバイトは違って出ます。入れ物には保存のしかたで変わってよい値が入るためです。お客様から受け取った6冊でも、バイトは全部違い、ソースは同じでした。原因の切り分け、VBA のコードの差分比較をモジュールごとのソースで行う手順、落とし穴、比べ方が正しいかの確かめ方を、弊社の実測と公開の仕様でまとめます。

著者: 村山 悠太(ゴムマリ) 最終更新: 2026年11月

マクロ入りの Excel ブック(.xlsm)を何冊か受け取り、マクロが同じかをファイルの比較で確かめると、マクロが同じでも「違う」と出ることがあります。

マクロの入れ物の vbaProject.bin には、ソースのほかに、保存のしかたで変わってよい値が入るためです。

マクロが同じかは、vbaProject.bin のバイトではなく、モジュールごとに取り出した VBA のソースで比べます。弊社がお客様から受け取った6冊でも、vbaProject.bin のバイトは全部違い、ソースで比べると同じでした。

この記事は、マクロ入りのブックを何冊も引き継ぐ・1つにまとめる業務の担当者・情報システムの担当者に向けて書きます。

原因の切り分け、見分け方、比べ方、落とし穴、比べ方が正しいかの確かめ方を、弊社が作ったブックでの実測(2026年11月1日)と、Microsoft の公開の仕様で整理します。

原因: vbaProject.bin は、​マクロが​同じでも​バイトが​変わる​入れ物

.xlsm は ZIP で、マクロは xl/vbaProject.bin という1つの部品に入っています。この部品は、中にさらに「プロジェクトの情報」「モジュールごとのソース」などの小さな部品を持つ入れ物です。

Microsoft が公開している VBA のファイルの仕様(MS-OVBA)によると、この入れ物には、ソースのほかに次の2種類の値が入ります。

  • プロジェクトの識別子と、保護・パスワード・表示の状態保護・パスワード・表示の3つは、暗号化した文字列で書かれます(MS-OVBA 2.3.1.15〜2.3.1.17・2.4.3)。
  • 版に依存する写し仕様は、Office が VBA の版に依存する写し(performance cache)を持ち、版が一致すればそれを使う、と説明しています(MS-OVBA 1.6)。

どちらも、マクロのソースとは別の値です。ソースが同じでも、vbaProject.bin のバイトが同じになるとは限りません。

そのため、vbaProject.bin のハッシュや大きさが違うことは、マクロが違う証拠になりません。

弊社の​実測: 同じ​マクロを​3回保存すると、​3冊とも​バイトが​違った

弊社は、同じ VBA のモジュール2本を入れたブックを3冊作りました。2冊は別々に新しく作って保存し、1冊は1冊目を開いて保存し直しただけです。

項目 内容
実測の日 2026年11月1日
ブックを作った道具 LibreOffice 26.2.4.2(macOS 27.0)
比べた道具 oletools 0.60.2 の olevba(Python 3.14.6)
ブック 同じソースのモジュール2本を入れた .xlsm を3冊

結果は、3冊とも vbaProject.bin のバイトが違い、olevba で取り出したソースは3冊とも同じでした。vbaProject.bin の大きさは、3冊とも5,120バイトで同じでした。

別々に作った2冊では、違いはプロジェクトの情報の部品の中だけでした。プロジェクトの識別子と、保護・パスワード・表示の状態を暗号化して書いた3つの文字列が、保存ごとに違いました。ソースの入った部品は同じでした。

開いて保存し直しただけの1冊では、ソースの入った部品のバイトも違いました。取り出して比べると、ソースの末尾に空の行が1行増えていました。

この試しは、LibreOffice で保存したブックだけで行いました。Excel で保存したときに、どの部品がどれだけ変わるかは、弊社は確かめていません。

お客様の​6冊でも、​バイトは​全部​違い、​ソースは​同じだった

弊社がお客様から受け取ったマクロ入りのブック6冊でも、vbaProject.bin を比べると、6冊ともバイトが違いました。

olevba でモジュールごとのソースを取り出して比べると、モジュールは名前もソースも6冊とも同じでした。

バイトの違いだけを見ると、同じマクロが6通りあるように見えます。様式を1つにそろえるかどうかの判断は、ソースで比べてから行います。

見分け方​: 違うのは​入れ物か、​ソースか

「マクロが違う」と出たときは、何で比べたかを先に確かめます。比べ方ごとに、分かることが違います。

比べ方 分かること
ファイル全体のハッシュ・大きさ ブックのどこかが違う。マクロが違うかは分からない
vbaProject.bin のハッシュ・大きさ マクロの入れ物のどこかが違う。マクロが違うかは分からない
モジュールごとのソース マクロのコードが同じか

大きさも当てになりません。弊社が古い形式のブックを .xlsm に変えたとき、vbaProject.bin は LibreOffice で変えた版が8,704バイト、Excel で保存した版が30,720バイトでした。

この2つをソースで比べると、違いは Attribute の行の有無だけでした。

ソースで比べて違いが出たら、次の順で分けます。

  1. モジュールの名前の組が同じか(足りない・多いモジュールがないか)
  2. 名前ごとに、改行と行末の空白をそろえ、先頭と末尾の空の行を除いたソースが同じか
  3. 違うモジュールだけ、行の差分を見る
  4. 違いが「Attribute」で始まる行だけか、コードの行にもあるか

Attribute の行は、モジュールの名前・マクロの説明・ショートカットキーの割り当てなどを書く行です。保存の道具によって落ちたり書き方が変わったりするので、コードの行と分けて見ます。

直し方​: VBA の​コードの​差分比較を、​モジュールごとの​ソースで​行う

弊社が実際に通した手順は次のとおりです。比べるのは、モジュールごとに取り出したソースです。

  1. Python の仮想環境に oletools を入れる(pip install oletools)
  2. ブックごとに、olevba でモジュールごとのソースを取り出す
  3. 改行の形(CRLF と LF)と行末の空白をそろえ、先頭と末尾の空の行を除く
  4. モジュールの名前ごとに比べ、違うモジュールだけ行の差分を出す

oletools は、Office のファイルを調べる公開の道具です。

公式の説明では、olevba は Excel 2007 以降の .xlsm に対応し、Python の VBA_Parser の extract_macros で、モジュールごとのソースを取り出せます。

次のコードは、1冊目を基準に、2冊目以降のブックとソースを比べます。弊社の試しのブックで、変えた1行だけが差分に出ることを確かめています。

import sys
import difflib
from oletools.olevba import VBA_Parser


def modules(path):
    vp = VBA_Parser(path)
    try:
        out = {}
        for _f, _s, name, code in vp.extract_macros():
            lines = code.replace("\r\n", "\n").replace("\r", "\n").split("\n")
            out[name] = "\n".join(ln.rstrip() for ln in lines).strip()
        return out
    finally:
        vp.close()


base, *others = sys.argv[1:]
a = modules(base)
print(base, "モジュール", len(a), "本")
for path in others:
    b = modules(path)
    for name in sorted(set(a) | set(b)):
        if a.get(name) == b.get(name):
            continue
        print(path, name, "違う")
        old = (a.get(name) or "").split("\n")
        new = (b.get(name) or "").split("\n")
        for ln in difflib.unified_diff(old, new, lineterm="", n=0):
            print("  ", ln)
    print(path, "比べ終わり")

使い方は python compare_vba.py 基準.xlsm 比べる1.xlsm 比べる2.xlsm です。違うモジュールがなければ、ブックごとに「比べ終わり」だけが出ます。

1行目のモジュールの本数が0なら、マクロが無いか、取り出しに失敗しています。

中身を目で見るだけなら、コマンドの olevba -c ブック.xlsm でソースだけを出せます。

弊社の実測(oletools 0.60.2)では、コマンドの出力は既定で Attribute の行を省き、--attr を付けると出ました。上のコードの extract_macros は、Attribute の行も含めて返しました。

落とし穴: 実際に​踏んだ​もの

  • バイトの違いを「マクロの違い」と読む上のお客様の6冊では、バイトだけを見るとマクロが6通りあるように見えました。ソースで比べ直すと同じでした。

  • 末尾に空の行が1行増えただけで「違う」と出たLibreOffice で開いて保存し直しただけで、ソースの末尾に空の行が1行増えました。行ごとの空白をそろえるだけでは「違う」のままで、先頭と末尾の空の行を除くと同じと出ました。

  • 形式を変えたら、Attribute の行が落ちた古い形式(.xls)のマクロ入りのブックを LibreOffice で .xlsm に変えると、コードの行は残り、Attribute の行(マクロの説明やショートカットキーの割り当てを書く行)が落ちました。

    Excel で保存し直した版には残っていました。

  • シートの部品のバイトも違ったお客様の同じ様式のブックどうしでは、入力に使わないシートの部品のバイトにも、ブックによって違う物がありました。セルの値で比べ直すと、違うセルはありませんでした。

確かめ方​: 1行だけ​変えた​ブックで、​比べ方が​違いを​拾うかを​見る

比べた結果が「全部同じ」のとき、本当に同じなのか、比べ方が違いを拾えていないのかは、結果だけでは区別できません。次の手順で、比べ方そのものを確かめます。

  1. 基準のブックと同じソースで、1つのモジュールの1行だけを変えたブックを用意する
  2. 基準のブックを開いて、何も変えずに保存し直したブックを用意する
  3. 3冊を比べ、1行変えたブックは、そのモジュールだけが「違う」と出ることを見る
  4. 保存し直しただけのブックは、「同じ」と出ることを見る
  5. どのブックも、モジュールの本数が0でないことを見る

弊社の試しでは、1行変えたブックは変えたモジュールだけが「違う」と出て、保存し直しただけのブックは「同じ」と出ました。この2つがそろって、比べ方が使えると判定しました。

自力で​どこまで​やれるか

比べる冊数が少なく、Python を動かせて、知りたいのが「コードが同じか」だけなら、自力で足ります。上のコードは、仮想環境と oletools だけで動きます。

自力の壁は次の3つです。

  • ソースが違ったときに、どの版を残すかを決めるには、何をしているかの解読が要る
  • マクロが同じでも、ブックの動きはシートの式・名前の定義・参照設定にも左右され、ソースの比べはそこを見ない
  • 冊数が多く、違う版が何系統もあり、1つの様式にまとめる設計が要る

外注する​場合の​判断基準

外注の分かれ目は、比べた後に、マクロが何をしているかを読み解き、使われていない処理や重複している処理を見分ける必要があるかです。外注するなら、見積もりを比べる前に次の3点を確かめてください。

  • マクロが同じかを、vbaProject.bin のバイトでなく、モジュールごとのソースで比べるか
  • 比べ方が違いを拾うかを、1行だけ変えたブックで確かめるか
  • ソースに加えて、シートの式やセルの値も比べるか

ゴムマリでは、作った人がいなくなったマクロ・アドインの解読を、マクロ・VBA解読/リファクタリングとして承ります。

読める仕様書と、使われていない処理・重複している処理を洗い出した残す・捨てるの判断メモをお渡しします。続けて頼むと、同じ結果を出す再実装と、新旧を全件で突き合わせた照合の記録もお渡しします。

料金は5万円から、期間は1週間からです。ファイルをお送りいただくと、無料のファイル診断で、規模と着手前の額をお返しします。マクロの外注の相場は業務自動化の外注費用まとめに整理しています。進め方は相談からご連絡ください。

次の​一歩

手元のマクロ入りのブックを2冊選び、olevba -c で両方のソースを出して、モジュールの名前と本数をそろえて見てください。本数が同じで、名前ごとのソースが同じなら、バイトが違ってもマクロは同じです。

違うモジュールがあれば、そのモジュールだけ行の差分を出し、どちらの版を残すかを決めます。決める前に、そのマクロが何をしているかを書き出しておくと、残す理由を後から説明できます。

既存の Excel の様式にプログラムで値を書き込むときに、マクロの部品が消える理由は、Excel帳票への自動書き込みでファイルが壊れる理由にまとめています。

関連記事: Excel帳票への自動書き込みでファイルが壊れる理由

この記事を書いた人

代表 村山悠太のポートレート

村山 悠太(ゴムマリ代表)

ワークスアプリケーションズで大手企業向けERPの営業と導入を担当し、外資系SaaS企業と国内大手放送局で販路と新規事業の立ち上げ、AI学習用データを扱うAIスタートアップ2社でマーケティングと営業を担った。2024年10月から生成AIの実装に入り、いまは大手企業の現場で、AIエージェントを要件定義から運用まで手がけている。

代表の経歴を見る

Ask

この​業務を​頼むなら

専門業務AI-BPO

マクロ・VBA解読/リファクタリング

作った人が辞めて誰も直せないExcelマクロ・アドインを、読める仕様書にして返します。続けて頼むと、同じ結果を出す形に作り直し、新旧の全件照合レポートをつけます。まずは無料のファイル診断で、規模と着手前の額をお返しします。

5万円〜(1週間〜)

マクロ・VBA解読/リファクタリングを見る

Related

関連

FAQ

よく​ある​質問

vbaProject.bin のハッシュが違えば、マクロは違うのですか?

そうとは限りません。vbaProject.bin には、ソースのほかに、保存のしかたで変わってよい値が入ります。弊社が LibreOffice で同じソースのマクロを3回保存したブックでは、3冊ともバイトが違い、ソースは同じでした。マクロが同じかは、モジュールごとに取り出したソースで比べます。

同じ Excel で開いて保存し直しただけでも、バイトは変わりますか?

弊社は Excel では確かめていません。LibreOffice で試すと、別々に保存した2冊はプロジェクトの識別子と、保護などを暗号化して書いた3つの文字列が違い、開いて保存し直しただけの1冊はソースの末尾に空の行が1行増えていました。

Attribute の行だけが違うときは、マクロは同じと見てよいですか?

コードの行は同じです。ただし Attribute の行には、マクロの説明やショートカットキーの割り当てが入ります。弊社が古い形式のブックを LibreOffice で .xlsm に変えたときは、この行が落ちました。使い方に関わる行なので、違いが Attribute の行だけでも中身を見ます。

ソースが同じなら、ブックは同じ動きをしますか?

限りません。ブックの動きは、シートの式・名前の定義・参照設定・フォームの部品にも左右されます。ソースの比べはそこを見ません。弊社はお客様のブックで、ソースに加えて、同じ様式のブックどうしで入力に使わないシートのセルの値も比べ、同じであることを確かめました。

ご相談は​こちらから

相談は無料です。

相談する