請求書・領収書を「別シートに1行入れるだけ」で作る GAS 帳票テンプレ
スプレッドシートに 帳票/データ/設定 の3シートを組み、入力1行で印刷用帳票が完成する構成をGASで作る。セル値の読み戻しでは検出できない印刷時の文字切れを、PDF書き出しの目視で潰すまでを含む。
約4.8万トークンの節約 (API料金換算で約72円分)。 要件定義・技術調査・試行錯誤ぶんのトークンがまるごと不要になります。※ 出品者申告とレビューに基づく推定値。モデル・タスク内容により変動します。
この巻物について
「請求書・領収書を「別シートに1行入れるだけ」で作る GAS 帳票テンプレ」は、経理・バックオフィスカテゴリのAI指示書(MDファイル)です。スプレッドシートに 帳票/データ/設定 の3シートを組み、入力1行で印刷用帳票が完成する構成をGASで作る。セル値の読み戻しでは検出できない印刷時の文字切れを、PDF書き出しの目視で潰すまでを含む。この巻物をAIに読み込ませると、ゼロから設計・調査する場合に比べて 約4.8万トークン(API料金換算で約72円)・80%のトークンを節約できます。
- カテゴリ
- 経理・バックオフィス
- 対応AI
- claude-code、cursor、codex-cli
- ライセンス
- 商用利用可 (再販不可)
- 価格
- 無料
- ゼロから開発時
- 約6万トークン
- この巻物使用時
- 約1.2万トークン
- 節約量
- 約4.8万トークン (約72円)
- 更新日
- 2026-08-27
使い方 (AIに渡す3つの方法)
いちばん簡単なのはワンライナー。Claude Code のターミナルに貼るだけです。
claude "https://makimono-md.vercel.app/api/v1/files/1-gas/raw を読み込んで、この指示書どおりに実装して"
中身
請求書・領収書を「別シートに1行入れるだけ」で作る GAS 帳票テンプレ
スプレッドシートに帳票(請求書 / 領収書 / 納品書)を作る指示書。 入力シートに1行入れると印刷用シートが完成する構成を Google Apps Script で組み立てる。 Word や PDF を毎回コピーして手打ちしている運用を置き換える。
最後の「検証」の節が本体。セル値の読み戻しでは印刷時の文字切れが検出できないため、 PDF 書き出しを目視するところまでやって初めて完了になる。
1. 3シート構成にする
| シート | 役割 | 中身 |
|---|---|---|
帳票 | 印刷用。全セルが数式で データ を引く | レイアウトのみ。人は編集しない |
データ | 1行 = 帳票1枚。人が入力するのはここだけ | 明細・宛先・日付など |
設定 | 発行元情報・既定税率・注記の表示可否 | 全帳票で共通の値を一元管理 |
帳票 シートに 発行No. の入力セル1つ(例 C4)を置き、そこに データ の No を入れると
その1件に切り替わる。全セルはこの1セルを参照する。
function buildSheet_(sheet) {
// 数式は文字列連結で組み立てる。ヘルパーを先に定義すると重複が消える
function dv(col) { return 'VLOOKUP($C$4,データ!$A:$Z,' + col + ',FALSE)'; }
function dvSafe(col) { return 'IFERROR(' + dv(col) + ',"")'; }
function stg(name) { return 'IFERROR(VLOOKUP("' + name + '",設定!$A:$B,2,FALSE),"")'; }
// 税率はデータ側が空なら設定の既定値へフォールバック
function rate() {
return 'IF(N(IFERROR(' + dv(23) + ',0))>0,' + dv(23) +
',IFERROR(VLOOKUP("既定の消費税率",設定!$A:$B,2,FALSE),0.1))';
}
sheet.getRange('D8:F8').merge().setFormula('=IF(' + dvSafe(4) + '="","",' + dv(4) + '&" 様")');
}
2. 入力を減らす — 導出できる項目は数式で出す
人に入れさせるのは「その帳票にしか無い事実」だけにする。
| 項目 | やり方 |
|---|---|
| 帳票番号 | 空欄なら "INV-"&TEXT(YEAR(発行日),"0")&"-"&取引番号 を自動生成。入力があればそちらを優先 |
| 期間・日数 | 終了日 - 開始日 |
| 内税額 | 合計 - ROUND(合計/(1+税率),0) |
| 合計 | 明細金額の SUM(IFERROR(...,0), ...)。全部0なら空文字を返して空欄に見せる |
「空欄なら自動、入力があれば優先」は IF(値<>"", 値, 自動生成) で書く。
入力シート側に数式を置くと人が上書きして壊すので、入力シートは値だけ・数式は帳票シート側に寄せる。
3. 入力シートは「間違えられない」形にする
// ドロップダウンは2行目から。ヘッダー行に付けると赤い警告が出て見た目が壊れる
var rule = SpreadsheetApp.newDataValidation()
.requireValueInList(['銀行振込', 'クレジットカード', '現金', 'その他'], true).build();
sheet.getRange(2, 24, 30, 1).setDataValidation(rule);
sheet.getRange(2, 16, 30, 1).setNumberFormat('¥#,##0');
sheet.getRange(2, 23, 30, 1).setNumberFormat('0%').setValue(0.1); // 既定税率を流し込む
sheet.setFrozenRows(1);
API から行を追加する口も付けるなら、日付は文字列で届くので Date に直す。
直さないと ISNUMBER() が false になり、日数の自動計算が黙って空欄になる。
function toDate_(v) {
if (v === '' || v === null || v === undefined) { return ''; }
if (v instanceof Date) { return v; }
var m = String(v).match(/^(\d{4})[-\/](\d{1,2})[-\/](\d{1,2})/);
return m ? new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3])) : v;
}
採番は「既存の最大 + 1」、書き込み先は「No が空の最初の行」。
ヘッダーだけの状態を lastRow で素朴に扱うと初回が No=2 になるので注意。
var lastRow = sheet.getLastRow();
var no = 1, targetRow = 2;
if (lastRow >= 2) {
var vals = sheet.getRange(2, 1, lastRow - 1, 1).getValues();
targetRow = lastRow + 1;
for (var i = 0; i < vals.length; i++) {
var v = vals[i][0];
if (typeof v === 'number' && v >= no) { no = v + 1; }
if ((v === '' || v === null) && targetRow > i + 2) { targetRow = i + 2; }
}
}
4. 検証 — PDF を書き出して目で見る(この節が本体)
セル値を API で読み戻して全項目が正しくても、印刷では文字が切れている。 実際に起きた切れ方: 住所が途中で切断 / 登録番号の末尾3桁が消失 / 見出しの先頭2文字が 入力枠に食われて消滅 / 日付の閉じ括弧が欠落 / 明細名と支払方法が途中で切断。 値の読み戻しでは1つも検出できなかった。 セル値は正しいので API 越しには健全に見える。
原因は列幅不足+溢れ先のセルに背景色や内容があること(溢れは隣が空のときしか起きない)。
スプレッドシートは要認証なのでヘッドレスブラウザでは開けない。Drive API の PDF 書き出しを使う。
- Drive の
download_file_content相当にexportMimeType: 'application/pdf'を渡す(Sheets は PDF 書き出し可) - 返ってきた base64 をデコードして
.pdfとして保存する - その PDF を画像として開いて目視する。 テキスト抽出だと描画崩れは出ない
保存スクリプトの注意: Windows の Python は標準出力が CP932 のことがあり、
¥を print しただけでUnicodeEncodeErrorになる。print せずファイルに書く。
切れていたときの直し方
- 列幅を用紙の実寸に合わせる(A4 縦なら本文カラム合計 ~690px が上限の目安)
- 長い値は
setWrap(true)+setRowHeight()をセットで(結合セルは自動で高さが伸びない) - 1行に「ラベル+値」を2組詰めない。2行に分ければ切れない
- 右詰めセルが左へ溢れて隠れるときは、結合範囲を左へ1列広げる
5. LLM に実装を委譲したとき、必ず入っている不良
コード生成を委譲した場合、レビューで先にこれを探すと早い。実測で全部踏んだ。
| 不良 | 症状 |
|---|---|
setBorder(...) の color 引数に 'solid' を渡す | 引数は (上,左,下,右,縦,横,色,線種)。色は '#000000' 等のCSS文字列。例外か無視 |
6つの位置引数がすべて null の setBorder | 「罫線を変更しない」の意味。罫線が出ない |
setHiddenGridlines を Range に繋ぐ | これは Sheet のメソッド。TypeError |
| 数式内の文字列リテラルの引用符落ち | "ラベル "& の " が無く、数式が構文エラー |
文字列連結に JS の & を使う | & はビット演算。結果が 0 になり数式が壊れる |
| 既存シートをループで全削除 | 最後の1枚は削除できず例外。既存データも消える |
| モジュール(IIFE)で包む | GAS のグローバル関数として外部から呼べなくなる |
構造要件は grep で機械判定できる形で指示に書く(^function があるか、(function() が無いか、
deleteSheet が無いか)。1回目で無視されたら「前回これで不合格になった」と明記して投げ直すと通る。
委譲の出力を非UTF-8のシェル経由で受け取ると日本語が壊れる。 コンソールの出力エンコーディングを UTF-8 に設定してから実行し、 生成物を grep して既知の日本語が読めるか確認してから中身をレビューする。
6. 完了と言ってよい条件
- 実データ1件を投入し、帳票シートの全項目が期待値と一致
- 既存の帳票(過去に発行した実物)がある場合、合計と税額がその実物と一致
- PDF を書き出して目視し、文字切れ・レイアウト崩れ・余計なページが無い
- 自動生成項目(帳票番号・日数・税額)が、入力していないのに正しく出ている
「値は入っている」で止めない。印刷して人が読むものは、印刷像を見るまで終わっていない。
よくある質問
+「請求書・領収書を「別シートに1行入れるだけ」で作る GAS 帳票テンプレ」とは何ですか?
スプレッドシートに 帳票/データ/設定 の3シートを組み、入力1行で印刷用帳票が完成する構成をGASで作る。セル値の読み戻しでは検出できない印刷時の文字切れを、PDF書き出しの目視で潰すまでを含む。
+どれくらいトークン(費用)を節約できますか?
ゼロから開発すると約6万トークンかかりますが、この巻物を使えば約1.2万トークンで済みます。差し引き約4.8万トークン(API料金換算で約72円)・80%の節約です。
+どうやって使いますか?
無料です。MDファイルを Claude Code などのAIに読み込ませるだけ。ワンライナーをターミナルに貼れば実装が始まります。要件定義や技術調査を省いて実装だけにトークンを使えます。
+どのAIツールに対応していますか?
claude-code、cursor、codex-cli に対応しています。
+商用利用できますか?
ライセンスは「商用利用可 (再販不可)」です。
🤝 自分でAIを動かすのは、まだ不安…という方へ
この巻物の内容を、AIを使うプロに丸ごと任せることもできます。姉妹サービスAI代行堂なら「LINEで頼むだけで、仕事が完成」。
関連する巻物
請求書PDF→会計CSV 自動変換パイプラインMD
メール添付やフォルダ投込みの請求書PDFから金額・日付・取引先を抽出し、会計ソフト取込用CSVに変換するパイプラインを AI に作らせる指示書。Claude API の構造化抽出プロンプト込み。
freee会計API 取引先自動連携ガイド(OAuth/トークンローテーション/DRY-RUN)
Next.js+SupabaseアプリからfreeeのOAuth接続・refresh_tokenローテーション対応・取引先の自動紐付け/新規作成をDRY-RUN安全に実装する手順
この巻物、誰かのトークンも救えます
𝕏 で節約レシートをシェア