今回試したプロトタイプ
今回は、計画外勤務の申請から承認、勤務実績との照合、未申請者や修正対象者への通知、既存帳票を使ったPDF出力までの流れを、実際に動くプロトタイプとして作成しました。
すべてを一度に完成させるのではなく、まずは現場で負担が大きい部分を小さく作り、実際に動かしながら必要な機能や実現方法を具体化することを目的としました。
今回使用した主な技術は、次のとおりです。
今回のプロトタイプで実現したこと
- 計画外勤務の事前・事後・修正申請
- 社員情報の自動補完
- 申請IDの自動発行
- 修正申請と元申請の関連付け
- 勤務実績CSVの自動取込
- 申請時間と実績時間の照合
- 未申請・修正依頼・実績通知の自動判定
- 個人別の月度累計時間の計算
- Googleフォームへの事前入力済みリンク生成
- HTML形式のGmail下書き作成
- 管理者確認後の送信
- 既存の時間外勤務指示書を使ったPDF出力
- 承認済みの人への印影と承認日の自動表示
現場で起きていたこと
計画外勤務が発生した場合、これまでは紙の申請書や指示書への記入、管理者による承認、翌日の勤務実績確認、未申請者への声掛けなどを、人の確認に頼って行っていました。
※ 実際の時間外勤務指示書

特に負担が大きかったのは、次のような点です。
- 計画外勤務の申請が紙ベースである
- 申請のために事務所まで移動する必要がある
- 申請時間と実績時間が異なる場合の確認が必要
- 実績があるのに申請がない人を毎日探す必要がある
- 未申請者への連絡や修正依頼が口頭中心になる
- 当月の計画外勤務累計を個人別に確認しにくい
- 指示書の作成と保管に手間がかかる
業務自体は回っていましたが、その裏では、管理者や担当者の経験、記憶、声掛けによって支えられている部分が多くありました。
そこで今回は、現場の既存運用を大きく変えずに、申請・照合・通知・帳票出力をつなげることを考えました。
最初に考えた全体の流れ
今回の仕組みは、次の流れで動きます。
Googleフォームで申請
↓
GASで管理台帳へ転記
↓
管理者が承認・差戻し
↓
PADで勤務実績CSVを取得・送信
↓
GASで申請と勤務実績を照合
↓
未申請・修正依頼・実績通知を判定
↓
個人別メールの下書きを作成
↓
管理者が確認して送信
↓
既存様式でPDF出力・保存
机上で考えていた段階では、単純に「申請をデジタル化する」程度のイメージでした。
しかし、実際に作り始めると、申請ID、修正申請との関連付け、CSVの文字コード、社員番号の先頭0、月度累計、メールの誤送信防止、帳票への承認印など、必要な機能が次々に見えてきました。
Googleフォームで事前・事後・修正申請を受け付ける
- 社員番号
- 勤務日
- 計画外区分
- 早出
- 残業
- 休日出勤
- その他
- 計画外開始・終了時刻
- 業務内容
- 発生理由
- 備考
- 管理者への伝達事項
修正申請の場合は、元の申請と確実に関連付けるために 「修正対象申請ID」 を追加しました。
Googleフォームのセクション分岐を使い、修正申請を選んだ場合だけ修正対象申請IDを入力する画面を表示しています。
作ってみて分かったこと
当初は、社員番号・勤務日・計画外区分が一致すれば、元申請を自動で探せると考えていました。
しかし、同じ日に複数の申請がある場合や、修正対象が複数候補になる場合を考えると、申請IDを指定するほうが安全です。
実際に作ったことで、「修正申請には元申請を特定する仕組みが必要」ということが明確になりました。
GASで管理台帳へ自動転記する
フォーム送信時には、GASのonFormSubmit(e)を使い、回答内容を管理台帳へ自動転記します。
管理台帳では、申請内容、承認状態、実績時間、照合結果、修正対象申請ID、PDF出力状況などを一元管理しています。
社員番号の先頭0問題
正社員の社員番号には、先頭が0の番号があります。
例えば、0624306という社員番号を数値として扱うと、624306になってしまいます。
そこで、社員番号は文字列として扱い、GAS側でも7桁へ統一しました。
const employeeNoText =
String(employeeNo || '')
.trim()
.padStart(7, '0');
この処理は、フォーム入力、管理台帳、PDF出力、通知メールのすべてで必要になりました。
Power Automate Desktopで勤務実績CSVを取り込む
勤務実績は、勤怠システムから出力されたZIPファイル内のCSVを利用します。
PADでは、次の処理を作成しました。
受信フォルダ内のZIPを取得
↓
ZIPを解凍
↓
CSVを取得
↓
PowerShellでUTF-8へ変換
↓
GASのWebアプリへPOST送信
↓
処理済みZIPを移動
↓
一時ファイルを削除
苦労した文字コード
CSVは、そのまま送ると日本語が正しく読み取れないことがありました。
そこで、PowerShellでUTF-8へ変換してからGASへ送信しました。
また、処理済みフォルダに同名のZIPが存在すると移動できない問題もありました。
最終的には、ファイル名へ日時を付けることで、同じデータを再テストしても安全に保存できるようにしました。
直近7日分と長期履歴を分けて保存する
勤務実績は、用途に応じて2つに分けました。
勤務実績取込
- 直近7日分だけ保持
- 日々の照合作業に使用
- 同じ社員番号・勤務日は上書き
計画外実績履歴
- 長期保存
- 個人別・日付別に保存
- 月度累計計算に使用
計画外実績履歴のシート
月度は16日から翌月15日
会社の月度は、毎月16日から翌月15日です。
例えば、2026/06/16~2026/07/15は「2026年7月度」として集計します。
このルールに合わせ、個人別の早出、居残り、計画外勤務時間を月度単位で集計しました。
計画外月度集計のシート
申請と実績を照合する
申請時間と勤務実績を比較し、対象者を次の3種類に分けました。
未申請
計画外勤務実績あり
かつ
同じ社員番号・勤務日の申請なし
修正依頼
申請あり
かつ
申請時間と実績時間に差異あり
または
承認状態が差戻し
実績通知
申請あり
かつ
照合結果が一致
通知対象一覧のシート
当初は「未申請・要修正一覧」という別シートも考えていましたが、最終的には通知対象一覧に、通知区分・メールアドレス・申請時間・実績時間・累計・送信状態までまとめました。
作りながらシートの役割を整理したことで、不要なシートも見えてきました。
Googleフォームへの事前入力済みリンクを作る
未申請者や修正対象者へメールを送る際、フォームを開いてから社員番号や勤務日を再入力するのは手間です。
そこで、Googleフォームの事前入力機能を使いました。
function createOvertimeFormUrl_(
applicationType,
employeeNo,
workDate,
overtimeType,
correctionApplicationId
) {
// entry番号を使ってURLを組み立てる
}
未申請者用リンクでは、申請区分、社員番号、勤務日、計画外区分を事前入力します。
修正依頼用リンクでは、さらに修正対象申請IDを追加します。
これにより、本人はリンクを開き、必要な部分だけ入力すればよくなりました。
Gmail下書きを自動作成する
最初は、通知対象者へ自動送信する案も考えました。
しかし、誤判定やメール内容の確認を考え、まずはGmail下書きを作成する方式にしました。
通知メールは、次の3種類です。
- 未申請者への申請依頼
- 申請時間と実績時間が異なる人への修正依頼
- 照合済みの人への実績通知
当初はプレーンテキストメールでしたが、長いURLがそのまま表示され、見栄えがよくありませんでした。
そこで、HTMLメールへ変更しました。
HTMLメールで見やすくする
未申請メールは黄色、修正依頼は赤、実績通知は緑を基調にしました。
未申請メール
修正依頼メール
実績通知メール
Googleフォームへのリンクは、長いURLではなく、ボタン風に表示しました。
<a href="フォームURL"
style="
display:inline-block;
background:#1a73e8;
color:#ffffff;
text-decoration:none;
font-weight:bold;
padding:13px 30px;
border-radius:6px;
">
事後申請フォームを開く
</a>
メール本文には、対象日、計画外区分、申請時間、実績時間、差異時間、当月度累計、申請IDを表示しています。
安全対策
通知対象一覧にチェックボックスを設け、管理者が確認したメールだけ送信できるようにしました。
未チェック:送信しない
チェック済み:送信対象
さらに、下書き作成日時、送信状態、送信日時、送信エラーも記録し、誤送信と二重送信を防止しています。
既存の時間外勤務指示書をPDF化する
新しい帳票を作るのではなく、会社で使っている既存の「時間外勤務指示書」を活用しました。

