業務自動化

GASでGoogleドライブの領収書をOCR→経費表に自動転記 経理を週2時間削減

個人事業主・小規模法人・士業事務所 (月20〜100枚の領収書を1人で処理する経理) の業務自動化レシピ
業種個人事業主・小規模法人・士業事務所 (月20〜100枚の領収書を1人で処理する経理)
ツールGoogle Apps Script
難易度★★☆ 中
設定時間約 45 分

領収書の束を前に、日付・金額・店名を経費表へ入力する作業は、GoogleドライブのOCRとGoogle Apps Scriptを組み合わせて効率化できます。追加費用の目安は¥0ですが、読み取り結果の確認や紙の原本保管は必要です。中小企業や個人事業主向けに、設定から運用上の注意点まで紹介します。

読了時間 約11分 / 設定所要時間 約45分 / 追加費用の目安 ¥0

編集長の見解: 領収書の読み取り自動化は、有料の会計クラウドサービスだけのものではありません。月20〜100枚程度なら、GoogleドライブのOCRを使って転記作業を減らせる可能性があります。重要なのは、読み取った結果を経費表へ記録し、後から確認しやすくすることです。本記事では、追加費用の目安を抑えた仕組みと、残すべき人の確認作業を整理します。

🔍 領収書の入力に「週2時間」かかる理由

編集部のシミュレーションでは、月80枚の領収書を処理する場合、1枚あたり平均6分かかると、月8時間になります。4週で換算すると、週約2時間です。

この試算は実在企業の計測値ではありません。封筒から出し、内容を読み、経費表へ入力して整理する一般的な作業を想定しています。

作業を分けると、自動化しやすい部分と、人が判断すべき部分が見えてきます。

自動化の対象は、前半の転記と整理です。勘定科目や私用分の判断は、人が行う前提で設計します。

💡 編集部メモ: 外部サービスを使う方法は別記事で紹介しています。Slack投稿を起点にするならZapier×Slackで領収書から経費精算を自動化するレシピ、請求書を社外に出さず処理するならn8n×Ollamaで請求書PDFを自社完結処理するレシピが参考になります。本記事は、追加費用を抑えたい場合の選択肢です。

次に、追加費用を抑えられるGoogleドライブのOCRの仕組みを確認します。

🧩 GoogleドライブのOCRを変換機能として使う

Googleドライブは、画像やPDFをGoogleドキュメント形式へ変換する際に、OCRを実行できます。OCRとは、画像に含まれる文字を読み取ってテキストに変換する機能です。

Google公式の開発者向け資料では、画像をドキュメントへ変換する際にOCRを使えることが説明されています。ocrLanguage というパラメーターを使えば、日本語などの言語情報も指定できます。

Google Apps Script (以下、GAS) は、Googleアカウントで使えるプログラム実行環境です。GASから変換を呼び出すと、読み取った文章をそのまま取得できます。

部品役割公式ドキュメント
DriveApp領収書フォルダの走査、ファイルの移動・名前変更DriveApp リファレンス
Drive (拡張サービス / v3)Googleドキュメント形式への変換、OCRの実行Advanced Drive Service
DocumentApp変換後のドキュメントから本文を取得DocumentApp リファレンス
SpreadsheetApp経費表への追記SpreadsheetApp リファレンス

GASで4つの機能をつなぐと、領収書の投入から経費表への記録までを自動化できます。

🗺 全体フロー — フォルダに入れて確認する

スマートフォンで撮った領収書やメールで届いたPDFを、「未処理」フォルダへ入れます。GASが読み取り、経費表へ追記した後、処理済みフォルダへ移動します。

領収書フォルダから経費表へ自動転記
📥
01
未処理フォルダへ投入
スマートフォンで撮った画像やPDFをGoogleドライブへ保存
🔤
02
GASがOCRを実行
ドキュメント形式へ変換し、日付・金額・取引先を抽出
📊
03
経費表へ追記
スプレッドシートへ1行追加し、確認欄を未チェックで用意
🗂
04
名前を変更して格納
日付・金額・取引先の形式に変更し、処理済みフォルダへ移動

