
アップデート:Googleフォームで質問を自由にカスタマイズ(欠席・遅刻・早退連絡システムを作成する)
※2024.10.3
・アップデート等の影響だと思われますが、フォームを開けるプログラムが動かない現象が発生しているためコード修正しました。修正箇所は集計用スプレッドシートのスクリプトコード88行目です(以下参照)。
//修正前コード
//items[0].setTitle('欠席・遅刻・早退する日:' + form_targetDay);
//修正コード
items[0].asSectionHeaderItem().setTitle('欠席・遅刻・早退する日:' + form_targetDay);
※2024.1.8
・Google Workspace for EducationでGmailが使えない制限下でもクラスルーム等への通知ができるようにコード修正しました。
Googleフォームを活用した欠席・遅刻・早退連絡についてフォームの質問内容や質問数をカスタマイズできるよう改良しました!
作成手順は「Googleフォームを活用した欠席・遅刻・早退連絡システムを作成する(GAS使用)」とほとんど同じです。
■ 特徴
GAS(Google Apps Script)を使用しているので、以下の特徴があります。
・Googleフォーム送信時に送信者(保護者)へ確認メールを送る。
・集計結果のスプレッドシートを見やすくする。
・Googleフォームへ入力できない時間帯を設定する。
・毎日定時に集計結果のスプレッドシートURLを職員へ通知(メール or Googleチャット or Googleクラスルーム)する。
■ 作成ファイルについて
次の3つのファイルを作成します。
1 Googleフォーム
2 Googleフォームの回答と連携しているスプレッドシート
3 集計用スプレッドシート(コピー作成します)
1 Googleフォームを作成する
(1)質問を作成する
※質問は【タイトルと説明を追加】~【3問目】までは全く同じに作成してください(コピペ推奨)。回答は自由に設定してください。
※4問目以降は質問内容も質問数も自由に設定してください!
【タイトルと説明を追加】対象日を表示する欄を作成
・1番上へ挿入する
※タイトルは何もいじらず、デフォルトでOKです。毎日自動実行する、フォームへ入力できるようにするプログラムのなかに、「欠席・遅刻・早退する日:○月○日」と設定されるプログラムが書いてありますので、これで設定します。

【1問目】氏名を設定
・質問の右側の[ラジオボタン ▼]をクリックして[記述式]を選択。
・質問の回答を必須にする → 質問欄右下の「必須」を[オン]
・質問(コピペ) → 氏名(お子さんのフルネーム)
氏名(お子さんのフルネーム)

【2問目】学年を設定
・質問の右側は[ラジオボタン ▼]のまま。
・質問の回答を必須にする → 質問欄右下の「必須」を[オン]
・質問(コピペ) → お子さんの学年
お子さんの学年

【3問目】組を設定
・質問の右側は[ラジオボタン ▼]のまま。
・質問の回答を必須にする → 質問欄右下の「必須」を[オン]
・質問(コピペ) → お子さんのクラス
お子さんのクラス

超重要!!!
【4問目】以降は自由に設定してください!質問数も自由です!
(2)メールアドレスを収集する設定をする
フォーム送信時に確認メールを送信するので、メールアドレスを収集します。
①設定 → ②回答 →③「メールアドレスを収集する」 →④「回答者からの入力」を選択

(3)確認メッセージを編集する
・「確認メッセージ:」 → 連絡ありがとうございました。入力されたメールアドレスへ送信内容を送りましたので確認をお願いいたします。

(4)GASを書く
Googleフォームで記述するGASはフォーム送信時に送信者(保護者)へ確認メールを送るのと、3で作成する集計用スプレッドシートへ記録するスクリプトです。
まずはスクリプトエディタを開きます。


