- 希望がそろってから、本当にしんどい仕事が始まる
- 結果から言います = 1回押すと、案・不足・候補・公平が1画面に出ました
- 先に約束します = AIに、シフトの割付は決めさせません
- 今回使うのは3つだけ = 初期化・案を作る・確定する
- 用意するもの = 新しいスプレッドシート1枚
- ① 初期化する = 台紙をまとめて作る
- ② 必要人数とスタッフを入れる
- ③ 希望を○・×・△・?で入れる
- ④ 「今週のシフト表を作る(案)」を押す
- 第二波 = ×を1つ○にしたら、不足が5から4へ減りました
- 最後は人が確定する = 案と確定を分けました
- 裏側のしくみ(ここは読み飛ばしてOK)
- 正直にできないこと(先に言っておきます)
- AIに渡すプロンプト(全文・中身は読まなくて大丈夫)
- 次回予告 = 「金曜は無理です」を、そのまま読ませる
希望がそろってから、本当にしんどい仕事が始まる
「来週の希望を出してください」
返事が集まる。月曜の朝は○、火曜の昼は×、土曜なら△。そこまでは、まだ入口です。
本当に頭を使うのは、そのあとです。
必要な人数を満たしながら、×の人は避ける。週の上限を超えないようにする。同じ人ばかり土日に寄せない。一つのマスに誰かを入れると、別のマスが足りなくなる。そこを直すと、今度は別の人の回数が多くなる。
シフト表のつらさは、名前を書くことではなく、表の全部を頭に載せたまま何度も組み替えることでした。
わたし自身は、パート・アルバイトのシフトを実務で管理している人ではありません。だから今回、分かったふりをせず、架空の「テスト店舗」と5人のスタッフを用意しました。わざと土日に人が足りなくなる希望を入れ、1か所だけ希望が変わったら表がどう動くかまで、実機で確かめました。
作りたかったのは、人の代わりに勝手に決める箱ではありません。
最初の組み合わせを引き受け、不足と判断材料を、人に返してくれる秘書です。
結果から言います = 1回押すと、案・不足・候補・公平が1画面に出ました
スタッフ5人の希望と、曜日・時間帯ごとの必要人数をスプレッドシートに入れます。
上のメニューから、「今週のシフト表を作る(案)」を押しました。

数秒後、『シフト表(案)』に1週間分の名前が入りました。
出てきたのは、名前を並べただけの表ではありません。
- 誰がどの曜日・コマに入るかを見渡せる色つきの週間表
- 必要人数に届かなかった赤いマス
- そのマスについて、本人確認や相談の手がかりになる候補ヒント
- 人ごとの割当数・土日数・△を使った回数が分かる公平サマリー
- まだ本人確認が必要な「?」の一覧
今回の最初の結果は、必要人数に対して、合計5人分の不足でした。今回のサンプルでは、5つのマスに1人ずつ足りない状態です。

