
毎月同じ相手に同じ金額で送る請求書は、スプレッドシートのひな形と Google Apps Script(GAS)があれば、毎月1日の朝に勝手に作って送るところまで自動に出来ます。 この記事では、自社で実際に毎月動かしていた仕組みを例に、スプレッドシートの作り方、貼るコード、試し方、毎月動かす設定までを、実際の画面で順番に書きます。 上から順にやれば、同じ物が作れます。 コードを AI に書いてもらう時のプロンプトも載せています。
出来上がりの形
Google Apps Script(GAS)とは、Gmail やスプレッドシートなど Google のサービスを動かす、小さなプログラムの事です。 スプレッドシートのメニューから開いて書けて、Google アカウントがあれば使えます。
出来上がると、毎月1日の朝8時台に次の事が勝手に起きます。

| 毎月、手でやっていた事 | 仕組みに任せた後 |
|---|---|
| 前月のファイルを複製して、名前を付け直す | ひな形のシートを自動でコピーし、「2601」のような年月の名前を付ける |
| 請求番号・発行日・支払期限を打ち替える | 動いた日から前月を計算して、自動で入れる |
| PDFに書き出して、保存する | シートをそのままPDFにする |
| メールを書いて、PDFを添付して送る | 決まった文面で送る。 自分にも同じメールが届く |
ここまで任せると、毎月の操作は0です。 締め日が近づくたびに「今月の請求書、出したっけ?」と頭のメモリを使い続ける状態とは、ここでおさらばです。
用意する物
- Google アカウント(Gmail が使えるもの)
- スプレッドシート1つ
- 送り先のメールアドレス(相手と自分)
請求書の元になるデータは、全部この1つのスプレッドシートの中に置きます。 中身は次の3種類のシートです。
| シート | 中身 | 作る人 |
|---|---|---|
| 「テンプレ」 | 請求書のひな形。 宛名・品目・数量・単価・振込先を書いておく。 金額と合計は数式で計算 | 自分(最初に1回) |
| 「Logs」 | 動いた記録。 何も書かずに空けておく | 自分(空のまま) |
| 「2601」「2602」… | その月の請求書。 「テンプレ」のコピーに番号と日付が入った物 | 仕組み(毎月1日に1枚ずつ増える) |
この例は毎月同じ金額の契約なので、金額もひな形に書いたままです。 毎月変わるのは、請求No・発行日・お支払期限の3つだけ。 ここまで割り切ると、仕組みはかなり小さく出来ます。
手順1: 請求書のひな形「テンプレ」を作る
① Google ドライブで「新規 > Google スプレッドシート」を作り、名前を付ける(例: 請求書の自動作成)
② 下のシート名を右クリック >「名前を変更」で、「テンプレ」に変える
③ 左下の「+」でシートを1枚足し、名前を「Logs」にする
④ 「テンプレ」に、今使っている請求書と同じ形を作る(宛名・品目・数量・単価・金額・振込先)
⑤ 毎月変わる3つのマスは空けておき、その場所を控える

| 空けておくマス | 入る物 | 例(2026年2月1日に動いた時) |
|---|---|---|
| F4 | 請求No | 202601100 |
| F5 | 発行日(前月の末日) | 2026年01月31日 |
| B22 | お支払期限(当月の末日) | 2026年02月28日 |
マスの場所は、自分の請求書に合わせて変えて構いません。 手順2のコードの一番上で、その場所を書き換えます。
手順2: コードを貼る
① スプレッドシートの上のメニュー「拡張機能」を押す
② 「Apps Script」を押す。 新しいタブで、コードを書く画面が開きます

③ 左の「コード.gs」を開き、最初から入っている中身を全部消して、この手順の最後にある「貼るコード」を貼る
④ 一番上の「ここだけ自分の物に書き換える」の6行を、自分の物に変える。 送り先(TO)は、最初は自分のアドレスだけにしておきます
⑤ 保存のマーク(または Ctrl+S)を押して保存する

⑥ 左の歯車のマーク「プロジェクトの設定」を開く
⑦ タイムゾーンが「(GMT+09:00) 日本標準時 – 東京」になっているか確かめる。 違っていたら変える