人が行うのは投入と最終確認

4番目の名前変更は、単なる整理ではありません。電子帳簿保存法で求められる検索性との関係を確認します。

📜 電子帳簿保存法との関係

領収書の電子化では、「電子取引データの保存」と「スキャナ保存」を分けて考える必要があります。電子取引データは、メール添付のPDFやWebサイトから取得した領収書など、電子的に受け取ったデータが対象です。

一方、紙で受け取った領収書をスキャンし、原本を廃棄する場合は、スキャナ保存の要件が関係します。

区分対象になる領収書電子保存の位置づけ本レシピとの相性
電子取引データの保存メール添付のPDF、Webサイトから取得した領収書データでの保存が必要◎ 対応しやすい
スキャナ保存店頭で紙で受け取った領収書紙原本を廃棄したい場合に選ぶ方法△ 自作構成では要件確認が必要
紙のまま保存店頭で紙で受け取った領収書従来どおり紙で保管○ 転記の効率化に利用できる

電子取引データの保存では、主に次の項目を確認します。

検索性を確保する方法として、国税庁は次の方法を示しています。

本記事のスクリプトは、経費表とファイル名を自動で作ります。ただし、これだけで法令上の要件を満たすと判断しないでください。保存方法や事業規模などによって、必要な対応は変わります。

💡 知っておくと安心: 国税庁の一問一答では、基準期間(個人事業主は前々年、法人は前々事業年度)の売上高が5,000万円以下の場合などに、一定の条件を満たせば検索機能の確保が不要となる扱いが示されています。電子取引データを印刷し、日付・取引先ごとに整理して提示・提出できる状態にする方法もあります。いずれも、税務職員からデータのダウンロードを求められた場合に応じられることなどが条件です。最新の条件は、国税庁の資料や税理士に確認してください。

⚠️ 注意: このレシピだけではスキャナ保存の要件を満たしません。紙で受け取った領収書をスキャンし、原本を廃棄するスキャナ保存では、解像度200dpi相当以上・24ビットカラーでの読み取り、入力期間内のタイムスタンプ付与または保存時期の確認、訂正・削除履歴の確認、帳簿との相互関連性、表示・出力のための機器や説明書類の備付けなどが求められます。Googleドライブと自作スクリプトの組み合わせだけでは、要件を満たすか確認できません。紙の領収書は捨てず、従来どおり保管してください

本記事は国税庁の公表資料をもとにした一般的な整理です。自社の保存方法が要件を満たすかどうかは、顧問税理士または所轄の税務署へ確認してください。判断は事業実態や書類の種類によって変わります。

💡 編集部の判断材料: 紙の原本を廃棄したい場合は、要件対応を確認した市販ソフトの利用が現実的です。導入費用の一部が補助金の対象になる場合もあるため、検討時はIT導入補助金 2026 の解説記事も確認してください。本レシピは、まず追加費用の目安を抑えて転記作業を減らし、必要になった段階で市販ソフトを検討する方法です。

要件を切り分けたところで、実際の構築に進みます。

🛠 設定手順 — 約45分で完成

作業は、ドライブとシートを用意し、拡張サービスを有効にしてコードを貼り付ける流れです。プログラミングの知識がなくても始められますが、初回は必ず少量でテストしてください。