秘書は、人数が足りないのに、もっともらしい完成表にはしませんでした。×を勝手に破ることもありません。
足りないところは赤いまま。「?を確定すれば候補になり得る」と、最後に人が判断するための材料を残します。候補欄に出た人を、そのまま入れてよいという意味ではありません。本人確認や相談の手がかりです。
そして今回も、わたしはコードを一行も書いていません。コードを書いたのはAIです。わたしがしたのは、作ってほしいものと、破ってほしくない約束を言葉にして、返ってきた完成形を貼り、実際に動かして確かめることでした。
先に約束します = AIに、シフトの割付は決めさせません
「AI×GASでシフト表」と聞くと、AIが人の希望を見て、いい感じに割り振る姿を想像するかもしれません。
この秘書は、その作り方をしていません。
AIが得意なのは、話し言葉の希望を読み取るような「言葉の仕事」です。一方で、×を絶対に破らない、週上限を守る、同じ入力なら同じ結果にする、といった厳密な組み合わせを、毎回ぶれずに扱う仕事は別物です。
そこで、割付そのものは、スプレッドシートの裏側で動く固定ルール(GAS)で計算します。
ルールは、できるだけ短く説明できる形にしました。
- 入れる人が少ない、埋めにくいマスから先に見る
- その時点で割当が少ない人を優先する
- 土日の偏りも数える
- ○を△より先に使う
- ×・空欄・未確定の「?」には入れない
- それでも足りなければ、不足として赤く残す
乱数は使いません。同じ希望と設定なら、同じ案になります。
だから「AIが最適解を出しました」とは言いません。これは、説明できる順番で作る割付案です。最適なシフトかどうか、公平だと納得できるかどうか、最後に決めるのは人です。
今回使うのは3つだけ = 初期化・案を作る・確定する
今日使うメニューは3つだけです。
- 初期化(シートを作る)
- 今週のシフト表を作る(案)
- この案を確定にする
核の体験だけなら、Webアプリとして公開する作業はありません。新しいスプレッドシートを1枚作り、AIが書いたコードを貼り、初回の許可を済ませれば試せます。
用意するもの = 新しいスプレッドシート1枚
まず、Googleドライブで新しいスプレッドシートファイルを1つ作ります。名前は「シフト表秘書」など、あとで分かるもので大丈夫です。中のシート(タブ)は、初期化メニューが入力用の4枚を用意します。
この記事の後半に載せる「AIに渡すプロンプト」を、ChatGPTやGeminiへ丸ごと貼ります。返ってきたコードを、スプレッドシートの[拡張機能]→[Apps Script]に貼り付けて保存します。
スプレッドシートとApps Scriptのタイムゾーンは、どちらもAsia/Tokyoにそろえてください。曜日や締切を扱うため、ここがずれると「同じ日」のつもりでも判定がずれることがあります。
保存後にシートを開き直すと、上部に「シフト表秘書」メニューが増えます。
① 初期化する = 台紙をまとめて作る
最初に、「初期化(シートを作る)」を押します。
初回だけ、Googleの許可画面が出ます。画面に沿って承認し、もう一度「初期化」を押します。
すると、入力に使う4枚の台紙が作られます。
- 設定:店舗名、対象週、コマ名、週上限の初期値など
- 必要人数:月〜日の各コマに何人必要か
- スタッフ:名前、メール、週上限など
- 希望:スタッフごとの○・×・△・?
『シフト表(案)』は、初めて案を作ったときに追加されます。『確定シフト』も、初めて案を確定したときに追加されます。最初から空の出力先を増やさず、必要になったときだけ作る形です。
初期化は、無いシートを作る方式です。すでにある同名シートを勝手に消すためのボタンではありません。
まず試すだけなら、メニューの「テスト_サンプル一式を入れる」を使えます。架空の5人と、わざと不足が出る希望が入ります。記事の図版も、このテストデータで作りました。
② 必要人数とスタッフを入れる
『必要人数』には、月〜日と朝・昼・夜の交わるマスへ、必要な人数を入れます。
『スタッフ』には、名前と週の上限を入れます。育てる編で個別連絡を使う場合はメールアドレスも使いますが、今日の割付だけなら名前と上限が中心です。
この秘書は、1日を1〜3個のコマに分ける方式です。初期設定は「朝・昼・夜」ですが、「1限・2限・3限」などにも置き換えられます。30分刻みで出退勤時刻が人ごとに違うシフトは、今回の守備範囲ではありません。
③ 希望を○・×・△・?で入れる
『希望』シートでは、プルダウンから4つの印を選びます。
- ○:入れる
- ×:入れない
- △:できれば避けたいが、入ることはできる
- ?:本人への確認が必要
空欄は×として扱います。「?」も、○・×・△のどれかに人が確定するまでは×扱いです。
分からないものを、秘書の都合で「入れる」にしないためです。
④ 「今週のシフト表を作る(案)」を押す
準備ができたら、メニューの「今週のシフト表を作る(案)」を押します。
『シフト表(案)』は、押すたびに今の設定と希望からゼロから組み直されます。以前の案を少しずつ継ぎ足していくのではありません。
これは便利な一方で、正直な注意点でもあります。希望を1セル直しただけでも、関係なさそうな人の割当が組み替わることがあります。毎回、表全体をもう一度計算するからです。
そのため、スタッフへ共有してよいのは、この案ではありません。人が確認して、必要なら手で直し、次の「確定」を済ませてからです。
第二波 = ×を1つ○にしたら、不足が5から4へ減りました
最初の案では、全体で合計5人分が不足していました。その中に、土曜の朝の1人分も含まれていました。
そこで、『希望』シートに戻り、安藤さんの土曜・朝を×から○へ変えました。