⑦のタイムゾーンは飛ばさないで下さい。 ニューヨークのままだと「毎月1日の8時」がニューヨークの8時(日本の夜)になり、前月の計算もずれます。 この記事のために作った時も、最初はニューヨークになっていました。
貼るコード
/**
* 毎月1日に、前月分の請求書を作ってメールで送る
* 先にスプレッドシートへ「テンプレ」(請求書のひな形)と「Logs」(記録)の2枚を作っておく
*/
// ===== ここだけ自分の物に書き換える =====
const TO = 'jibun@example.com'; // 送り先。 最初は自分だけにして、確かめてから「相手,自分」にする
const ATENA = '株式会社〇〇 御中'; // メール本文の宛名
const ITEM = '月額サポート費'; // 件名とPDFの名前に入れる品目
const CELL_NO = 'F4'; // 請求Noを入れるマス
const CELL_ISSUE = 'F5'; // 発行日を入れるマス
const CELL_DUE = 'B22'; // お支払期限を入れるマス
// =======================================
/** 本番: 毎月1日にトリガーから動く */
function main() {
run(new Date(), true);
}
/** 試験: 2026年2月1日に動いた事にして、メールは送らない */
function testRun() {
run(new Date(2026, 1, 1), false);
}
/** 毎月1日 8時台に main を動かす設定(最後に1回だけ実行する) */
function setTrigger() {
// 2回押しても毎月2通にならないよう、前に作った main のトリガーを消してから作る
ScriptApp.getProjectTriggers()
.filter(t => t.getHandlerFunction() === 'main')
.forEach(t => ScriptApp.deleteTrigger(t));
ScriptApp.newTrigger('main').timeBased().onMonthDay(1).atHour(8).create();
}
function run(baseDate, send) {
ScriptApp.requireAllScopes(ScriptApp.AuthMode.FULL); // 許可が足りない時は、ここで全部の許可を求めて止まる
try {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const prev = new Date(baseDate.getFullYear(), baseDate.getMonth() - 1, 1); // 前月の1日
const name = fmt(prev, 'yyMM'); // シート名(例: 2601)
log('開始(' + fmt(baseDate, 'yyyy/MM/dd') + ' に動いた扱い)');
// 1. 「テンプレ」をコピーして、前月の年月の名前を付け、一番左に置く
const old = ss.getSheetByName(name);
if (old) ss.deleteSheet(old); // 同じ月をやり直した時は作り直す
const sheet = ss.getSheetByName('テンプレ').copyTo(ss).setName(name);
ss.setActiveSheet(sheet);
ss.moveActiveSheet(1);
log('シート「' + name + '」を作成しました');
// 2. 請求No・発行日(前月の末日)・お支払期限(当月の末日)を入れる
const no = fmt(prev, 'yyyyMM') + '100';
const issue = new Date(prev.getFullYear(), prev.getMonth() + 1, 0);
const due = new Date(baseDate.getFullYear(), baseDate.getMonth() + 1, 0);
sheet.getRange(CELL_NO).setNumberFormat('@').setValue(no);
sheet.getRange(CELL_ISSUE).setNumberFormat('@').setValue(fmt(issue, 'yyyy年MM月dd日'));
sheet.getRange(CELL_DUE).setNumberFormat('@').setValue(fmt(due, 'yyyy年MM月dd日'));
SpreadsheetApp.flush(); // PDFにする前に、書き込みを確定させる
log('請求No ' + no + '・発行日・お支払期限を入れました');
// 3. そのシートをA4縦のPDFにする
const url = 'https://docs.google.com/spreadsheets/d/' + ss.getId() + '/export?format=pdf'
+ '&gid=' + sheet.getSheetId() + '&size=A4&portrait=true&fitw=true&gridlines=false'
+ '&printtitle=false&sheetnames=false&pagenum=false&fzr=false';
const label = fmt(prev, 'yyyy年MM月度');
const token = ScriptApp.getOAuthToken();
const pdf = UrlFetchApp.fetch(url, { headers: { Authorization: 'Bearer ' + token } })
.getBlob().setName('請求書_' + label + ITEM + '.pdf');
log('PDFを作成しました: ' + pdf.getName());
// 4. メールで送る(試験の時は送らない)
if (!send) {
log('試験なのでメールは送りません');
return;
}
MailApp.sendEmail(TO, '【請求書】' + label + ' ' + ITEM,
ATENA + '\n\n' + label + 'の' + ITEM + 'につきまして、請求書を添付にて送付いたします。\n'
+ 'つきましては、期日までのご入金をお願い申し上げます。\n',
{ attachments: [pdf] });
log('メールを送りました: ' + TO);
} catch (e) {
log('止まりました: ' + e.message, 'ERROR');
throw e;
}
}
/** やった事を「Logs」シートに1行ずつ残す */
function log(message, level) {
SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Logs')
.appendRow([new Date(), level || 'INFO', message]);
}
/** 日付を、日本時間の決まった形の文字にする */
function fmt(date, pattern) {
return Utilities.formatDate(date, 'Asia/Tokyo', pattern);
}
自分で直すのは、一番上の6行だけです。 その下は、上の図の流れ(コピー → 番号と日付 → PDF → メール → 記録)をそのまま書いています。
AI に書いてもらう時のプロンプト
このコードは、Gemini などの AI に頼んでも書いてもらえます。 「送る日を25日にしたい」「マスの場所が違う」など、自分の請求書に合わせて変えたい時は、下のプロンプトを自分の物に書き換えて、AI に渡して下さい。
Google スプレッドシートの「拡張機能 > Apps Script」に貼る、
Google Apps Script のコードを書いて下さい。
【スプレッドシートの作り】
・「テンプレ」シート: 請求書のひな形。
F4 に請求No、F5 に発行日、B22 にお支払期限を入れる。
それ以外のマスは触らない
・「Logs」シート: 記録用。 A列に日時、B列に INFO か ERROR、
C列にメッセージを1行ずつ足す
【やってほしい事】
1. 毎月1日の朝8時台に動く
2. 「テンプレ」をコピーして、前月の年月の名前を付け、一番左に置く。
(2026年1月分なら「2601」)
同じ名前のシートがあれば、消してから作り直す
3. 請求Noは、前月の年月6桁の後ろに「100」を付けた物(例: 202601100)
発行日は前月の末日、お支払期限は当月の末日
日付は「2026年01月31日」の形の文字で入れる
4. そのシートを A4 縦の PDF にする(枠線なし・幅に合わせる)
5. PDF を添付してメールを送る。
件名は「【請求書】2026年01月度 月額サポート費」の形
6. やった事を「Logs」に1行ずつ記録し、止まった時は理由を ERROR で残す
【その他】
・日付は日本時間(Asia/Tokyo)で扱う
・送り先・宛名・品目・マスの場所は、コードの一番上にまとめる
・日付を固定して、メールを送らずに試せる関数も作る
・毎月1日8時台に動かすトリガーを作る関数も作る
・メールは MailApp で送る(Gmail を読む権限を求めないため)
・コードは1つのファイルにまとめて、全文を出す
コツは、【スプレッドシートの作り】で、どのシートのどのマスに何があるかを先に書く事です。 ここが無いと、AI はマスの場所を想像で書くしかありません。
AI が書いたコードも、次の手順3と同じく、まずはメールを送らない試験から動かして下さい。 出来たシートと「Logs」の記録を見れば、日付や番号のずれにすぐ気付けます。 コードを貼り替えると、もう一度「承認が必要です」が出る事があります。 メールの送り方など、使う部品が変わると必要な権限も変わるためで、手順3の③と同じように許可すれば進めます。
手順3: 試しに動かす(メールは送らない)
① 画面の上の「実行」の右にある関数の選択で「testRun」を選ぶ
② 「実行」を押す