GASで領収書をOCRし経費表へ転記する手順
STEP 1
フォルダを2つ作る
Googleドライブに「領収書_未処理」と「領収書_処理済」の2フォルダを作り、URL末尾のフォルダIDを控えます。
STEP 2
経費表シートを作る
新しいスプレッドシートを作り、シート名を「経費表」に変更します。1行目に「日付・金額・取引先・区分・確認済・ファイルリンク・OCR原文」の7列を用意します。「確認済」列にはチェックボックスを設定します。
STEP 3
Apps Scriptエディタを開く
スプレッドシートのメニューから「拡張機能」→「Apps Script」を選びます。
STEP 4
Drive拡張サービスを有効化
エディタ左側の「サービス」にある+をクリックし、「Drive API」を追加します。バージョンはv3を選びます。
STEP 5
コードを貼り付ける
以下のコードをコード.gsへ貼り付けて保存します。フォルダIDはコードへ直接書かず、次の手順でスクリプトプロパティに登録します。
STEP 6
フォルダIDを登録
エディタ左側の歯車(プロジェクトの設定)から「スクリプト プロパティ」を開き、INBOX_FOLDER_IDとDONE_FOLDER_IDにSTEP 1のIDを登録します。
STEP 7
領収書1枚でテスト実行
未処理フォルダに領収書を1枚だけ入れ、関数processReceiptsを実行します。初回はアクセス承認が表示されるため、内容を確認して許可します。
STEP 8
毎日の自動実行を設定
読み取り精度を確認した後、エディタ左側の時計アイコンから「時間主導型」→「日タイマー」でトリガーを追加します。

貼り付けるコード

以下をApps Scriptエディタの コード.gs に貼り付けてください。未処理フォルダのファイルをOCRし、経費表へ追記して名前を変更し、処理済みフォルダへ移動する processReceipts が本体です。

/**
 * 領収書_未処理フォルダ → DriveのOCRで文字抽出 → 経費表へ追記
 * → 日付_金額_取引先に名前を変更 → 領収書_処理済へ移動
 * 事前に「サービス」からDrive API (v3)を追加しておくこと
 */
function processReceipts() {
  // Apps Scriptは1回の実行が6分で打ち切られる。1回あたりの上限を決めておく
  const MAX_PER_RUN = 40;
  // Googleは精度確保のため2MB以下を推奨。必要なら変更可
  const MAX_FILE_SIZE = 2 * 1024 * 1024;
  // OCR対象の形式
  const OCR_MIME_TYPES = [MimeType.PDF, MimeType.JPEG, MimeType.PNG, MimeType.GIF];
  let processed = 0;

  const props = PropertiesService.getScriptProperties();
  const inboxId = props.getProperty('INBOX_FOLDER_ID');
  const doneId = props.getProperty('DONE_FOLDER_ID');
  if (!inboxId || !doneId) {
    throw new Error('INBOX_FOLDER_ID / DONE_FOLDER_IDが未設定です');
  }

  const doneFolder = DriveApp.getFolderById(doneId);
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('経費表');
  if (!sheet) {
    throw new Error('「経費表」という名前のシートが見つかりません');
  }

  const iterator = DriveApp.getFolderById(inboxId).getFiles();
  const targets = [];
  while (iterator.hasNext()) targets.push(iterator.next());

  for (let i = 0; i < targets.length; i++) {
    if (processed >= MAX_PER_RUN) {
      Logger.log('今回の上限 ' + MAX_PER_RUN + '件に達したため終了。残りは次回に処理されます');
      break;
    }

    const file = targets[i];

    if (OCR_MIME_TYPES.indexOf(file.getMimeType()) < 0) {
      Logger.log('OCR対象外の形式のためスキップ: ' + file.getName() + ' / ' + file.getMimeType());
      continue;
    }

    if (file.getSize() > MAX_FILE_SIZE) {
      Logger.log('サイズ超過のためスキップ: ' + file.getName());
      continue;
    }

    let text = '';
    let tempDocId = null;
    try {
      // Googleドキュメント形式へ変換するとOCRが実行される
      const converted = Drive.Files.create(
        { name: 'OCR_TEMP_' + file.getName(), mimeType: MimeType.GOOGLE_DOCS },
        file.getBlob(),
        { ocrLanguage: 'ja' }
      );
      tempDocId = converted.id;
      text = DocumentApp.openById(tempDocId).getBody().getText();
    } catch (e) {
      Logger.log('OCR失敗: ' + file.getName() + ' / ' + e.message);
      continue;
    } finally {
      if (tempDocId) DriveApp.getFileById(tempDocId).setTrashed(true);
    }

    const parsed = parseReceipt_(text);

    sheet.appendRow([
      parsed.date,
      parsed.amount,
      parsed.vendor,
      '',
      false,
      file.getUrl(),
      text.slice(0, 500)
    ]);

    const ext = file.getName().indexOf('.') >= 0
      ? file.getName().slice(file.getName().lastIndexOf('.'))
      : '';

    if (parsed.dateCompact && parsed.amount) {
      const vendor = parsed.vendor || '取引先未読';
      file.setName(parsed.dateCompact + '_' + parsed.amount + '_' + vendor + ext);
    } else {
      file.setName('要確認_' + file.getName());
    }

    file.moveTo(doneFolder);
    processed++;
  }
}

