経営企画が毎月各部門から集めるKPIのスプレッドシートについて、未提出と入力値の異常を拾い、部門ごとの督促と確認の文面を下書きする
各部門が毎月入力するKPIのシートを締切の前後に読み、未提出・空欄・桁違い・前月からの急変を拾います。部門の備考で説明が付いているかを判定し、部門ごとの督促と確認のメールを下書きにします。
- 生成AI
- ChatGPT/Claude/Gemini
- 連携・自動化
- Google Apps Script/Make/Power Automate/Python
- 対象業界
- IT・SaaS/商社/小売/製造
- 対象部門
- 経営企画
- 対象業務
- 内容確認・チェック/書類作成
- 主な課題
- データ分析に時間がかかる/期限・対応漏れが起きる/確認ミスが多い
- AIで行う処理
- 判定
- 主な効果
- 入力漏れ削減/対応スピード向上/工数削減
- 導入難易度
- ★☆☆☆☆
- 実装レベル
- 半自動化
- 費用感
- API連携(中)
- 人間の確認
- 条件付き
01導入前 / 導入後の業務フロー
- 締切の前日に、60枚のシートの「提出」のチェックを順に見て、未提出の部門を一覧にする
- 未提出の部門の担当者に、督促のメールを1通ずつ書いて送る
- 締切の当日から、提出済みのシートを1枚ずつ開き、前月の列と並べて見る
- 空欄、桁が違いそうな値、前月から大きく動いた値に印を付ける
- 印を付けた項目の備考を読み、説明が無いものを部門ごとにまとめる
- 部門の担当者に、確認のメールを書いて送る
- 返事が来たら値を直してもらい、集計のシートに取り込む
- 自動締切の前日の朝、スクリプトが60枚のシートの「提出」のチェックを読み、未提出の部門を一覧にする
- 自動未提出の部門ごとに、督促のメールの下書きを Gmail に作る
- 人経営企画が下書きを確かめて送る
- 自動締切の翌日の朝、スクリプトが提出済みのシートを読み、規則で空欄・桁違い・急変・エラーを拾う
- 自動拾った項目と、その項目の備考、KPIの定義を生成AIに渡し、説明が付いているかを判定させる
- 自動説明の無いものと判断できないものを部門ごとにまとめ、確認のメールの下書きを作る
- 自動判定の結果を「確認一覧」のシートに書き出す
- 人経営企画が確認一覧を見て、下書きを直して送る
- 人部門から返事が来たら、値を直してもらい、集計のシートに取り込む
各工程の詳しい説明を読む
- 締切の前日に、60枚のシートの「提出」のチェックを順に見て、未提出の部門を一覧にする
- 未提出の部門の担当者に、督促のメールを1通ずつ書いて送る
- 締切の当日から、提出済みのシートを1枚ずつ開き、前月の列と並べて見る
- 空欄、桁が違いそうな値、前月から大きく動いた値に印を付ける
- 印を付けた項目の備考を読み、説明が無いものを部門ごとにまとめる
- 部門の担当者に、確認のメールを書いて送る
- 返事が来たら値を直してもらい、集計のシートに取り込む
(a)桁違いを見落とす。 単位が「千円」のシートに円で入れた値、「%」の項目に小数で入れた値は、前月の列と並べて見れば気づくはずですが、60枚目には目が慣れています。 経営会議の資料になってから見つかることがあります。
(b)備考を読み落とす。 4番で印を付けた後、5番で備考を読むのを省いて確認のメールを送り、「備考に書いてあります」と返されることがあります。 部門にとっては二度手間です。
(c)連絡が項目ごとにばらばらになる。 見つけた順にメールを送ると、同じ部門に午前と午後で別の確認が届きます。部門の担当者は、何に答えればよいかを自分でまとめ直すことになります。
(d)同じ文面を毎月書いている。 督促も確認も、文面はほとんど同じです。それでも宛先と項目と値が毎回違うため、手で書いています。
- 【自動】 締切の前日の朝、スクリプトが60枚のシートの「提出」のチェックを読み、未提出の部門を一覧にする
- 【自動】 未提出の部門ごとに、督促のメールの下書きを Gmail に作る
- 【人】 経営企画が下書きを確かめて送る
- 【自動】 締切の翌日の朝、スクリプトが提出済みのシートを読み、規則で空欄・桁違い・急変・エラーを拾う
- 【自動】 拾った項目と、その項目の備考、KPIの定義を生成AIに渡し、説明が付いているかを判定させる
- 【自動】 説明の無いものと判断できないものを部門ごとにまとめ、確認のメールの下書きを作る
- 【自動】 判定の結果を「確認一覧」のシートに書き出す
- 【人】 経営企画が確認一覧を見て、下書きを直して送る
- 【人】 部門から返事が来たら、値を直してもらい、集計のシートに取り込む
3番目と8番目で、送信は必ず人が行います。 下書きは経営企画のアカウントに作り、自動では送りません。 部門長を宛先に含めるか、どこまで強く書くかは、部門との関係を知っている人が決めます。
4番目の規則と5番目の判定を分けているのも、意図してのことです。 「急変かどうか」は数字の問題なので規則で決め、生成AIには数字の計算をさせません。 生成AIが読むのは、備考の文章が急変の説明になっているかどうかだけです。
02今回想定するシステム構成
部門ごとのKPIのシート(60枚、共通のひな形) ▼【トリガー】時間主導型トリガー(10分おき。締切の前日と翌日の朝9時以降だけ処理する) Google Apps Script ├──▶ 提出のチェックを読む → 未提出の一覧 → 督促の下書き(Gmail) ├──▶ 当月・前月・前年同月・過去12か月の値を読む ├──▶ 規則で拾う(空欄・桁違い・急変・エラー・型の違い) ▼ Gemini API(構造化出力) │ 拾った項目ごとに、備考で説明が付いているかを判定 │ 部門ごとの確認の文面を下書き ▼ Google Apps Script ── 確認一覧のシートへ書き出し、Gmail に下書きを作る ▼ 【経営企画が確かめて送る】
| 役割 | 想定する製品 | 代替候補 |
|---|---|---|
| 実行環境 | Google Apps Script | Power Automate、Make、Python |
| 生成AI | Gemini API(有料の枠、構造化出力) | Claude API、OpenAI API |
| シート | Google スプレッドシート(部門ごとのKPIのシートと確認一覧) | Microsoft 365 のブック |
| メール | Gmail(経営企画のアカウントの下書き) | Outlook |
新しく足すのは、スクリプトと Gemini API の契約だけです。 部門のシートも集計のシートも、今あるものを使います。部門のシートには書き込みません。 スクリプトが書き込むのは、経営企画が持つ確認一覧のシートと Gmail の下書きだけです。
土台になるのは、Google Apps Script のインストール型トリガーです。 時間主導型のトリガーは、毎分から毎月までの間隔で関数を動かせます。インストール型トリガーは、作成した人のアカウントで実行されるとされています。下書きは、トリガーを作った経営企画の担当者の Gmail にできます。
スクリプトの実行時間には上限があります。 1回の実行は6分まで、トリガーの合計の実行時間は Google Workspace のアカウントで1日6時間までです。URL の取得(外部 API の呼び出し)は Google Workspace で1日100,000回まで、メールの宛先は1日1,500までとされています。60枚を1回の実行で処理しきれない場合に備えて、処理を分けます。 詳しくは第7章で書きます。
03どうやって実装するのか
処理の起点を決める
時間主導型トリガーを10分おきに動かし、スクリプトの中で「今日が処理する日か」「朝9時を過ぎたか」を判定します。 締切は第5営業日なので、カレンダーの日付で決め打ちできません。祝日の一覧をシートに持ち、営業日を数えて前日(第4営業日)と翌日(第6営業日)だけ処理に進みます。
| 日 | 処理 |
|---|---|
| 第4営業日 | 未提出の一覧と督促の下書き |
| 第5営業日(締切) | 何もしない(部門の入力を待つ) |
| 第6営業日 | 未提出の再督促と、提出済みのシートの点検・確認の下書き |
| 第8営業日 | 確認への返事が無い部門の一覧 |
締切の当日には動かしません。 当日の昼に点検すると、入力の途中のシートを「空欄だらけ」と判定してしまいます。
トリガーは、経営企画の担当者が自分のアカウントで作ります。 インストール型トリガーは作った人のアカウントで動き、下書きもその人の Gmail にできるためです。担当者が異動するときは、トリガーを作り直す必要があります。 手順を1枚にまとめておきます。
入力データを集める
| データ | 中身 | 取得元 |
|---|---|---|
| 部門の一覧 | 部門コード、部門名、シートのID、担当者と部門長のメールアドレス | 経営企画の管理シート |
| KPIの定義 | 項目コード、名前、単位、必須か、急変とみなす幅、比べる相手(前月/前年同月) | 経営企画の管理シート |
| 部門のKPIのシート | 当月と過去の値、備考、提出のチェック | 部門ごとのスプレッドシート |
| 営業日のカレンダー | 祝日と会社の休日 | 経営企画の管理シート |
質を決めるのは、KPIの定義です。 「急変とみなす幅」は項目ごとに違います。売上の20%の変動と、不良率の20%の変動は意味が違います。 不良率は0.5%が0.6%になっただけで20%です。項目ごとに、割合の幅と絶対値の幅の両方を持たせます。
単位の列が、桁違いを拾う手がかりになります。 「千円」の項目に円で入れれば1,000倍、「%」の項目に小数で入れれば100分の1になります。単位を知っていれば、10倍や1,000倍のずれを「桁違いの疑い」として名前を付けて拾えます。
データの取得方法を決める
部門のシートは、管理シートに並べたIDで SpreadsheetApp.openById() を使って開きます。シートの範囲は getValues() で一度に読み、1セルずつ読みません。 60枚 × 30項目 × 13か月を1セルずつ読むと、6分の上限に届きます。
| 取るもの | 読み方 | 何に使うか |
|---|---|---|
| 当月・前月・前年同月・過去12か月の値 | 値の範囲を getValues() で一括 | 規則の判定 |
| 表示されている文字 | 同じ範囲を getDisplayValues() で | #REF! などのエラーと、数字のはずの欄の文字列を見つける |
| 備考 | 備考の列を getValues() で | 生成AIの判定の材料 |
| 提出のチェック | 決まったセル | 提出の有無 |
getValues() と getDisplayValues() を両方読むのは、エラーと文字の混入を見分けるためです。 数式が壊れたセルや、「約120」のように文字で入った値は、値だけを見ると扱いが紛らわしくなります。
1回の実行で全部を処理しきれないことを前提にします。 処理済みの部門コードをスクリプト プロパティに保存し、5分を過ぎたら区切って、次の実行で続きから処理します。 スクリプト プロパティは、スクリプトのすべての利用者で共有される設定の置き場所で、アプリ全体の設定に使うものとされています。続きは、10分おきに動かしている時間主導型トリガーの次の回で拾います。未処理の部門が残っていない回は、何もせずにすぐ終わります。
AIへ渡す前に整形する
- 提出の確認 … 提出のチェックが入っていないシートは、点検せずに督促の対象にします
- 型の確認 … 数字のはずの欄に文字列が入っていれば「型の違い」、表示が
#で始まるエラーなら「エラー」として拾います - 空欄の確認 … 必須の項目が空なら「空欄」。0 と空欄は区別します
- 桁違いの確認 … 前月の値との比が10倍以上か10分の1以下なら「桁違いの疑い」。単位が千円・%の項目では、1,000倍・100倍のずれを名前付きで拾います
- 急変の確認 … 定義の割合の幅と絶対値の幅の両方を超えたら「急変」。季節で動く項目は前年同月と比べます
- 過去の幅の確認 … 過去12か月の最小と最大の外に出たら「過去の幅の外」として付記します
3番目の「0 と空欄の区別」を軽く見ないでください。 不良が無かった月の不良件数は0で、入れ忘れた月は空欄です。getValues() は空のセルを空の文字列で返すため、数値の0と取り違えないよう比較を書きます。
規則の部分は、たとえば次のように書けます。
function checkItem(def, cur, prev, lastYear, display) {
if (String(display).startsWith('#')) return 'error';
if (cur === '' || cur === null) return def.required ? 'blank' : null;
if (typeof cur !== 'number') return 'type_mismatch';
const base = def.compareTo === 'last_year' ? lastYear : prev;
if (typeof base !== 'number' || base === 0) return null;
const ratio = cur / base;
if (ratio >= 10 || ratio <= 0.1) return 'digit_error';
const pct = Math.abs(ratio - 1) * 100;
const abs = Math.abs(cur - base);
if (pct >= def.pctLimit && abs >= def.absLimit) return 'sudden_change';
return null;
}
比べる相手が0や空のときは、急変を判定しません。 新しく始めた項目や、前月がたまたま0だった項目で、割り算が意味を持たないからです。過去12か月の幅の外かどうかは、この関数とは別に付記します。
ここまでが規則の仕事です。 生成AIに渡すのは、4番から6番で拾った項目と、その項目の備考だけです。拾われなかった項目は渡しません。
AIに処理させる
させるのは、規則が拾った項目それぞれについて、部門の備考が理由の説明になっているかを判定することと、部門ごとの連絡を下書きすることです。
| 判定 | 意味 | 例 |
|---|---|---|
explained | 備考が、その項目のその動きの理由を説明している | 受注が45%増、備考「大口案件A社の受注を今月計上」 |
unexplained | 備考が空か、別の項目のことしか書いていない | 在庫日数が2倍、備考は空 |
unclear | 備考はあるが、その動きの説明になっているか判断できない | 残業時間が40%増、備考「繁忙のため」 |
「桁違いの疑い」は、備考があっても explained にしません。 単位の誤りは、理由の説明では直らないからです。部門に値そのものを確かめてもらいます。
| させないこと | 理由 |
|---|---|
| 急変かどうかの判定 | 規則で決める。生成AIに割合を計算させない |
| 正しい値の推測 | 「たぶん千円単位の誤り」と値を直さない |
| KPIの良し悪しの評価 | 見るのは入力の誤りだけ。部門の評価はしない |
| 部門の事情の推測 | 備考に書かれていない理由を補わない |
| 送信 | 下書きまで。送るのは人 |
4行目がいちばん起きやすい失敗です。 備考が空でも、生成AIは「季節的な要因と考えられます」と理由を作って explained にしがちです。書かれていない理由で確認を省くと、本当の入力の誤りがそのまま経営会議に出ます。
指示内容を固定する
あなたは経営企画の担当者です。各部門が入力したKPIのうち、
規則で「確認が必要」と拾われた項目について判定し、部門への連絡を下書きします。
【判定のしかた】
各項目について judgement を次から選んでください。
- explained ..... 備考が、その項目のその動きの理由を具体的に説明している
- unexplained ... 備考が空、または別の項目のことしか書いていない
- unclear ....... 備考はあるが、その動きの説明になっているか判断できない
迷ったときは unclear を選んでください。
【厳守事項】
- 備考に書かれていない理由を補わないでください。
「季節要因」「一時的な変動」などを自分で考えて explained にしないでください。
- rule が digit_error(桁違いの疑い)の項目は、備考があっても unexplained にしてください。
- 値の正誤を判断したり、正しい値を推測したりしないでください。
- 割合や差を計算しないでください。与えられた値をそのまま使ってください。
- KPIの良し悪しや、部門の取り組みへの評価を書かないでください。
- reason には、判定の根拠にした備考の文言をそのまま引用してください。
【連絡の下書き】
- unexplained と unclear の項目だけを、1通にまとめてください。
- 項目ごとに、項目名・当月の値・前月の値・確認したいことを1行で書いてください。
- 締切や期限は {reply_due} と書いてください。
- 丁寧に、短く書いてください。前置きのあいさつは1文までにしてください。
【部門】{dept_name}
【KPIの定義】{kpi_definitions}
【拾われた項目】{flags}
「迷ったときは unclear」と書いているのは、explained が連絡を省く判定だからです。 誤って explained にすると、確認すべき項目が誰にも聞かれずに残ります。誤って unclear にしても、確認の連絡が1行増えるだけです。 誤りの重さが違うので、迷ったら軽いほうに倒します。
出力形式を固定する
次の形のJSONで受け取ります。
{
"dept_code": "",
"items": [
{
"kpi_code": "", "rule": "blank | digit_error | sudden_change | out_of_range | error | type_mismatch",
"current": "", "previous": "",
"judgement": "explained | unexplained | unclear",
"reason": ""
}
],
"message": { "needed": true, "subject": "", "body": "" }
}
Gemini API の構造化出力で、この形を指定します。 JSON スキーマを渡すと、構文として正しい JSON が返ります。ただし公式の説明でも、値の意味の正しさは保証されないため、アプリケーションの側で検証するよう書かれています。
スクリプトの側で確かめるのは3つです。
| 確かめること | 外れたとき |
|---|---|
kpi_code が、渡した項目の中にある | その行を捨て、元の項目を unclear として残す |
digit_error の項目が explained になっていない | unexplained に直す |
explained の reason が、その項目の備考の文字列に含まれる | unclear に直す |
3行目が、上で書いた「書かれていない理由を補わない」の機械の側の守りです。 引用が備考に無ければ、生成AIが理由を作ったということです。
検証を通った後の下書きは、たとえば次のようになります。
件名:【確認のお願い】9月度KPIの入力値について(第2工場 製造部)
第2工場 製造部 ご担当者様
9月度のKPIをご提出いただきありがとうございます。
次の2項目について、値をご確認ください。
・在庫日数:当月 48.0日/前月 23.5日(前月の約2倍。備考の記載なし)
・不良率:当月 12/前月 0.8(単位は%です。入力の桁をご確認ください)
お手数ですが、{reply_due} までにシートを修正いただくか、
備考欄に理由をご記入ください。
経営企画部
値と前月の値を必ず並べて書かせます。 部門の担当者がシートを開かなくても、何を聞かれているかが分かるようにするためです。「約2倍」のような言い方は、スクリプトが計算した比を渡して書かせ、生成AIには計算させません。
システムへ連携する
| つなぎ先 | 方式 | 内容 |
|---|---|---|
| 部門のKPIのシート | SpreadsheetApp.openById() で読む | 値・備考・提出のチェック |
| 経営企画の管理シート | 読む | 部門の一覧、KPIの定義、営業日 |
| Gemini API | UrlFetchApp.fetch() で POST | 判定と下書き |
| 確認一覧のシート | 書く | 部門・項目・規則・判定・引用・状態 |
| Gmail | GmailApp.createDraft() | 督促と確認の下書き |
UrlFetchApp.fetch() は、method に post、contentType に JSON、payload に要求の本文を入れて呼びます。muteHttpExceptions を true にすると、失敗の応答でも例外を投げずに応答を返すため、状態コードを見て再試行するかを決められます。
Gemini API のキーは、コードに書かずスクリプト プロパティに置きます。 ただしスクリプト プロパティは、スクリプトの利用者の間で共有される置き場所です。スクリプトの編集権限を持つ人を、経営企画の担当者に限ります。
GmailApp.createDraft() は、宛先・件名・本文と、cc などのオプションを取ります。部門長を cc に入れるかは、部門の一覧の列で部門ごとに決めておきます。
人が確認する
- 確認一覧を部門ごとに見る … 規則・当月と前月の値・判定・引用を1行で読めるようにしてあります
explainedの行も流し見る … 引用された備考が、本当にその動きの説明かを確かめます- 下書きを直して送る … 宛先、
cc、強さを直して送ります - 判定を覆したら記録する …
explainedをunexplainedに、またはその逆に直した行に印を付けます
2番目を省かないでください。 explained の行は連絡に載らないため、誰も見なければ、それきりになります。 引用の一致は機械で確かめていますが、引用した備考が別の月の事情を書いていることもあります。
例外に対処する
| 起きること | 対応 |
|---|---|
| 部門のシートが開けない(権限が外れた、移動された) | 確認一覧に「開けない」と書き、経営企画へ通知 |
| ひな形の列が変えられている | 項目コードの行が見つからなければ、そのシートは点検せず人へ |
| 6分の上限に近づく | 5分で区切り、続きを次の実行へ |
| Gemini API が失敗の応答を返す | 再試行し、続けて失敗すれば規則の結果だけで確認一覧に書く |
| 構造化出力の値が検証に通らない | 第7章の表のとおり unclear か unexplained に直す |
| 子会社のシートが英語で書かれている | 備考の言語はそのまま渡し、下書きは部門の一覧の言語の列に従う |
| 未提出が続く部門 | 第8営業日の一覧に載せ、経営企画から電話する |
4行目で、生成AIが使えないときも点検は止めません。 規則の結果だけで確認一覧を作れば、経営企画が備考を読んで判定できます。生成AIは連絡を減らすための部品で、点検そのものの前提ではありません。
記録を残す
- 実行した日時、処理した部門、区切った位置
- 規則で拾った項目(規則の種類、当月・前月・前年同月の値)
- 生成AIに渡した備考と、返ってきたJSON
- 検証で直した判定と、その理由
- 作った下書きと、人が送った日時(送らなかったものも)
- 人が判定を覆した記録
最後の行は、急変の幅を見直す材料になります。 unclear が毎月同じ項目に出るなら、その項目の幅が狭すぎるか、備考の書き方の例をひな形に入れるべきです。
04実装レベルの3段階
最小構成では枚数がさばけません。 1枚ずつ表にまとめて貼るので、60枚には使えません。確かめるための段階です。 半自動化で、1件30分が9分になり、この段階が本記事の想定です。 シートを開いて探す作業と、メールを書く作業が自動になり、人が行うのは確認一覧を読むことと、下書きを直して送ることです。 本格構成は、半自動化を数か月回してから考えます。 返事を受けた後の読み直しと取り込みまで自動にすると、部門が直した値を経営企画が見ないまま会議の資料に入ります。 取り込みの前に人の目が入る形を保てるかを、先に決めてください。
05工数削減シミュレーション
導入後 60件 × 9分 ÷ 60 = 9 時間/月
自社条件で導入効果を整理したい方へ
このユースケースを自社に当てはめた場合の前提値と削減見込みを、業務ヒアリングをもとに整理します。
06向いている企業・向いていない企業
- 経営企画が毎月、部門・工場・子会社から数十枚のKPIのシートを集めて経営会議の資料を作っている製造業・商社・小売・IT企業。部門ごとのシートが Google スプレッドシートの共通のひな形で作られ、締切の前後に経営企画が1枚ずつ開いて未提出と入力の誤りを確かめている場合。督促と確認の連絡を、毎月ほぼ同じ文面で手で書いている場合。
- KPIが数部門・数項目しかなく、1枚の表で全員が直接入力している場合。KPIを基幹システムや BI の仕組みから自動で集計しており、部門の手入力が無い場合。部門ごとのシートの形がばらばらで、ひな形にそろえる予定がない場合。KPIの良し悪しや部門の評価をAIに判断させたい場合(この構成が見るのは入力の誤りと提出の有無だけです)。
07最小構成で試す方法
- 先月提出された60枚から10枚を選ぶ(うち数枚は、実際に桁違いや確認があったものを入れる)
- 10枚それぞれについて、当月・前月・前年同月の値と備考を1つの表にまとめる
- 手元の Gemini の画面に表を貼り、「前月から30%以上動いた項目と、前月の10倍・10分の1になった項目を挙げ、備考で理由が説明されているかを判定してください。備考に書かれていない理由を補わないでください」と指示する
- 出てきた判定を、当時経営企画が確認した内容と突き合わせる
10枚で確かめるのは、備考による判定が使えるかどうかです。 拾う部分はスクリプトで確実に書けるので、試すのは判定の部分です。
| 出てきた内容 | 判断 |
|---|---|
当時確認した項目が unexplained、確認しなかった項目が explained になった | スクリプトに進む |
備考が空なのに理由を補って explained にした | 指示の書き方で直る。構成は有効 |
備考がほとんど書かれておらず、すべて unexplained になる | ひな形の運用が先。 AIの問題ではない |
3行目が出ても、構成は無駄になりません。 規則で拾って部門ごとに下書きを作るだけでも、①と④の時間は減ります。あわせて、ひな形の備考欄に「急変したときは理由を書く」という記入例を入れてください。
08実装時につまずきやすいポイント
| 問題 | 対策 |
|---|---|
備考が空なのに explained になる | 引用が備考に含まれるかを機械で確かめる |
| 桁違いが説明付きとして流れる | digit_error は explained にしない規則を後段で強制する |
| 0 と空欄を取り違える | 空の文字列と数値の0を分けて比較する |
| 割合だけで急変を拾い、小さな項目が毎回並ぶ | 割合と絶対値の幅の両方を超えたものだけ拾う |
| 夏や年末の項目が毎年急変として出る | 季節で動く項目は前年同月と比べる |
| 6分の上限で止まる | 一括読みにし、5分で区切って続きを次の実行へ |
| 締切の当日に入力途中のシートを点検する | 当日は動かさない |
| 担当者の異動でトリガーが止まる | 作り直しの手順を残す |
| ひな形の列を部門が変える | 項目コードで行を探し、見つからなければ人へ |
| 下書きが自動で送られる | 送信は人。 スクリプトに送信の関数を書かない |
| 前月が0の項目で割り算が壊れる | 比べる相手が0や空なら急変を判定しない |
| 下書きが担当者のGmailに埋もれる | 件名に決まった接頭辞を付け、確認一覧に下書きの件名を並べる |
| 子会社の締切が本社と違う | 部門の一覧に締切の営業日の列を持たせる |
上の2行が、この構成の失敗のほとんどです。 どちらも「確認しなくてよい」という判定が誤って出る失敗で、誤った確認より、誤った省略のほうがはるかに重いからです。
09セキュリティ・AIガバナンス上の注意点
この構成で扱うデータ: 部門別の売上・受注・原価・在庫、不良率、残業時間などの月次の業績と、その理由を書いた備考です。個人の名前は原則として含みませんが、備考に担当者の名前や取引先の名前が書かれることがあります。
- 生成AIへ渡す範囲を、拾われた項目と備考に限る … 60枚の全項目を渡す必要はありません
- Gemini API は有料の枠で使う … 無料の枠は、機密の情報を送らないよう求められています
- API キーの置き場所と編集権限を管理する … スクリプト プロパティは利用者の間で共有されるため、スクリプトを編集できる人を絞ります
- 部門の評価に使わない … この構成が見るのは入力の誤りと提出の有無です。督促の回数や
unexplainedの件数を、部門の評価の材料にしないでください。 備考を書かなくなります - 自動で送らない … 宛先や
ccの誤りは、業績の数字を関係のない人に送ることになります
誤りが起きた場合のリスクは、入力の誤りが経営会議の資料に入ることと、部門に不要な確認を繰り返すことの2つです。 前者は explained の判定を引用で検査することで、後者は備考で説明の付いたものを連絡から外すことで防ぎます。
10まず何から始めるか
1週目:KPIの定義に列を足す
経営企画の管理シートのKPIの定義に、単位、必須か、急変とみなす割合と絶対値の幅、比べる相手(前月か前年同月か)の列を足します。幅は、過去1年の実績から、毎月引っかかりすぎない値を仮に置きます。
2週目:10枚で試す
先月の60枚から10枚を選び、手元の Gemini の画面で判定させます。当時確認した項目と突き合わせ、備考に無い理由を補っていないかを最優先で見ます。
3週目:規則だけのスクリプトを作る
部門のシートを読み、提出の確認と、空欄・桁違い・急変・エラーを拾って確認一覧に書き出すところまで作ります。この時点では生成AIを呼ばず、拾い方の当たり外れだけを見ます。
4週目:判定と下書きを足す
Gemini API の判定と、引用の検査と、Gmail の下書きを足します。締切の前日と翌日の2回、実際の月で動かします。
2か月目: 急変の幅を、unclear と覆した判定の記録を見て見直します。3か月目以降: 1件30分が何分になったかを実測し、ひな形の備考欄に記入例を入れます。unexplained の確認が減り、部門から「備考に書いてある」と返されることがなくなった時点で、この構成は完成です。
11関連ユースケース
12この仕組みを理解するための記事
13技術仕様の確認日・参考情報
| 確認した内容 | 情報源 | 確認日 |
|---|---|---|
| 時間主導型トリガーが毎分から毎月までの間隔で動かせること。インストール型トリガーは作成した人のアカウントで実行されること。失敗した実行はメールで通知されること | Google for Developers: Installable triggers | 2026-10-06 |
| 1回の実行が6分まで。トリガーの合計実行時間が Google Workspace で1日6時間。トリガーは1ユーザー1スクリプトあたり20まで。URL の取得が Google Workspace で1日100,000回。メールの宛先が Google Workspace で1日1,500 | Google for Developers: Quotas for Google Services | 2026-10-06 |
SpreadsheetApp.openById() が指定したIDのスプレッドシートを開くこと。getValues() と getDisplayValues() があること | Google for Developers: SpreadsheetApp | 2026-10-06 |
GmailApp.createDraft(recipient, subject, body, options) があり、cc・bcc・htmlBody などのオプションを取ること | Google for Developers: GmailApp | 2026-10-06 |
UrlFetchApp.fetch() の method・contentType・payload・headers・muteHttpExceptions | Google for Developers: UrlFetchApp | 2026-10-06 |
| スクリプト プロパティがスクリプトのすべての利用者で共有され、アプリ全体の設定に使うものであること | Google for Developers: Properties Service | 2026-10-06 |
| Gemini API の構造化出力が JSON スキーマに沿った JSON を返し、値の正しさはアプリケーションで検証すべきこと | Google AI for Developers: Structured output | 2026-10-06 |
| 無料の枠に送った内容がサービスの改善に使われ、機密・個人の情報を送らないよう求められていること。有料の枠ではプロンプトと応答を製品の改善に使わないこと | Google AI for Developers: Gemini API Additional Terms of Service | 2026-10-06 |
急変とみなす幅と、どの項目を前年同月と比べるかは、自社で決めてください。 本記事は Google for Developers と Google AI for Developers で確認できた範囲だけを扱っています。
実装ステータス:構成例。 公開仕様に基づいて設計した構成であり、当社で実際に構築・検証したものではありません。工数の数値はモデル条件による試算です。
自社の業務に使えるAI活用候補を整理します
このユースケース(UC-0549)についてのご相談はこちらから。