③ 初回だけ「承認が必要です」と出るので、「権限を確認」を押して自分のアカウントを選び、許可する

③は、メールを送ったりスプレッドシートを読み書きしたりする権限を、このコードに渡す確認です。 個人の Gmail のアカウントだと「このアプリは Google で確認されていません」という画面が出る事があります。 自分で書いたコードなので、「詳細」から先に進んで許可して下さい。 会社の Google Workspace の中で作って、同じ会社の人が使う場合は、この画面は出ません(Apps Script のドキュメント)。
許可する前に、出てくる権限が「スプレッドシートの読み書き」「メールの送信」「外部のサービスへの接続(PDFを作るのに使う)」「自分がいない時の実行(毎月動かすのに使う)」の4つだけか見て下さい。 知らない人から渡されたコードでは、許可しないで下さい。 項目ごとにチェックを付ける画面の時は、4つ全部にチェックを付けて下さい。 1つでも足りないと、このコードは何もせずに止まり、もう一度許可を求めます。
④ ブラウザのスプレッドシートのタブに戻ると、一番左に「2601」というシートが出来ていて、「Logs」に記録が並んでいる


⑤ 中身を確かめたら、試しに出来た「2601」は、下のタブを右クリック >「削除」で消して構いません
手順4: 自分宛てに1回送ってみる
① 送り先(TO)が自分だけになっているか、もう一度確かめる
② 関数の選択で「main」を選び、「実行」を押す
③ その日の日付で前月分の請求書が作られ、PDF付きのメールが自分に届く(例えば10月8日に押すと、9月分の「2609」が作られます)
④ 届いたPDFの見た目と、件名・本文を確かめる

