今回はGoogleフォームでスプレッドシートからデータを読み込んでクイズを作ります
事前に「質問・選択肢・フィードバック」をスプレッドシートに入力して
それを読み込んでクイズモードのフォームを作ってみます
事前に用意するスプレッドシートの構造
- A列に質問
- B列に選択肢
- 先頭が正解
- C列に正解のフィードバック
- D列に不正解のフィードバック
Code.gs
function createQuizzesFromSheet() {
const spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit#gid=0';
const formName = 'Simple Quiz from Sheet';
const description = 'Pleas answer the following question';
// スプレッドシートを読み込む
const sheet = SpreadsheetApp.openByUrl(spreadsheetUrl).getSheets()[0];
const [headers, ...rows] = sheet.getDataRange().getValues();
// 列インデックス取得
const colIndex = {
question: headers.indexOf('Question'),
options: headers.indexOf('Options'),
correctFb: headers.indexOf('Correct Feedback'),
incorrectFb: headers.indexOf('Incorrect Feedback')
};
// 新しいフォームを作成
const form = FormApp.create(formName);
form.setDescription(description);
form.setIsQuiz(true);
// 各行のデータから問題を作成
rows.forEach(row => {
const question = row[colIndex.question];
const optionsText = row[colIndex.options];
const correctFb = row[colIndex.correctFb];
const incorrectFb = row[colIndex.incorrectFb];
const options = optionsText
.split('\n')
.map((text, index) => ({
text: text.trim(),
isCorrect: index === 0 // 最初の選択肢を正解に
}));
const item = form.addMultipleChoiceItem();
item.setTitle(question)
.setChoices(options.map(opt => item.createChoice(opt.text, opt.isCorrect)))
.setRequired(true)
.setPoints(10)
.setFeedbackForCorrect(FormApp.createFeedback().setText(correctFb).build())
.setFeedbackForIncorrect(FormApp.createFeedback().setText(incorrectFb).build());
});
form.setPublished(false);
Logger.log('作成されたフォームのURL: ' + form.getEditUrl());
}
上記 Code.gs を実行すると
指定したスプレッドシートからデータを読み込んで
質問・選択肢・解答集に値が入ったフォームが作成されます
フォームの編集画面 > 解答集を作成
Tips 1: 選択肢をシャッフルしたい場合
選択肢もシャッフルしたい場合は Apps Script だけではできないので
事前に選択肢をシャッフルする設定にしたテンプレートのフォームを作って
そのテンプレートをコピーして質問や回答を上書きする
その方法でCode.gsを書き直してみる
Code.gs
function createQuizzesFromSheetByTemplate() {
const spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit#gid=0'; // スプレッドシートURL
const templateFormUrl = 'https://docs.google.com/forms/d/FORM_ID/edit'; // テンプレートフォームURL
const formName = 'Quiz from Sheet';
const description = 'Pleas answer the following question';
// --- スプレッドシートを読み込む ---
const sheet = SpreadsheetApp.openByUrl(spreadsheetUrl).getSheets()[0];
const [headers, ...rows] = sheet.getDataRange().getValues();
// ヘッダーインデックス取得(柔軟に対応するため)
const colIndex = {
question: headers.indexOf('Question'),
options: headers.indexOf('Options'),
correctFb: headers.indexOf('Correct Feedback'),
incorrectFb: headers.indexOf('Incorrect Feedback')
};
// --- フォームのテンプレートをコピーして新規作成 ---
const templateFormId = FormApp.openByUrl(templateFormUrl).getId();
const templateFile = DriveApp.getFileById(templateFormId);
const copiedFile = templateFile.makeCopy(formName);
const form = FormApp.openById(copiedFile.getId());
form.setTitle(formName);
form.setDescription(description);
form.setIsQuiz(true);
form.setPublished(false);
// 最初の項目を複製して数を揃える
const original = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE)[0];
for (let i = 1; i < rows.length; i++) {
original.duplicate();
}
const mcItems = form.getItems(FormApp.ItemType.MULTIPLE_CHOICE);
// --- 各行に基づいてフォーム項目を設定 ---
rows.forEach((row, i) => {
const question = row[colIndex.question];
const optionsText = row[colIndex.options];
const correctFb = row[colIndex.correctFb];
const incorrectFb = row[colIndex.incorrectFb];
const options = optionsText
.split('\n')
.map((text, index) => ({
text: text.trim(),
isCorrect: index === 0 // 先頭が正解
}));
const item = mcItems[i].asMultipleChoiceItem();
item.setTitle(question)
.setChoices(options.map(opt => item.createChoice(opt.text, opt.isCorrect)))
.setRequired(true)
.setPoints(10)
.setFeedbackForCorrect(FormApp.createFeedback().setText(correctFb).build())
.setFeedbackForIncorrect(FormApp.createFeedback().setText(incorrectFb).build());
});
form.setPublished(false);
Logger.log('Created Form: ' + form.getEditUrl());
}
Tips 2: アンケートフォームの場合
質問も選択肢もシャッフルしない場合はもっと短く書けます
Code.gs
function createSimpleFormFromSheet() {
const spreadsheetUrl = 'https://docs.google.com/spreadsheets/d/SPREADSHEET_ID/edit#gid=0';
const formName = 'Simple Survey from Sheet';
const description = 'Pleas answer the following question';
// スプレッドシートのデータ取得
const sheet = SpreadsheetApp.openByUrl(spreadsheetUrl).getSheets()[0];
const [headers, ...rows] = sheet.getDataRange().getValues();
const colIndex = {
question: headers.indexOf('Question'),
options: headers.indexOf('Options'),
};
// 新しい通常フォームを作成(クイズではない)
const form = FormApp.create(formName);
form.setDescription(description);
// 各行の質問をフォームに追加
rows.forEach(row => {
const question = row[colIndex.question];
const optionsText = row[colIndex.options];
const options = optionsText
.split('\n')
.map(text => text.trim())
.filter(text => text); // 空行除去
const item = form.addMultipleChoiceItem();
item.setTitle(question)
.setChoiceValues(options)
.setRequired(true);
});
Logger.log('作成されたフォームの編集URL: ' + form.getEditUrl());
}
関連記事