対象日の計画外勤務者を抽出し、氏名、社員番号、計画労働時間、時間外勤務予定、業務内容、発生理由、実績時間、当日時間外時間、対象日までの月度累計を自動転記します。
時間外勤務実績の開始時刻
最初のPDFでは、実績開始時刻に通常勤務の始業時刻が入っていました。
例えば、計画勤務が7:30~16:30、実績勤務が7:30~17:24の場合、時間外勤務実績は16:30~17:24でなければなりません。
そこで、早出・残業・休日出勤ごとに、時間外勤務部分だけを切り出す処理へ修正しました。
PDFへ承認印と承認日を入れる
承認状態が「承認」の人だけ、PDFの承認印欄へ印影と承認日を表示しました。

背景透明のPNG印影をGoogleドライブへ保存し、GASで挿入しました。
const stampImage =
sheet.insertImage(
stampBlob,
stampColumn,
upperRow
);
stampImage
.setWidth(46)
.setHeight(46)
.setAnchorCellXOffset(xOffset)
.setAnchorCellYOffset(0);
承認日は、結合セルの左上セルへ書き込み、下寄せで表示しました。
dateCell
.setValue(approvalDateText)
.setFontSize(8)
.setHorizontalAlignment('center')
.setVerticalAlignment('bottom');
印影の位置、サイズ、承認日の文字サイズは、PDFを何度も出力しながら調整しました。
ChatGPTを壁打ち相手にした
今回の制作では、ChatGPTを「答えを出す道具」というより、壁打ち相手として使いました。
ChatGPTとのやり取り一例
例えば、次のような場面で相談しました。
GASの構文エラー
波かっこの不足や重複
フォームのセクション分岐
修正対象申請IDの設計
社員番号の先頭0問題
CSVの文字コード
PDFの出力範囲
時間外実績の開始・終了時刻
HTMLメールの見栄え
印影と承認日の位置調整
一度で完成したわけではありません。
画面を見せてエラーを説明し、修正して実行し、また次の問題を相談するという繰り返しでした。
まさに、壁へボールを打ち返しながら、少しずつ形を整えていく感覚でした。
AIを使って感じたこと
ChatGPTは、最初から完成形を知っているわけではありません。
こちらが、現場のルール、シート構成、実際のエラー、期待する動き、画面の状態を具体的に伝えるほど、提案も具体的になりました。
一方で、提案されたコードをそのまま使うだけではなく、自分で画面を確認し、動作を試し、必要に応じて修正することが重要だと感じました。
周囲から得たフィードバック
現場のメンバーに今回のシステムの全体像と実画面を見てもらっての感想・提案・意見をいただきました。
【フィードバックの一例】
- 申請者がスマートフォンから入力できるので、2階の売場から3階の事務所まで用紙に書き込みに行く手間が減りそう。
- 未申請者が一覧で分かり、メールまで準備されるのは管理側の負担軽減につながりそう。
- 既存の時間外勤務指示書と同じ形式でPDFが出るので、現場で受け入れやすい。
- 業務監査も紙じゃなくてパソコンのPDFデータでOKにしてほしい。
- メールを自動送信ではなく、確認後に送信する仕組みは安心できる。
- 個人のメールアドレスへの送信を全員が承諾してくれるか不安。
- 仕事中は基本的に携帯電話の所持ができないから、発注用のタブレットにメールで送ってもらえたらうれしいかも。
- これって、(入退店・出退勤の)スキャン忘れにも応用できないかな?
![]()
フィードバックからの気づき
機能を増やすことだけが改善ではなく、現場で安心して使えることが重要だと感じました。
特に、既存帳票を残す、メールを即時送信しない、送信前に管理者が確認する、修正申請の元データを明確にするといった点は、実運用を意識することで追加した機能です。
作ってみて分かったこと
今回、実際に作ったことで、机上では分からなかったことが多く見えてきました。
1. 申請フォームだけでは足りなかった
申請のデジタル化だけでは、未申請確認、実績照合、修正依頼、月度累計、帳票保存までは解決できませんでした。
2. データのつながりが重要だった
社員番号、勤務日、計画外区分、申請IDを使って、フォーム、管理台帳、勤務実績、通知、PDFを関連付ける必要がありました。
3. 現場運用では安全策が必要だった
自動送信は便利ですが、誤送信の可能性があります。
そのため、次の段階を設けました。
対象抽出
↓
下書き作成
↓
管理者確認
↓
チェック
↓
送信
4. 既存の仕組みを活かすほうが受け入れやすい
帳票を完全に新しくするのではなく、既存の時間外勤務指示書を使ったことで、現場の運用に合わせやすくなりました。
5. プロトタイプを作ることで次の課題が見えた
作る前には想定していなかった、複数店舗への展開、権限管理、印影の正式運用ルール、データ保管期間、承認者不在時の対応、AppSheet化などの課題も見えてきました。
今後の方向性
今後は、次の改善を検討しています。
AppSheetとの連携
Googleフォームだけでなく、AppSheetを使って、自分の申請一覧、修正対象、承認待ち一覧、管理者承認画面を作ることを考えています。
複数ページPDF
現在は1ページ最大10名です。対象者が11名以上の場合に、複数ページへ自動分割する機能を追加したいです。
月度集計の見える化
個人別・部門別の計画外勤務時間をグラフ化し、長時間化の傾向を早めに確認できるようにしたいです。
運用ルールの整理
技術的にできることと、会社として正式に運用できることは別です。
特に、電子印影の扱い、個人メールアドレスの管理、PDFの保管ルール、承認権限については、正式運用前に確認が必要です。
入退店・出退勤時のカードスキャン忘れ対応
本人が気づいていないカードスキャン忘れの通知・理由報告依頼も、毎日の勤務実績データを活用し、同様の仕組みの中で実現したいです。
今回のプロトタイプで得られたこと
今回の制作では、単にGASのコードを書くだけでなく、現場の課題を分解し、複数の技術をつないで、実際に動く流れを作ることができました。
特に大きかったのは、最初から完成形を目指すのではなく、次の進め方ができたことです。
まず1つ動かす
↓
問題を見つける
↓
修正する
↓
次の機能を追加する
作ってみることで必要な機能が見え、試行錯誤を共有することで、次の改善につながる材料も増えました。
次のステップでは、今回のプロトタイプを土台に、より使いやすく、現場で継続的に運用できる仕組みへ発展させていきたいと思います。
参考:今回作成した主なシート
フォームの回答
管理台帳
社員マスタ
通知対象一覧
勤務実績取込
計画外実績履歴
計画外月度集計
時間外勤務指示書_原本



















