Googleスプレッドシートのデータ(A:No / B:FLAG / C:問題 / D:正解)を読み取り、FLAG=1 の行だけを出題に採用して2択のGoogleフォームを自動生成するApps Scriptです。誤答は「次の行のD列(最終行は2行目にループ)」を使い、選択肢はコード側でシャッフル、設問順はフォーム機能でシャッフルします。生成されたフォームは元スプレッドシートと同じフォルダに移動されます。
function createTwoChoiceFormFromActiveSheet_ShuffleInCode() {
// ===== 設定 =====
const START_ROW = 2; // 見出しの次
const COL_FLAG = 2; // B=FLAG
const COL_Q = 3; // C=問題(赤)
const COL_A = 4; // D=正解(青)
const SHUFFLE_QUESTIONS = true; // 設問の順番をフォーム機能でシャッフル
const SHUFFLE_CHOICES = true; // 選択肢の順番をコードでシャッフル
// ===== データ取得 =====
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sh = ss.getActiveSheet();
const lastRow = sh.getLastRow();
if (lastRow < START_ROW) throw new Error('データ行がありません。');
const data = sh.getRange(START_ROW, 1, lastRow - START_ROW + 1, 4).getValues(); // A〜D
const nAll = data.length;
// 全行(誤答参照用)& 出題対象(B=1)
const itemsAll = data.map((row, i) => ({
rowIndex0: i,
flag: String(row[COL_FLAG - 1]).trim(),
q: String(row[COL_Q - 1]).trim(),
a: String(row[COL_A - 1]).trim(),
}));
const itemsQuiz = itemsAll.filter(x => x.flag === '1' && x.q && x.a);
if (itemsQuiz.length === 0) throw new Error('FLAG=1 かつ C/D が空でない行がありません。');
// ===== フォーム作成 =====
const formTitle = `${ss.getName()}|二択クイズ`;
const formDesc = '適切な方を選んでください。';
const form = FormApp.create(formTitle)
.setDescription(formDesc)
.setIsQuiz(true)
.setShuffleQuestions(!!SHUFFLE_QUESTIONS); // 設問順はフォーム機能でランダム化
// =====(任意)設問自体も事前に並び替えたい場合のシャッフル =====
const quizArray = itemsQuiz.slice();
if (SHUFFLE_QUESTIONS) {
shuffleInPlace(quizArray);
}
// ===== 設問追加(選択肢をコードでシャッフル)=====
quizArray.forEach(item => {
const nextIdx = (item.rowIndex0 + 1) % nAll;
let wrong = itemsAll[nextIdx].a || '';
if (!wrong || wrong === item.a) wrong = itemsAll[0].a || '(ダミー)';
let choices = [
{ text: item.a, correct: true }, // 正解
{ text: wrong, correct: false }, // 誤答(次の行D)
];
if (SHUFFLE_CHOICES) shuffleInPlace(choices);
const mc = form.addMultipleChoiceItem();
mc.setTitle(item.q)
.setChoices(choices.map(c => mc.createChoice(c.text, c.correct)))
.setRequired(true);
});
// ===== 同じフォルダへ移動 =====
const ssFile = DriveApp.getFileById(ss.getId());
const parents = ssFile.getParents();
if (parents.hasNext()) {
const parent = parents.next();
const formFile = DriveApp.getFileById(form.getId());
parent.addFile(formFile);
try { DriveApp.getRootFolder().removeFile(formFile); } catch (e) {}
}
Logger.log('編集URL: ' + form.getEditUrl());
Logger.log('回答URL: ' + form.getPublishedUrl());
// --- ユーティリティ:Fisher–Yates シャッフル ---
function shuffleInPlace(arr) {
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const tmp = arr[i]; arr[i] = arr[j]; arr[j] = tmp;
}
return arr;
}
}
操作方法
0) 事前準備(シート構成)
- 行1に見出し
- A: No(任意)
- B: FLAG … 出題する行は
1
、それ以外は空/0 - C: 問題(赤)
- D: 正解(青)
- 行2以降にデータを入力
1) スクリプトを貼り付け
- スプレッドシートを開く → メニュー 拡張機能 → Apps Script
- 新規プロジェクトに、提示の関数
createTwoChoiceFormFromActiveSheet_ShuffleInCode()
を貼り付けて保存
2) 権限付与と実行
- ▶️ボタンで関数を実行(初回のみ権限許可ダイアログが出ます)
- 実行が終わると、ログ(表示 → ログ)に
- 編集URL
- 回答URL
が表示されます
3) フォームの動作仕様
- 出題対象:
B=1
の行のみ - 誤答:各行の次の行の D(最終行は2行目のD)
- 選択肢の順番:コードでランダム(Fisher–Yates)
- 設問の順番:フォーム側の機能でランダム化(
setShuffleQuestions(true)
)
4) 保存場所
- 生成されたフォームは、既定ではマイドライブ直下に作成されますが、スクリプトが元スプレッドシートと同じフォルダへ移動します。
5) よくある質問
- Q. B=1が1件だけだと?
誤答の取得に次行のDを使うため、最低2件の出題行(B=1)があると自然です。 - Q. 選択肢シャッフルをフォーム側のUIでONにする必要は?
不要です。コードでシャッフルしています。 - Q. 設問の順番は固定にしたい
const SHUFFLE_QUESTIONS = false
に変更してください。 - Q. 3択/4択にしたい
nextIdx
を+1, +2, +3
と増やして複数誤答を作り、choices
配列を拡張すれば対応できます。