以下のコードをコピペしてください。
※コードの3行目にある「const ss」へは、3で作成する集計用スプレッドシートのIDをコピペしてください。集計用スプレッドシートのIDについては3で説明します。
function onFormSubmit(e) {
//*******集計用スプレッドシートIDを指定*******************************
const ss = SpreadsheetApp.openById('ここへスプレッドシートIDを入力してください');
//***********************************************************
const sheet = ss.getSheetByName('集計シート');
const sheet_2 = ss.getSheetByName('通知名簿');
// フォームの回答を取得
const formResponses = e.response.getItemResponses();
//質問数を取得
const responses = FormApp.getActiveForm();
const numQuestions = responses.getItems().length;//質問数
const realQuestions = formResponses.length;//実際の回答数に応じた数
//質問配列を作成
const formItems = responses.getItems();
let quest = new Array(numQuestions + 1).fill("");
for (let i = 1; i < formItems.length; i++) {
quest[i] = formItems[i].getTitle();
}
//
quest[0] = "対象日";
quest[numQuestions] = "メールアドレス";
quest[numQuestions+1] = "フォーム送信日時";
//項目が未入力(データが初期化された状態)なら実行
if(sheet.getRange(1,1).getValue()==""){
sheet.getRange(1,1,1,quest.length).setValues([quest]); //questは1次元配列なので[quest]で2次元配列にしてからセル範囲へ代入している
}
// 回答の配列を作成(要素数を設問数+2にする)
let row = new Array(numQuestions + 2).fill("");
// 回答の配列に回答を追加
for (let i = 0; i < realQuestions; i++) {
//質問項目が一致している場所へ格納
row[quest.indexOf(formResponses[i].getItem().getTitle())] = String(formResponses[i].getResponse()); //チェックボックスの回答をそのまま入れると文字化けするのでStringで対応した
}
// メールアドレスと送信日時を回答の配列に追加
row[numQuestions] = e.response.getRespondentEmail();
row[numQuestions + 1] = e.response.getTimestamp();
// 対象日と曜日を回答の配列に追加
let targetDay = sheet_2.getRange(1, 14).getValue();
targetDay = Utilities.formatDate(targetDay, 'JST', 'M/d');
row[0] = targetDay;
// 確認メールの本文を作成
const subject = "フォーム送信ありがとうございます";
let body = '以下の内容で受け付けましたので\n' +
'確認をよろしくお願いします。\n' +
'連絡や状況把握のため、保護者様に\n' +
'連絡を入れる場合がありますので\n' +
'ご了承ください。\n' +
'\n' +
'─────────────────────────\n' +
'ご送信内容の確認\n' +
'─────────────────────────\n' +
'\n';
for (let i = 0; i < realQuestions; i++) {
body += "【" + formResponses[i].getItem().getTitle() + "】" + "\n " + row[quest.indexOf(formResponses[i].getItem().getTitle())] + "\n\n";
}
// メール送信は最後に実行
let msg = "";
//ドキュメントロックを使用する(同時受信回避のため)
let lock = LockService.getDocumentLock();
//30秒間のロックを取得
try {
//ロックを実施する
lock.waitLock(30000);
//メインルーチン
// スプレッドシートに登録
sheet.appendRow(row);
//調整------------
const lastRow = sheet.getLastRow(); // 追加した行の行番号を取得
const lastCol = sheet.getLastColumn(); // 一番右端の列番号を取得
//背景色
const color = "#FFFF00";
const range = sheet.getRange(lastRow,1,1,lastCol);
range.setFontWeight("bold"); //文字を太くする
range.setBackground(color); //背景
//日付>年>組の順に並び替え
sheet.getRange(2, 1, lastRow, lastCol).sort(3);
sheet.getRange(2, 1, lastRow, lastCol).sort(2);
sheet.getRange(2, 1, lastRow, lastCol).sort({column: 1, ascending: false});
//sheet.autoResizeColumns(1,lastCol); //列幅自動調整
//メッセージを格納
msg = "無事に処理完了";
} catch (e) {
//ロック取得できなかった時の処理等を記述する
const checkword = "ロックのタイムアウト: 別のプロセスがロックを保持している時間が長すぎました。";
//通常のエラーとロックエラーを区別する
if(e.message == checkword){
//ロックエラーの場合
msg = "別の処理が終わらずロックタイムアウトになってしまいました。";
}else{
//ソレ以外のエラーの場合
msg = e.message;
}
} finally {
//ロックを開放する
lock.releaseLock();
//メッセージを表示する
Logger.log(msg);
}
// 確認メールを送信
MailApp.sendEmail(e.response.getRespondentEmail(), subject, body);
}
コピペ後はこんな感じです↓

(5)トリガーを設定する
画像の手順に従って設定してください。

Googleフォームの作成は以上となります。
2 Googleフォームの回答と連携しているスプレッドシートを作成する
画像の手順に従ってスプレッドシートを作成してください。


3 集計用スプレッドシートをコピーする

(1)シートは「集計シート」と「通知名簿」の2つ
【集計シート】Googleフォームから送信された連絡を集計するシート。職員が連絡を確認するシートです。
※列幅はデフォルトのままなので、内容に応じて見やすい幅へ変更してください。

【通知名簿】メールで通知する名簿、長期休業中(夏休み・冬休み・年度末の停止期間)の設定、「土日祝日の登校日」や「振替日(平日のお休み)」などの特殊日程の設定、管理者の設定をするシートです。

(2)GASへ必要事項を入力する
コピーした集計用スプレッドシートにはすでにGASが記述されていますので、必要事項について入力をしてください。
まずはスクリプトエディタを開きます。


1カ所目(必須)
→ 5行目のurl_myformへGoogleフォームの編集用URLを入力する

2カ所目(必須)
→ 33行目あたりのurl_fmSSへフォーム回答用スプレッドシートのURLを入力する

