小テスト作成シャッフル機能付き

この記事で、小テスト作成のプログラムを作っていたんですが、

それに、シャッフル機能を追加しました!!

細かい解説は改めて YouTube で行いますね!!!

すぐに使いたい方はチャンネル登録しておいてください😆

// 設問をシャッフルを実行するか決定する
var shouldShuffle = true ; // true オン  false オフ

// 選択肢をシャッフルするか決定する
var choicesShuffle = true ; // true オン  false オフ

/**
 * 配列をシャッフルする関数(Fisher-Yates のアルゴリズムを使用)
 *
 * @param {Array} array - シャッフルする元の配列
 * @return {Array} - シャッフルされた配列
 */

function shuffle(array) {
  // 現在のインデックスは、配列内でまだシャッフルされていないセクションの場所を示す
  var currentIndex = array.length;

  // シャッフルのための一時的な値とランダムに選ばれた要素のインデックス
  var temporaryValue, randomIndex;

  // 配列内の未処理のセクションが残っている限り、処理を続ける
  while (0 !== currentIndex) {
    // 残っている要素からランダムに一つを選び、それを currentIndex で指定された要素と交換する
    randomIndex = Math.floor(Math.random() * currentIndex);
    currentIndex -= 1;

    // 現在の要素とランダムに選ばれた要素を交換する
    temporaryValue = array[currentIndex];
    array[currentIndex] = array[randomIndex];
    array[randomIndex] = temporaryValue;
  }

  // シャッフルされた配列を返す
  return array;
}

/**
 * Googleフォームを作成する関数
 * スプレッドシートの設定シートに基づいてGoogleフォームを作成し、それぞれの質問について設定を適用する。
 */

