数式びっしり、シートや列が多くて複雑なExcelファイル。そんな職人芸なExcelを解析したくて、Claude Codeに読ませてみた。
今回の解析対象のExcel:
- 数式が多い
- 表形式(いわゆるExcel方眼紙ではない。列ごとにある程度同じ数式が入っている)
- 図表は使われていない
- シート複数あり
最終的に、このような図を出せる。これは列の計算式の依存関係である。
スクリプト概要
まず、内容をテキスト化するスクリプトを書いた(コードは後述)。
指定したExcelの各セルを以下のような、セルごとに1行のテキストを出力する。
'Sheet1'!B2: =SUM(C2:E2)
'Sheet1'!C2: 123456
'Sheet1'!B3: =SUM(C3:E3)
'Sheet1'!C3: 5678
...
セルごとに1行を出力する。
行数が多い場合は、デフォルトで先頭30行+末尾30行だけ出力する。列ごとに同じ数式が埋め込まれている傾向にあるExcelなら、これで十分である。
スクリプトの使い方
python extract_excel.py file.xlsx [output_dir]
- 第1引数:Excelファイルパス(必須)
- 第2引数:出力ディレクトリ(任意)
出力はシート単位の .txt
と、全シート名を列挙した worksheets.md
である。
Claude Codeに投げてみる
以下のような作業をClaude Codeに依頼してみる。
このディレクトリには、1つのExcelファイルの内容をワークシートごとにテキストに書き出したファイルが入っています。
このExcelファイルに含まれるワークシートごとに以下の作業をしてください。
作業結果はワークシートごとに `explain-01_Sheet1.md` のようなファイル名の形式でMarkdownで出力してください。
- ワークシートの概要
- 列ごとの説明
- 列ごとに
- 計算式がある場合はどのワークシート・列に依存しているか
- 計算している内容の詳細な説明
- このワークシートに含まれるセルの計算式から、このワークシートの依存先ワークシート
次に、`explain-*.md` を見て、ワークシートの列の依存関係をmermaidで図示し、worksheets.md に図を追記してください。
これで最初に出したmermaidの図のような分析ができる。
Excelファイルをテキストにするとなにが便利か
- セルの内容を grep, diff しやすい
- ClaudeなどのAIが読みやすい
- 非表示になっている隠しワークシートや行のトラップに気づける
Pythonコード
extract_excel.py
import sys
import os
from openpyxl import load_workbook
excel_file = sys.argv[1]
output_dir = sys.argv[2] if len(sys.argv) > 2 else None
all_mode = sys.argv[3] == "true" if len(sys.argv) > 3 else False
def process_worksheet(ws, output_file=None):
rows_list = list(ws.iter_rows())
total_rows = len(rows_list)
def write_cell(cell, file_handle=None):
if cell.value:
line = f"'{ws.title}'!{cell.coordinate}: {cell.value}"
if file_handle:
file_handle.write(line + "\n")
else:
print(line)
def write_separator(file_handle=None):
line = f"# ... skipped {total_rows - 60} rows ..."
if file_handle:
file_handle.write(line + "\n")
else:
print(line)
if not all_mode and total_rows >= 70:
# デフォルト: 先頭30行 + 最後30行
for row in rows_list[:30]:
for cell in row:
write_cell(cell, output_file)
# セパレーター
write_separator(output_file)
# 最後30行
for row in rows_list[-30:]:
for cell in row:
write_cell(cell, output_file)
else:
# 全行処理
for row in rows_list:
for cell in row:
write_cell(cell, output_file)
try:
wb = load_workbook(excel_file, data_only=False)
worksheet_names = []
for ws in wb.worksheets:
worksheet_names.append(ws.title)
if output_dir:
# ワークシート名をファイル名として使用(無効な文字を置換)
safe_name = "".join(c if c.isalnum() or c in (' ', '-', '_') else '_' for c in ws.title)
idx = wb.worksheets.index(ws) + 1
safe_name = f"{idx:02d}_{safe_name}"
output_file_path = os.path.join(output_dir, f"{safe_name}.txt")
with open(output_file_path, 'w', encoding='utf-8') as f:
process_worksheet(ws, f)
print(f"Wrote worksheet '{ws.title}' to {output_file_path}")
else:
process_worksheet(ws)
if output_dir:
with open(os.path.join(output_dir, "worksheets.md"), "w", encoding="utf-8") as f:
for name in worksheet_names:
f.write(f"- {name}\n")
print(f"Wrote worksheet names to {os.path.join(output_dir, 'worksheets.md')}")
except FileNotFoundError:
print(f"Error: File '{excel_file}' not found", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
このPythonスクリプトの実行には pip install openpyxl
が必要だ。
それから、コマンドラインオプションの形式や処理の仕方が気持ち悪いが、手抜きである。