/**
 * OCR結果のテキストから日付・金額・取引先を推定する
 * 読み取れなかった項目は空欄で返し、人の確認に回す
 */
function parseReceipt_(text) {
  const tz = 'Asia/Tokyo';

  let date = '';
  let dateCompact = '';
  const m = text.match(/(20\d{2})\s*[\/年.\-]\s*(\d{1,2})\s*[\/月.\-]\s*(\d{1,2})/);

  if (m) {
    const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
    date = Utilities.formatDate(d, tz, 'yyyy/MM/dd');
    dateCompact = Utilities.formatDate(d, tz, 'yyyyMMdd');
  }

  const textForAmount = m ? text.replace(m[0], ' ') : text;
  let amount = '';
  const totalLine = textForAmount.match(/(合\s*|\s*|お買上げ計)[^\d]{0,12}([0-9,]{2,})/);

  if (totalLine) {
    amount = totalLine[2].replace(/,/g, '');
  } else {
    const nums = (textForAmount.match(/[0-9,]{3,}/g) || [])
      .map(function (s) { return Number(s.replace(/,/g, '')); })
      .filter(function (n) { return !isNaN(n) && n < 10000000; });

    if (nums.length) amount = String(Math.max.apply(null, nums));
  }

  let vendor = '';
  const lines = text.split('\n')
    .map(function (s) { return s.trim(); })
    .filter(function (s) { return s.length > 1 && s.length < 30; });

  for (let i = 0; i < Math.min(lines.length, 5); i++) {
    if (!/^[0-9,.\-\/:¥¥\s]+$/.test(lines[i])) {
      vendor = lines[i];
      break;
    }
  }

  vendor = vendor.replace(/[\\\/:*?"<>|]/g, '');

  return {
    date: date,
    dateCompact: dateCompact,
    amount: amount,
    vendor: vendor
  };
}

読み取れなかった項目は、空欄のまま経費表に並びます。空欄は人が確認する行です。

日付か金額を読み取れなかった領収書は、ファイル名の先頭に 要確認_ が付きます。処理済みフォルダの中でも、確認対象を見つけやすくなります。

⚠️ バージョン違いが起きやすい点: 上のコードはDrive APIのv3向けです。現在のApps Scriptで「Drive API」を追加すると、通常はv3が選ばれます。古いプロジェクトなどでv2になっている場合、Drive.Files.create is not a functionというエラーになることがあります。その場合は、サービスの設定をv3に切り替えてください。v2を使う場合は、メソッド名をDrive.Files.insertに、ファイル名の項目をnameからtitleに変更します。第3引数は{ ocr: true, ocrLanguage: ‘ja’ }とします。

設定が終わったら、読み取り精度と限界を確認します。

⚠️ 失敗パターンと読み取り精度

このレシピを「全自動の経理」と考えると、運用でつまずきます。特に注意したい点は、ファイル条件と読み取り結果の確認です。

⚠️ 失敗パターン1: 写真のサイズや形式で処理できない: Googleは読み取り精度を高める条件として、ファイルを2MB以下にすることを案内しています。厳密な上限とは限りませんが、コードでは安全側に倒して2MB超のファイルをスキップします。最近のスマートフォン写真は3〜5MBになることがあるため、撮影時に解像度を下げるか、Googleドライブアプリのスキャン機能でPDF化してください。

形式にも注意が必要です。OCR対象として使えるのはPDF・JPEG・PNG・GIFです。iPhoneの初期設定であるHEIC形式には対応していません。iPhoneでは「設定 → カメラ → フォーマット」で「互換性優先」を選ぶか、ドライブアプリのスキャン機能を使います。コードは対象外の形式をログに残してスキップし、未処理フォルダに残します。

⚠️ 失敗パターン2: 読み取り結果を確認せず申告に使う: GoogleのOCRは、太字・斜体・文字サイズ・改行を保持しやすい一方、リスト・表・段組み・脚注は検出されにくいと案内されています。レシートは表形式が多いため、税率区分や品目の並びが崩れることがあります。経費表の「確認済」チェックボックスを使い、金額や日付を目視確認してから記帳してください。

読み取り精度は、領収書の状態で変わります。Googleは、文字の高さ10ピクセル以上、正しい向き、一般的なフォント、明暗が均一で鮮明な画像などを条件として挙げています。

領収書の種類読み取りやすさの目安編集部の対策
メール添付のPDF (電子取引)高い。文字情報を含むPDFは比較的安定そのまま投入する
コンビニなどの感熱紙レシート低い。細字・かすれ・折れに弱い平らに伸ばし、明るい場所で真上から撮影する
手書きの領収書低い。書体差が大きい金額欄を人が確認する
複数枚を1枚に並べた写真低い。合計額を判別しにくい1枚1ファイルにする

GASには、1回の実行につき6分という時間上限があります。自動実行の合計時間も、無料のGoogleアカウントでは1日90分、Google Workspaceでは1日6時間までです。

日々数枚ずつ処理するなら対応しやすい範囲ですが、領収書を一度に大量投入すると、6分を超えて途中で止まることがあります。コードは1回40枚で区切っています。初回は数回に分けて実行し、それでも時間を超える場合はMAX_PER_RUNを20などに下げてください。

GoogleドライブやGASの無料枠、Google Workspaceの最新の条件は、Apps Scriptの割り当てと制限で確認してください。

限界を把握したところで、経営者が設定時間をどう回収するかを見ていきます。

🚀 経営者は設定時間をどう回収するか

編集部の想定シナリオを紹介します。従業員3名の設計事務所で、代表が月末に自分と従業員の領収書80枚を入力しているケースです。実在企業の事例ではありません。

追加費用の目安は¥0です。ただし、GoogleドライブやGASの利用状況によっては、Google Workspace契約などが必要になる場合があります。無料枠内に収まる想定規模で始め、利用量が増えたら最新の料金と上限を確認してください。

基本形が動いたら、次の応用も検討できます。

当サイトでは、経理まわりの自動化も紹介しています。

電子帳簿保存法の全体像や勘定科目の付け方も確認すると、この自動化の使いどころが明確になります。関連書籍を探す場合は、次のリンクをご利用ください。

Amazonで電子帳簿保存法・経理実務の関連書籍を見る → ※ PR・アフィリエイトリンクを含みます

編集部のまとめ: このレシピは、GoogleドライブのOCRを経費表への転記とファイル整理に活用する方法です。追加費用の目安を抑えながら、入力作業を減らせます。ただし、読み取り結果の確認は必要で、紙の原本を捨てられるとは限りません。まずは領収書1枚で試し、自社の運用に合うか確認してください。

出典・参考情報

Mira / AI経営ラボ 編集長

Google Apps Script を無料で試す → ※ PR・アフィリエイトリンクを含みます