そして、もう一度「今週のシフト表を作る(案)」を押します。
今度は土曜の朝に、井上さんと安藤さんが入りました。そこは緑のマスに変わり、必要人数に対する不足は合計5人分から4人分へ減りました。

希望が一つ変わるたび、頭の中で全部のつじつまを取り直す。その最初の組み替えを、ボタンへ渡せました。
もちろん、不足はまだ4コマあります。秘書は魔法の人員を連れてきません。
でも、どこが足りないか、相談の手がかりがあるか、誰に何コマ・土日・△が割り当てられたかが、同じ画面にそろっています。
「何となく埋まらない表」とにらめっこする時間が、「この赤い4か所を、どうするか」と考える時間に変わりました。
最後は人が確定する = 案と確定を分けました
案を確認したら、メニューの「この案を確定にする」を押します。
『確定シフト』へ、対象週と割付がコピーされます。このシートは、人が手で直してよい場所です。秘書は、ここを勝手に組み直しません。『シフト表(案)』は共有せず、人が確認・手直ししたあと、『確定シフト』だけを共有します。

「秘書が案を作る」と「人が決める」を、シートそのものから分けました。
不足を埋めるか。△の人へ相談するか。「?」を本人に確かめるか。労務上の条件や、人間関係まで含めて問題ないか。そこは、人の仕事として残します。
裏側のしくみ(ここは読み飛ばしてOK)
割付は、入れる候補が少ないマスから順に見ます。候補を置くたび、残りのマスの埋めにくさを計算し直します。
候補が複数いるときは、割当数、今週の土日数と直近4週の繰越土日数、○か△か、スタッフ表の並び順、という決まった順で選びます。最初の割付後には、一人を別のマスへ移し、空いた場所へ別の人を入れる「1段の入れ替え」も試します。
それでも埋まらなければ、赤い不足として残します。
この計算部分は、スプレッドシートから切り離した形でも試せるようにしました。余裕がある週、土曜が足りない週、1段の入れ替えで埋まる週、不足が残る週の4ケースを機械的に検算し、同じ入力を2回入れたとき同じ結果になることも確認しています。
難しい言葉を覚える必要はありません。大事なのは、AIの気分ではなく、書いてある順番で動き、足りないときは足りないと言うことです。
正直にできないこと(先に言っておきます)
- 30分刻みなど、人ごとに自由な開始・終了時刻を扱うシフトではありません
- 連勤、休憩、勤務間インターバルなどの労務条件は計算しません
- 同じ日に複数コマ入ることを禁止していません
- 週の開始は月曜固定です
- 公平の基準は、割当数・土日数・○と△など、この記事で説明した範囲です
- ×・空欄・未確定の「?」を破って、人数だけを埋めることはしません
- 1セルの変更でも、案全体が組み替わることがあります
- 最後の確認と確定は、人が行います
- 次回扱う自然文メモの読み取りでは、メモ本文がGemini APIへ送られます。メモに個人情報を書かない運用が必要です
これは、労務管理システムの完成品ではありません。
秘書が埋めるのは、最初の9割。最後のひと押しは、人。
そこを隠さないからこそ、毎週の下書きを任せられる道具になりました。
AIに渡すプロンプト(全文・中身は読まなくて大丈夫)
下の枠を途中で切らず、丸ごとコピーしてChatGPTやGeminiへ貼ってください。長いのは、作ってほしい機能だけでなく、「勝手に決めない」「消さない」「自動送信しない」という約束まで先に渡しているからです。
あなたはGoogle Apps Script(GAS)の熟練エンジニアです。次の仕様をすべて満たす、スプレッドシートに紐づけて使う「シフト表 秘書」の完成形コードを、1つの.gsファイルとして書いてください。非エンジニアがコードを丸ごと貼って使う前提です。関数名、シート名、メニュー名、画面文言は指定どおりにし、コード内コメントも実際の動作と一致させてください。未実装の機能をコメントだけで宣言しないでください。
【最重要の設計思想】
- シフトの割付をAI(Gemini)に決めさせない。厳密な組合せ制約は、SpreadsheetAppや外部AIに依存しない純粋な決定論コードで計算する。
- 乱数・現在時刻・API応答を割付順位に使わない。同じ入力なら必ず同じ案になる。
- AIを使うのは、①自然文の希望メモを○×△?へ構造化すること、③メールの挨拶文の骨子を作ることだけ。AIの出力は必ず検証し、失敗時は手入力または定型文へフォールバックする。
- ×、空欄、?を勝手に出勤可へ変えない。足りないときは不足として赤く表示する。
- 「案」と「確定」を分離する。案は毎回ゼロから再描画し、確定シフトは人が確認・手直しして確定した聖域とする。
【絶対にしないこと・正直な安全境界】
- 割付をGeminiへ依頼しない。割付ロジックはコードだけで行う。
- ③のGemini呼出しには、実在の個人名、宛先、具体的な勤務日・コマ、勤務パターンを渡さない。AIにはプレースホルダ(【宛名】【明細】【店名】【署名】)入りの連絡文の骨子生成指示だけを渡し、実データの差し込みはコード側で行う。
- ①でGeminiへ渡すのは希望メモ本文とマス名一覧だけ。メモ本文には利用者が個人情報を書かない運用であることをコメントと画面で正直に案内する。
- 対人メールは自動送信せず、GmailApp.createDraftで下書きまでにする。利用者が本文を確認してから送信する。
- 公開Webアプリの提出は、既存シートを上書きせず「提出ログ」へappendRowするだけにする。表示名の選択式であり、本人確認・なりすまし防止はしない身内運用だとフォームに明記する。
- 初期化は既存の同名シート・データを消さない。存在しないシートだけを作るfind-or-createにする。
- 週送りは、消す前に確定シフト・希望グリッド・希望メモを「アーカイブ」へ退避し、確認ダイアログでYESを選んだときだけクリアする。
- APIキーをコードに直書きしない。Geminiキーはスクリプトプロパティ GEMINI_API_KEY から読む。
【時刻・共通定数】
- `var TIMEZONE = 'Asia/Tokyo';`を定義し、日付表示・週判定・相対締切を東京時間で統一する。利用者へ、スプレッドシートとApps ScriptプロジェクトのタイムゾーンもAsia/Tokyoにそろえるようコメントで案内する。
- シート名は次のとおり。設定、必要人数、スタッフ、希望、シフト表(案)、確定シフト、提出ログ、希望メモ、アーカイブ。
- `var 曜日一覧 = ['月','火','水','木','金','土','日'];`
- 希望値は `['○','×','△','?']` の4値。空欄は×扱い。
- スタッフ列は、名前=1、メール=2、週上限=3、連絡記録=4、繰越土日数=5、表示名=6、備考=7。
【onOpenと初期化】
- `onOpen()`でメニュー「シフト表秘書」を作る。核の項目は「初期化(シートを作る)」「今週のシフト表を作る(案)」「この案を確定にする」。育てる編の項目として「希望メモをAIで読み取る」「提出ページのURLを表示」「確定シフトをひとりずつの下書きにする」「未提出の見回りを予約する」「未提出の見回りを解約する」「来週へ送る」「テスト_サンプル一式を入れる」「テスト_割付を今すぐ試す」「シートを整える」も追加する。区切り線を使い、メニュー名と関数名を一致させる。
- `初期化()`が最初に作るのは**設定・必要人数・スタッフ・希望の4枚だけ**。シフト表(案)は割付実行時、確定シフトは確定実行時、提出ログ・希望メモ・アーカイブは必要時に作る。
- 設定はA列項目・B列値の縦持ち。項目は店舗名、週の開始日(月曜)、コマ1の名前、コマ2の名前、コマ3の名前、週上限の既定値、提出締切(例「毎週土 18:00」)、店長名。初期値は店舗名=テスト店舗、コマ=朝/昼/夜、週上限=5、その他は空欄。
- 必要人数は1行目「コマ\曜日」+月〜日、行は有効なコマ名、0は募集しないマス。
- スタッフは見出し「名前」「メール」「週上限」「連絡記録」「繰越土日数(直近4週・自動)」「表示名」「備考」。スタッフ行順は割付の最後のタイブレークなので、並べ替えると結果が変わると注記する。表示名はフォームに出す名前で、空欄なら正式名を使う。同じ表示名は受付停止の原因になるので重複禁止と注記する。
- 希望は1列目スタッフ名、続いて「月-朝」など曜日-コマの列、最後に提出日時。○×△?のプルダウンを付ける。入力規則はsetAllowInvalid(true)とし、未知値は割付時に×扱い+警告欄に表示する。
- 初期化は何度実行しても既存データを触らず、作成したシートだけをalertで報告する。
【設定・入力の読み取り】
- 設定は各実行時に毎回シートから読む。週開始日は月曜へ矯正する。週締切は絶対日時ではなく「毎週X曜 HH:mm」を対象週の月曜から計算する。週送り後も締切が翌週に追随する。
- 必要人数は曜日×コマのグリッドから、必要人数が1以上のマスだけを固定順(曜日→コマ)で作る。コマ名は初期化時の設定と既存見出しを一致させる。
- スタッフは行順のまま読む。週上限が不正・負数なら0、繰越土日数は数値として読む。
- 希望値は○/◯/〇を○、×/✕/✖/x/X等を×、△/▲を△、?/?を?へ正規化する。空欄は×。その他の文字は×扱いにし、元の文字とマスを警告に残す。
【決定論の割付エンジン】
- `割付を計算_(入力)`をSpreadsheetApp非依存の純関数として実装し、入出力はプレーンなオブジェクトだけにする。Nodeで読み込めるよう、ファイル末尾にmodule.exportsの出口を置く(GAS実行時は何もしない)。
- 入力は `マス一覧:[{キー,曜日,コマ,必要}]`、`スタッフ:[{名前,週上限,繰越土日}]`、`希望:{名前:{マスキー:生値}}`。
- 前処理で希望を正規化し、?の個数と未知値警告を数える。
- 第1段はmost-constrained-first。各マスについて「その時点で置ける候補数÷必要人数」を計算し、最小のマスから処理する。マスを埋めるたびに候補数を再計算する。同率は固定されたマス一覧の先勝ち。
- 候補は、そのマスで○または△、まだそのマスに割り当てられておらず、週上限未達のスタッフ。×・空欄・?は候補に含めない。
- 第2段は公平キーの辞書順で候補を選ぶ。キーは、割当数の少なさ→今週の土日数+繰越土日数の少なさ→そのマスの○を△より優先→スタッフ行順。△で割り当てた回数は我慢数として台帳に記録する。
- 必要人数まで候補がいなければ、そのマスの不足人数を記録する。不足を隠したり、×を破って埋めたりしない。
- 第3段は1段スワップ。不足マスXに出られるが別マスYに入っているAをXへ移し、Yに出られる別人Bを入れられる場合だけ交換する。走査順は不足マス→スタッフ行順→Yの固定順→Bの行順。成立ごとに先頭から再走査し、成立合計200回で打ち切る。土日数・我慢数・不足数を交換に合わせて更新する。
- 出力は `割当`、`不足`、`ヒント`、`公平`、`警告`、`スワップ成立数`。不足マスのヒントは最大3名で、?を確定すれば候補になる人、週上限に到達した人を示す。
- このアルゴリズムを「最適解」と呼ばない。説明可能な固定ルールによる割付案であるとコメントする。
【核:案の生成と確定】
- `今週のシフト表を作る()`は設定・必要人数・スタッフを読み、提出ログがあれば先に最新提出を希望へ反映し、希望を読み、純粋な割付エンジンを実行し、シフト表(案)へ一括描画する。
- シフト表(案)は対象週ラベル、曜日+日付、色付きの週間表、充足=緑、不足=赤、募集なし=灰色、不足と候補ヒント、公平サマリー、読めなかった希望の警告、?残り一覧を表示する。
- 案シートは毎回clearしてゼロから再描画する揮発ビュー。数式バー等に「同じ入力なら同じ表」「1セル変更で無関係な割当も変わり得る」「スタッフに共有してよいのは確定シフトだけ」と明記する。
- `この案を確定にする()`は案の週・コマ構成を検証し、既存の確定シフトがある場合は上書き確認ダイアログを出す。人がYESを選んだ場合だけ確定シフトを上書きし、案を週ラベル付きでコピーする。確定シフトは人が手直しでき、秘書が案の再生成で勝手に触らない聖域と注記する。
【①希望メモのAI構造化】
- `希望メモをAIで読み取る()`は、希望メモシートのB列の名前・C列の原文を読み、処理済み行を飛ばし、Geminiへ本文とマス名一覧だけを渡す。
- プロンプトは「金曜ダメです」なら金曜全コマを×、「土曜昼まで」等を該当マスへ反映、触れられていないマスは出力しない、確信が持てないものは?とする指示にする。
- 返答JSONは `{"読み取り":[{"マス":"金-朝","値":"×"}]}`。未知マスは捨て、4値以外は?にする。名前照合・列見出し照合で希望へ流し込み、処理結果を記録する。
- AI失敗・キー未設定でも原文は残し、手入力を案内する。?は人が○×△へ確定するまで×扱い。
【②スマホ提出ページ】
- `doGet(e)`は設定を毎回読み、初期化前・マスまたはスタッフなしなら準備中、相対締切超過なら受付終了、通常なら提出フォームを返す。締切はページ表示時だけでなく送信直前にも再チェックする。
- フォームはスマホ用1カード。表示名プルダウン、曜日+日付×コマのタップグリッド、○△×?、任意の自然文メモ、提出ボタンを出す。タップは未入力→○→△→×→?の順で循環。未入力は×扱いと明記する。
- フォームに正式名簿を出さず表示名だけを出す。ただし選択式であり、なりすまし対策はない身内向けと明記する。
- `提出ログ`は必要時に見出し付きで作る。`希望を記録する(data)`は公開Webから呼ばれる提出入口で、ScriptLockを取得し、設定読取→締切再チェック→表示名と正式名の照合→値の検品→appendRowだけをロック内で行う。既存シートの希望セルは直接上書きしない。
- 知っているマスと○×△?だけを受け付け、未知キー・未知値は捨てる。メモは最大500文字。提出日時、正式名、対象週キー、希望JSON、メモ有無を提出ログへ追記する。メモがあれば希望メモにも追記する。
- 同一週に同じ人が複数回提出した場合、提出ログを上から読み、後の行(最新提出)を採用する。本人の希望グリッドは最新提出の全マスをいったん空欄(=×)へ戻してから反映する。
- LockServiceの取得失敗時は、混雑している旨を返す。ロックは必ずfinallyで解放する。
- 公開Webから呼ばれる提出入口以外のメニュー処理には、SpreadsheetApp.getUi()等の編集画面ガードを置く。公開名のトリガーハンドラ「未提出の見回りを送る」は自分宛メール以外の書込み・対人送信をしない。
【③確定シフトからGmail下書き】
- `確定シフトをひとりずつの下書きにする()`は確定シフトと設定の週を照合し、今週割当があり、メール欄があり、同じ週の連絡記録がなければGmailApp.createDraftで個別下書きを作る。
- Geminiの`連絡骨子_()`へ渡すのは、プレースホルダを必ず含む短い敬体の骨子生成指示だけ。必須プレースホルダがない返答、JSON不正、キー未設定は定型文へ戻す。
- 宛名、シフト明細、店名、署名をコード側で差し込む。日付セルがDate型でも必ず東京時間の「曜 M/d」に整形し、生のDate文字列をメール本文へ出さない。
- 自動送信は禁止。Gmailの下書きを人が確認して送信する。連絡記録は上書きせず追記し、週開始日入りタグで二重下書きを防ぐ。
【④週送り・未提出見回り】
- `来週へ送る()`は実行前に確認ダイアログを出す。YESの場合のみ、確定シフト、希望、希望メモを週キー付きでアーカイブへ退避し、希望グリッド(提出日時を含む)と希望メモをクリアする。提出ログは履歴なので消さない。
- 今週の確定シフトの土日実績をスタッフごとに記録し、繰越土日数は直近4週窓だけを保持する。設定の週開始日を7日進める。相対締切も次週へ追随する。確定シフトは見比べ用に残すと案内する。
- `未提出の見回りを予約する()`は既存の同名トリガーを削除してから、`未提出の見回りを送る`を毎日17時台に1つだけ予約する(冪等)。解約関数も用意する。予約・解約は自分宛に結果メールを送る。
- `未提出の見回りを送る()`は今週の提出ログと希望シートの提出日時を数え、未提出者を実行者自身へメールする。0人でも生存報告としてメールする。失敗時も自分宛に失敗通知を送る。第三者へのメールやデータ破壊はしない。
【Gemini接続】
- `var GEMINI_MODEL = 'gemini-2.5-flash';`。APIキーはPropertiesServiceのGEMINI_API_KEY。キー未設定ならnullを返し、①は手入力案内、③は定型文で継続する。
- UrlFetchAppでv1beta generateContentへPOSTし、キーは`x-goog-api-key`ヘッダーで渡す(URLクエリに入れない)。responseMimeTypeはapplication/json、thinkingBudgetは0。成功JSONだけを採用し、429/5xxは1回だけ2秒待って再試行、それ以外は粘らず失敗にする。
【テスト用サンプル】
- `テスト_サンプル一式を入れる()`を実装する。架空のテスト店舗、架空名5人(安藤・井上・宇野・遠藤・岡田)を入れ、メールはSession.getActiveUser().getEmail()(自分宛)だけにする。土日に不足が出る必要人数と、○×△?の希望を入れる。既存スタッフデータがあるときは上書き確認を出す。
- サンプルは、初回の「今週のシフト表を作る(案)」で、必要人数に対する合計不足が5人分(このサンプルでは5マスに1人ずつ)と候補ヒント、?残り、公平サマリーが見えるようにする。安藤の土-朝を×から○へ変えて再実行すると、土-朝が井上・安藤で充足し、合計不足が5人分から4人分になるデータにする。
- `テスト_割付を今すぐ試す()`は核の割付関数を呼ぶだけにする。外部送信を伴うテスト関数は追加しない。サンプルのメールは自分宛でも、記事では架空データの実演であることを明記できるようにする。
- 割付エンジンは、余裕、土曜不足、1段スワップ成立、不足残存の4ケースをNodeで検算できる純関数にする。机上テストは4/4 PASS、同じ入力2回の結果一致を確認できる構造にする。
【実装品質・出力形式】
- GAS V8で構文エラーなく動く日本語コードにする。SpreadsheetAppの読み書きは可能な範囲でバッチ化する。
- HTMLへ値を差し込む箇所は`& < > " '`をエスケープする。テンプレートリテラル内のブラウザJS文字列で改行を表す場合は`\\n`を使い、送信ボタンが無反応になる構文エラーを起こさない。
- シートをクリアするのはシフト表(案)の再描画と、確認後の週送り対象だけ。確定シフトの上書きは人のYES確認後だけ。
- 末尾アンダースコアのヘルパーはgoogle.script.runから呼べない形で整理する。提出入口は`希望を記録する`、メニュー処理は編集画面ガード、トリガーの公開ハンドラは自分宛通知だけに限定する。
- 返答は完成した1本のコードだけ。コードを分割したり、「残りは省略」と書いたり、仕様を実装せずにコメントだけ残したりしないでください。
次回予告 = 「金曜は無理です」を、そのまま読ませる
今日は、希望を○・×・△・?で入れ、ボタンで割付案を作りました。
次は、その希望を入れる手間を一つ減らします。
これは今回の核には含めず、次回の「育てる編」で追加します。
金曜は無理です。土曜なら昼まで。日曜はたぶん大丈夫です。
こんな話し言葉を『希望メモ』へ貼り、AIに○・×・△・?の下書きへ変えてもらいます。
ただし、AIに割付はさせません。曖昧な「たぶん」は、勝手に○へもしません。
文章を読むところはAI。シフトを組むところは固定ルール。最後に決めるのは人。
この役割分担のまま、シフト表 秘書を育てていきます。
※この記事の操作はすべて無料枠の範囲で行っています。画面のお名前・メールアドレス・各種ID/URLは、マスクまたは架空のサンプルに差し替えています。画面の表示や許可画面の文言は時期や環境により変わることがあるため、最新の内容はご自身の環境でご確認ください。コードは、一行も書いていません。
#AI×GAS #応用編その5 #シフト表 #Googleスプレッドシート #GAS #非エンジニア #つまずき帳


コメント