やること
- GoogleForm の項目に回答者の名前をプルダウンで選択してもらう枠を置く
- その選択可能なリストはスプレッドシートのリストから取得する
- 回答済みの名前はリストから除外する
経緯
最近学校現場で働くようになりました。
生徒へのアンケートを作ることがよくあるんですが、毎回生徒の名前を入力するのは大変なのでスプレッドシートの名簿から自動で生成するようにしました。
また、回答が済んだ生徒は除外することで重複する選択をなるべく防ぐことを目的としました。
注意
当初、トリガーを「フォームから - 起動時」で考えていましたが、この設定だとGoogleFormの編集画面を開くと起動するため、不適切でした。
トリガーの設定は 「フォームから - 送信時」 に設定すると、誰かが回答するたびにリストの更新がされます。
用意するもの
- GoogleForm
- これに紐づくGAS
- フォームの回答リストのSpreadsheet ※
- 名前リストが載ったSpreadsheet
※ 回答リストはGoogleFormで回答すると自動で生成されるので、予めフォームに適当に回答してください。
流れ
- 名前リストのシートを取得
- 回答リストのシートを取得
- セル範囲を指定して名前リストを取得(※1)
- 回答リストから回答済み名前リストを取得(※1)
- filter関数で未回答名前リストを抽出
- フォームを取得し、リスト形式の質問を取得
- リスト形式の質問から、指定の名前の項目かチェック
- プルダウンの選択肢に未回答リストをセットする
- GASのトリガーに「フォームから-起動時」でスクリプトを登録する
※1
名前リストは縦列で記入されることが多いと思います。
その場合、取得するデータは2次元のデータとなるのでループを回すのがやりづらいため、flat()関数で1次元配列にしています。
実装
GASスクリプト
function setNameList() {
const SS_ID = `AAAAA`; // 名前リストのスプレッドシート
const RES_SS_ID = `BBBBB`; // Formが自動生成する回答のスプレッドシート
// シート名
const S_NAME = `名前リスト`; // 名前リストが載ったシート名
const RES_S_NAME = `フォームの回答 1`; // 回答リストが載ったシート名
// 対象となるGoogleフォームの質問項目名
const QUESTION_NAME = "名前";
// 1 & 2.名前リストのシートを取得
const spreadsheet = SpreadsheetApp.openById(SS_ID);
const sheet = spreadsheet.getSheetByName(S_NAME);
// 3. 配列で設定されているデータを取得
// シートから縦列のリストを取得すると2次元の配列になるので、flat()で1次元化
const allNameList = sheet.getRange(2, 1, sheet.getLastRow() - 1).getValues().flat();
// 4. 回答済みの名前リストを取得
const resSS = SpreadsheetApp.openById(RES_SS_ID);
const resSheet = resSS.getSheetByName(RES_S_NAME);
const inputNameList = resSheet.getRange(2, 2, resSheet.getLastRow() - 1).getValues().flat();
// 5. filter関数で未回答名前リストを抽出
let uninputNameList = [];
let tmpList = allNameList.filter((data) => {
return !inputNameList.includes(data)
});
tmpList.forEach(data => uninputNameList.push([data]));
// 6.フォームを取得し、リスト形式の質問を取得
const form = FormApp.getActiveForm();
var listItems = form.getItems(FormApp.ItemType.LIST);
// 7. リスト形式の質問から、指定の名前の項目かチェック
listItems.forEach(function(item) {
if(item.getTitle() == QUESTION_NAME) {
// 8. プルダウンの選択肢に未回答リストをセットする
item.asListItem().setChoiceValues(uninputNameList);
}
});
}