function creteForm() {
  // 現在のスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // '設定' シートの全データを取得
  var values = spreadsheet.getSheetByName('設定').getDataRange().getValues();

  // 設定とヘッダー行を別の配列に保持
  var headers = values.slice(0, 2);

  if (shouldShuffle) {
    // 3行目以降のみシャッフルする
    var questions = values.slice(2);
    questions = shuffle(questions);

    // シャッフルされた配列とヘッダーを再結合
    values = headers.concat(questions);
  }

  // 全体の質問と回答の数を取得(ヘッダー行を除く)
  var QNA = values.length - 2;

  // フォームのタイトルと説明を取得
  var formTitle = values[0][1];
  var formDescription = values[0][3];

  // 新しいGoogleフォームを作成
  var form = FormApp.create(formTitle);
  form.setDescription(formDescription);

  // 回答者のメールアドレスを収集する設定を有効化
  form.setCollectEmail(true);

  // クイズモードが有効になっている場合、その設定を適用
  if (values[0][5] == true) { form.setIsQuiz(true); }

  // 例外処理の開始
  try {
    // QNA(質問と回答の数)分、ループを回す
    var i = 1;
    while (i < QNA + 1) {
      var k = i + 1;

      // 各質問のタイトルとヘルプテキストを設定するページブレイクアイテムを作成
      if (values[k][1] !== '' || values[k][2] !== '') {
        var Question = form.addPageBreakItem().setTitle(values[k][1]).setHelpText(values[k][2]);
      }

      // 各質問タイプに応じて、それぞれの処理を行う
      if (values[k][0] == 1) {

        // 質問を作成して、タイトルとヘルプテキストを設定
        var Question = form.addMultipleChoiceItem().setTitle(values[k][3]).setHelpText(values[k][4]);

        // 質問の選択肢の終了位置を決定
        var EndNo;
        if (values[k].indexOf('', 11) != -1) { EndNo = values[k].indexOf('', 11); } else { EndNo = values[k].length; }

        // 選択肢を格納するための配列を作成
        var Choices = [];

        // 選択肢を配列に追加
        for (var j = 11; j < EndNo; j++) {
          Choices.push(Question.createChoice(values[k][j], values[k][j] == values[k][5]))
        }

        // シャッフルが有効化されている場合のみ選択肢をシャッフルする
        if (choicesShuffle) {
          Choices = shuffle(Choices);
        }

        // 質問に選択肢を設定
        Question.setChoices(Choices);

        // "その他"オプションが有効な場合、その設定を適用
        if (values[k][10] == true) { Question.showOtherOption(true); }
      }
      // リストアイテムの場合
      else if (values[k][0] == 2) {

        // タイトルとヘルプテキストを設定して、新しいリストアイテムを追加
        var Question = form.addListItem().setTitle(values[k][3]).setHelpText(values[k][4]);

        // 選択肢が終了する列番号を見つける
        var EndNo;
        if (values[k].indexOf('', 11) != -1) { EndNo = values[k].indexOf('', 11); } else { EndNo = values[k].length; }

        // 選択肢を格納するための配列を作成
        var Choices = [];

        // 選択肢を配列に追加
        for (var j = 11; j < EndNo; j++) {
          Choices.push(Question.createChoice(values[k][j], values[k][j] == values[k][5]))
        }

        // シャッフルが有効化されている場合のみ選択肢をシャッフルする
        if (choicesShuffle) {
          Choices = shuffle(Choices);
        }
        // 質問に選択肢を設定
        Question.setChoices(Choices);
      }

      // チェックボックス型の質問の場合
      else if (values[k][0] == 3) {

        // チェックボックスの問題を作成し、タイトルを設定
        var Question = form.addCheckboxItem().setTitle(values[k][3]);

        // チェックボックスの選択肢の終了位置を決定
        var EndNo;
        if (values[k].indexOf('', 11) != -1) { EndNo = values[k].indexOf('', 11); } else { EndNo = values[k].length; }

        // 選択肢を配列として取得
        var ChoiceValues = values[k].slice(11, EndNo);
        
        // シャッフルが有効化されている場合のみ選択肢をシャッフルする
        if (choicesShuffle) {
          ChoiceValues = shuffle(ChoiceValues);
        }

        // 質問にチェックボックスの選択肢を設定
        Question.setChoiceValues(ChoiceValues);

        // "その他"オプションが有効な場合、その設定を適用
        if (values[k][10] == true) { Question.showOtherOption(true); }
      }

      // 記述式の質問の場合
      else if (values[k][0] == 4) {

        // 記述式の問題を作成し、タイトルとヘルプテキストを設定
        var Question = form.addTextItem().setTitle(values[k][3]).setHelpText(values[k][4]);
      }

      // 段落の質問の場合
      else if (values[k][0] == 5) {

        // 段落の問題を作成し、タイトルとヘルプテキストを設定
        var Question = form.addParagraphTextItem().setTitle(values[k][3]).setHelpText(values[k][4]);

        // テキストの長さの制限がある場合、その制限を設定
        if (values[k][5] != '')
          Question.setValidation(FormApp.createParagraphTextValidation().setHelpText(values[k][5] + '文字以内で書きなさい').requireTextLengthLessThanOrEqualTo(values[k][5]).build());
      }

      // 均等目盛の質問の場合
      else if (values[k][0] == 8) {

        // 均等目盛の問題を作成し、タイトルとヘルプテキストを設定
        var Question = form.addScaleItem().setTitle(values[k][3]).setHelpText(values[k][4]);

        // 均等目盛の範囲を設定
        Question.setBounds(values[k][11], values[k][12]);

        // 均等目盛のラベルを設定
        Question.setLabels(values[k][13], values[k][14]);
      }
      // クイズモードが有効で、ポイントが設定されている場合、そのポイントを設定
      if (values[0][5] == true && values[k][6] != '') { Question.setPoints(values[k][6]); }

      // クイズモードが有効で、正解に対するフィードバックが設定されていて、かつ問題が均等目盛でない場合
      if (values[0][5] == true && values[k][7] != '' && values[k][0] != 8) {
        // 正解に対するフィードバックを設定
        Question.setFeedbackForCorrect(FormApp.createFeedback().setText(values[k][7]).build());
      }

      // クイズモードが有効で、不正解に対するフィードバックが設定されていて、かつ問題が均等目盛でない場合
      if (values[0][5] == true && values[k][8] != '' && values[k][0] != 8) {
        // 不正解に対するフィードバックを設定
        Question.setFeedbackForIncorrect(FormApp.createFeedback().setText(values[k][8]).build());
      }

      // クイズモードが有効で、フィードバックが設定されていて、かつ問題が均等目盛の場合
      if (values[0][5] == true && values[k][7] != '' && values[k][0] == 8) {
        // フィードバックを設定
        Question.setGeneralFeedback(FormApp.createFeedback().setText(values[k][7]).build());
      }

      // 問題が必須に設定されている場合、その設定を適用
      if (values[k][9] == true) { Question.setRequired(true); }

      // 次の行へ進む
      i = i + 1;
    }
  }
  // エラーが発生した場合、エラーメッセージを表示
  catch (e) {
    Browser.msgBox('エラー発生。スプレッドシートの入力内容を確認して再度実行してください。', Browser.Buttons.OK);
  }

  // 処理が完了したら、完了メッセージを表示
  finally {
    Browser.msgBox('処理が終了しました。ドライブに作成されたファイルを確認してください。', Browser.Buttons.OK);
  }
}

コメント

タイトルとURLをコピーしました