• #gemini-api
  • #ocr
  • #excel
  • #tax-assistant
  • #claude-code
  • #automation
tax-assistantメモ

やりたかったこと

確定申告の医療費控除に向けて、手元に溜まったレシート画像87件を国税庁の医療費集計フォーム(Excel、v3.1)に入力する必要があった。手作業だと1件あたり数分かかるので、OCRで読み取ってExcelに自動入力する仕組みを作った。

全体の流れ

  1. レシート画像をGemini APIでOCR
  2. 読み取り結果をExcelの所定フォーマットに書き込み
  3. レシート画像をルールに従ってリネーム
  4. 重複チェックと集計シート追加

Gemini APIによるOCR処理

レシート画像87件をGemini APIに投げてOCR処理した。読み取り対象は以下の項目。

  • 患者名
  • 医療機関名
  • 診療日
  • 支払金額
  • 治療内容(医療費の区分判定用)

結果、87件すべてエラーなしで読み取り完了。手書きレシートや感熱紙でかすれたものも含まれていたが、Geminiの画像認識精度が高く、目視確認で修正が必要だったのは数件程度だった。

Excel入力の自動化

国税庁フォーマットへの対応

医療費集計フォーム v3.1 は、シートの保護やセル結合が多く、プログラムから書き込む際にいくつかハマりどころがあった。

日付入力の問題

最初の実装ではExcelの日付型(シリアル値)で書き込んでいた。しかし、国税庁フォームは日付セルを文字列として扱う想定になっており、シリアル値だと表示がずれる。

修正として、日付を文字列「YYYY/M/D」形式(例: 2026/1/15)で書き込むように変更した。月・日のゼロ埋めなし形式が国税庁フォームの表示と一致する。

スラッシュコマンド化

この処理を繰り返し使えるように、/import-medical-receipts というスラッシュコマンドとして実装した。

tax-assistant の既存パターンをベースにした構成で、以下の機能を持つ。

  • レシート画像ディレクトリを指定して一括OCR
  • OCR結果のプレビュー表示(書き込み前に確認できる)
  • Excelファイルへの書き込み
  • 重複チェック
  • 集計シート生成

レシート画像のリネーム

OCR後にレシート画像を整理しやすくするため、命名規則を決めてリネームを行った。

命名規則

{患者名}_{医療機関名}_{YYYYMMDD}_{金額}円.jpg

例: 山田太郎_A内科_20260115_1520円.jpg

リネームの手順

  1. 元画像のバックアップコピーを作成
  2. バックアップが完了してからリネーム実行

バックアップを先に取ることで、リネーム中のエラーで元ファイルが失われるリスクを避けた。

患者名が不明な場合のルール

レシートによっては患者名が印字されていないものがある。その場合は以下のルールで推定した。

  1. 同日の他レシートから推定: 同じ日に別の医療機関で受診したレシートに患者名が書いてあれば、同一人物と推定
  2. 複数候補がある場合: レシート件数が多い方、件数が同じなら合計金額が大きい方を採用

完全に推定できないケースはファイル名に「不明」を入れて、後から手動で確認できるようにした。

重複チェック

同じレシートを二重に入力しないよう、以下の条件で重複判定を行った。

  • 患者名
  • 医療機関名
  • 診療日
  • 金額

4項目すべて一致した場合に重複と判定し、スキップする。同日・同医療機関でも金額が異なれば別レシートとして扱う(再診料と検査料が別レシートになるケースがある)。

集計シート

Excelに集計用のシートを追加した。Google Spreadsheetで先に作っていた集計表のレイアウトを参考に、患者別の合計金額を表示するシートを生成する。

集計内容:

  • 患者別の医療費合計
  • 医療機関別の内訳
  • 月別の推移

Excelのバージョン管理ルール

国税庁のExcelフォームは「元ファイルを直接変更しない」運用とした。

  1. 元ファイルのコピーを作成
  2. コピーに対して変更を加える
  3. 元ファイルは常にオリジナルの状態で残す

こうすることで、スクリプトのバグで書き込みが壊れた場合でもやり直せる。確定申告関連のファイルは特に慎重に扱いたい。

振り返り

  • Gemini APIのOCR精度が想像以上に高く、87件エラー0件は期待を上回った
  • 日付のフォーマット問題は、国税庁フォームの仕様を先に調べておけば防げた
  • スラッシュコマンド化しておくと、来年以降もそのまま使い回せる
  • レシートのリネームは地味だが、後から探すときに助かる