3カ所目
→ 50行目あたりのclassIDへGoogle classroom IDを入力する(クラスルームへ通知しない場合は空欄のままにする)
※クラスルームへ通知しない場合は読み飛ばしてください。
Google Classroom APIを使用できるようにします。

次に、クラスルームIDを調べるスクリプトを実行して通知したいクラスルームのIDを取得してください。

(3)トリガーを3つ設定する

【1つ目】setCloseTrigger:「欠席・遅刻・早退連絡フォーム」への投稿を締め切るプログラム(closeFormAcceptance)が指定の時刻(デフォルトでは8:00)に実行されるようにセットするプログラムです。
※このトリガーはopenFormAcceptance実行時刻(デフォルトでは16:00)よりも後、closeFormAcceptance実行時刻(デフォルトでは8:00)よりも前に設定してください。画像だと午前3時~4時で設定しています。

【2つ目】setOpenTrigger:「欠席・遅刻・早退連絡フォーム」へ投稿できるようにするプログラム(openFormAcceptance)が指定の時刻(デフォルトでは16:00)に実行されるようにセットするプログラムです。
※このトリガーはcloseFormAcceptance実行時刻(デフォルトでは8:00)よりも後、openFormAcceptance実行時刻(デフォルトでは16:00)よりも前に設定してください。画像だと午後2時~3時(14:00~15:00)で設定しています。
※setOpenTriggerのプログラムの中に集計シートの背景をリセットするプログラムがあるため、できるだけopenFormAcceptance実行時刻の直前にトリガー設定してください。

【3つ目】setScheduledTrigger:本日の連絡を確認用に、集計用スプレッドシートのURLを定時に職員へ通知するプログラム(scheduledAggregation)がcloseFormAcceptance実行時刻(デフォルトでは8:00)の5分後に実行されるようにセットするプログラムです。
※scheduledAggregationには年度末に集計用スプレッドシートの通知名簿更新のお知らせメールを送るプログラム、Googleフォームと紐付いたスプレッドシート(欠席・遅刻・早退の連絡(回答))へ登録された情報と照合する機能もプログラムされています。

(4)集計用スプレッドシートのIDについて
「1 Googleフォームを作成する」→「(4)GASを書く」の「const ss」へコピペしてください。

【運用開始時の注意事項】
「1 Googleフォームを作成する→(1)質問を作成する」で最初に作成した対象日の欄へ「欠席・遅刻・早退する日:○月○日」という値をセットする必要があります。トリガー設定したsetOpenTriggerの中でセットされるopenFormAcceptanceが実行されることで「欠席・遅刻・早退する日:○月○日」という値が設定されます。デフォルトだとopenFormAcceptanceの実行時刻は前日16:00なので、運用開始日の前日16:00以降にGoogleフォームへアクセスして日付がセットされているか確認してください。
※Googleカレンダーへ一度もアクセスしたことが無い場合は一度アクセスしてください。Googleカレンダーへ一度もアクセスしたことが無い場合、setOpenTrigger実行時にエラーになってしまいます。
【年度更新について】
更新作業は大きく分けて次の4点です
(1)旧年度の「Googleフォームの回答と連携しているスプレッドシートとGoogleフォーム」のリンクを解除し、すべての回答を削除する
(2)新年度用に「Googleフォームの回答と連携しているスプレッドシート」を新規作成する
(3)集計用スプレッドシートのGASプログラム33行目あたりのurl_fmSSを更新する
(4)集計用スプレッドシートの「通知名簿」シートの情報更新
(1)旧年度の「Googleフォームの回答と連携しているスプレッドシート」とGoogleフォームのリンクを解除し、すべての回答を削除する


※リンクを解除した旧年度情報が入ったスプレッドシートは別の場所へ保存することをお勧めします。次の(2)で作成する新年度のスプレッドシートと同じ場所にあるとわかりにくくなるため。
(2)新年度用に「Googleフォームの回答と連携しているスプレッドシート」を新規作成する

(3)集計用スプレッドシートのGASプログラム33行目あたりのurl_fmSSを(2)で作成したフォーム回答用スプレッドシートのURL情報へ更新する
この記事の「3 集計用スプレッドシートをコピーする」→「(2)GASへ必要事項を入力する」→「2カ所目(必須)」参照
(4)集計用スプレッドシートの「通知名簿」シートの情報更新
新年度のメンバー登録や長期休業期間、特殊日程などの設定を更新してください。
以上でGoogleフォームを活用した欠席・遅刻・早退連絡システム作成の説明を終わります、お疲れ様でした。
朝の欠席の電話連絡が減ることで先生たちの負担感を少しでも減らせられれば幸いです。
保護者あて通知のひな形も掲載しておきます(googleドキュメント)