問題なければ、TO を「相手のアドレス,自分のアドレス」(カンマ区切り)に書き換えて保存します。 試しに出来たシートは消して構いません。 相手のアドレスを入れた後は、main を手で「実行」しないで下さい。 押したその場で、相手に送られます。
手順5: 毎月動かす設定をする
① 関数の選択で「setTrigger」を選び、「実行」を1回だけ押す
② 左の時計のマーク「トリガー」を開き、「main」の行が1つ出来ていれば完了
③ 止めたい時は、その行の右端の︙を押して「トリガーを削除」を選ぶ

これで毎月1日の8時台に、前月分の請求書が作られて送られます。 「8時」と指定しても、動くのは8時から9時の間のどこかです(分を指定しない場合、Google 側で分がランダムに決まる仕様です。 出典: Apps Script のリファレンス)。 朝イチに相手に届けば良い請求書なら、これで十分です。
setTrigger は、前に作ったトリガーを消してから作り直すので、2回押しても毎月2通にはなりません。 念のため、「トリガー」の画面で「main」の行が1つだけか確かめて下さい。
作る前に決めておく事
請求番号の付け方
この例では「請求する月+100」(2026年1月分なら 202601100)にしました。 相手が1社なので、月が変われば番号は重なりません。 相手が複数になるなら、番号の台帳をスプレッドシートに持って、通し番号で振る形にします。
送る前に、人が見るかどうか
この例は、確認なしでそのまま送っています。 金額も相手も毎月同じなので、見る所が無いからです。 金額が毎月変わる請求書なら、「作る」までを自動にして、送るのは人が確認してからにします(作り方は下の「よくある質問」)。
失敗した時に、誰が気付くか
自動の仕組みで一番怖いのは、黙って止まる事です。 この例では、送り先に自分も入れて、毎月1日に自分にも同じメールが届くようにしました。 届かなければ、何かが止まっているという事です。 止まった時は「Logs」に「止まりました」と理由が残るので、どこで止まったかもすぐ分かります。
誰が編集できるか
このスプレッドシートを編集できる人は、貼ったコードも書き換えられます(Apps Script のドキュメント)。 そして毎月の自動実行は、トリガーを作った人の権限で動きます(トリガーのドキュメント)。 請求書のスプレッドシートは、編集できる人を自分と、任せられる担当者だけにして下さい。 見るだけの人にもコードは見えるので、パスワードなどはコードに書かないで下さい。
よくある質問
今使っている Excel の請求書の書式は使えますか?
使えます。 Excel のファイルをスプレッドシートに変換して、「テンプレ」にします。 その上で、毎月変わる3つのマスの場所を、コードの一番上に書くだけです。 ただし、変換すると印刷の見た目が少し変わる事があるので、手順4で一度 PDF にして確かめて下さい。
毎月、金額が変わる場合は?
金額や品目を別のシート(請求のデータ)に置いて、そこから「テンプレ」に差し込む形にします。 この記事の例は金額が毎月同じ契約だったので、ひな形に書いたままにしています。 金額が変わる場合は、次の「送る前に確認したい」形とセットで考えるのがオススメです。
送る前に、自分で確認したいのですが。
コードの「MailApp.sendEmail」を「GmailApp.createDraft」に変えると、送らずに Gmail の下書きに入ります。 中身を見てから、自分で送信ボタンを押す形に出来ます。 この時は下書きを作るために、Gmail を読み書きする権限も求められます。
インボイスの登録番号はどう載せますか?
登録番号のように毎月変わらない項目は、「テンプレ」に書いておけば、毎月そのまま請求書に載ります。
まとめ
- 請求書の元になるデータは、1つのスプレッドシートの「テンプレ」に全部置く。 毎月変わるのは請求No・発行日・お支払期限の3マスだけ
- コードは「拡張機能 > Apps Script」に貼り、一番上の6行とタイムゾーンを直す
- testRun(送らない)→ main(自分宛て)→ setTrigger(毎月)の順に動かす
- 自分の請求書に合わせて変える時は、スプレッドシートの作りを書いたプロンプトで AI に頼み、同じく送らない試験から動かす
- 自分にも控えのメールを送り、「Logs」に記録を残すと、止まった時にすぐ気付ける
- スプレッドシートを編集できる人は絞り、許可する前に権限の一覧を見る
請求書のように毎月決まって発生する作業は、同じ考え方で自動に出来ます。 自社の業務に合わせて作ってほしい場合は構築代行を、社員が自分で組めるようになりたい場合は研修をご覧下さい(事務編では、請求書の管理台帳づくりや支払期限のリマインドの自動化を実際に組みます)。 Google のサービス全体の整え方は Google Workspace活用ガイド にまとめています。