从Google电子表格创建Google表单/测验

我正在尝试创建一个多项选择题表单,该表单将根据Google电子表格中的数据创建。我设法创建了一个包含60个问题的表格,每个问题有4个选项,并根据我在电子表格中的信息设置正确的选项。

我需要做的最后一件事是根据包含每个问题的反馈的电子表格中的列G,为每个问题插入正确的反馈。

编辑:这是我的电子表格&;表单的外观图片

Picture for Spreadsheet

Picture for how the form questions should look like

Picture of how the form questions look like (without a feedback)

问题是没有实施,我最多只能为所有问题设置一个固定的反馈/单词,但无法将每个问题的具体反馈导入到每个问题的反馈部分,有人能帮忙吗,以下是我的代码:

function popForm() {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName('Sheet1');
  var numberRows = sheet.getDataRange().getNumRows();
  var myQuestions = sheet.getRange(1,1,numberRows,1).getValues();
  var myAnswers = sheet.getRange(1,2,numberRows,1).getValues();
  var myGuesses = sheet.getRange(1,2,numberRows,4).getValues();
  var myfeedback = sheet.getRange(1,7,numberRows,1).getValues();
  var myShuffled = myGuesses.map(shuffleEachRow);
  Logger.log(myShuffled);
  Logger.log(myAnswers);
  // Create the form as a quiz.  The resulting form's "Quiz options" are different from a manually created quiz.  Be aware (and change manually if needed!
  var form = FormApp.create('Fast Track Question - Domain I');
  form.setIsQuiz(true);
  // Write out each multiple choice question to the form.
  for(var i=0;i<numberRows;i++){
    if (myShuffled[i][0] == myAnswers[i][0]) {
      var addItem = form.addMultipleChoiceItem();
      addItem.setTitle(myQuestions[i][0])
      .setPoints(1)
      .setChoices([
        addItem.createChoice(myShuffled[i][0],true),
        addItem.createChoice(myShuffled[i][1]),
        addItem.createChoice(myShuffled[i][2]),
        addItem.createChoice(myShuffled[i][3])
      ]);
      var incorrectFeedback = FormApp.createFeedback()
      .setText(myfeedback[i][7])
      .build();
      addItem.setFeedbackForIncorrect(incorrectFeedback);
    }
    else if (myShuffled[i][1] == myAnswers[i][0]) {
      var addItem = form.addMultipleChoiceItem();
      addItem.setTitle(myQuestions[i][0])
      .setPoints(1)
      .setChoices([
        addItem.createChoice(myShuffled[i][0]),
        addItem.createChoice(myShuffled[i][1],true),
        addItem.createChoice(myShuffled[i][2]),
        addItem.createChoice(myShuffled[i][3])
      ]);
      var incorrectFeedback = FormApp.createFeedback()
      .setText(myfeedback[i][7])
      .build();
      addItem.setFeedbackForIncorrect(incorrectFeedback);
    }
    else if (myShuffled[i][2] == myAnswers[i][0]) {
      var addItem = form.addMultipleChoiceItem();
      addItem.setTitle(myQuestions[i][0])
      .setPoints(1)
      .setChoices([
        addItem.createChoice(myShuffled[i][0]),
        addItem.createChoice(myShuffled[i][1]),
        addItem.createChoice(myShuffled[i][2],true),
        addItem.createChoice(myShuffled[i][3])
      ]);
      var incorrectFeedback = FormApp.createFeedback()
      .setText(myfeedback[i][7])
      .build();
      addItem.setFeedbackForIncorrect(incorrectFeedback);
    }
    else if (myShuffled[i][3] == myAnswers[i][0]) {
      var addItem = form.addMultipleChoiceItem();
      addItem.setTitle(myQuestions[i][0])
      .setPoints(1)
      .setChoices([
        addItem.createChoice(myShuffled[i][0]),
        addItem.createChoice(myShuffled[i][1]),
        addItem.createChoice(myShuffled[i][2]),
        addItem.createChoice(myShuffled[i][3],true)
      ]);
      var incorrectFeedback = FormApp.createFeedback()
      .setText(myfeedback[i][7])
      .build();
      addItem.setFeedbackForIncorrect(incorrectFeedback);
    }
  }
}


// This function, called by popForm, shuffles the 5 choices.
function shuffleEachRow(array) {
  var i, j, temp;
  for (i = array.length - 1; i > 0; i--) {
    j = Math.floor(Math.random() * (i + 1));
    temp = array[i];
    array[i] = array[j];
    array[j] = temp;
  }
  return array;
}

解决方案

建议更改脚本

您的代码很长,我发现使用一些额外的工具(如getDataRangepushspliceforEach)重写代码会更容易。

您似乎以正确的方式调用了这些方法,但由于您必须在几个地方重复自己,并跟踪许多数组和索引,因此很可能出现了一个小错误。

这是根据您的脚本改编的工作脚本:

function createQuiz() {
  let file = SpreadsheetApp.getActive();
  let sheet = file.getSheetByName("Sheet1");
  
  // Instead of getting individual ranges, it is more efficient
  // to get all the data in one go, and then operate on the two
  // dimensional array in memory.
  let range = sheet.getDataRange();
  let values = range.getValues();

  // Here I am using a existing form to test, but you can just
  // create a new one if you want.
  var form = FormApp.openById("[TESTING_ID]");
  
  
  form.setIsQuiz(true);

  values.shift(); // Using this to remove the first row of headers

  // Going through each line using a forEach to create a
  // multiple choice question
  values.forEach(q => {
    let choices = [q[1], q[2], q[3], q[4]];
    let title = q[0];
    let feedback = q[5]

    // Calling function to create multiple choice question
    createShuffledChoices(form, title, choices, feedback)
  });
}


function createShuffledChoices(form, title, choices, feedback){

  let item = form.addMultipleChoiceItem();

  item.setTitle(title)
  .setPoints(1)

  // Setting up the array that will be passed into item.setChoices()
  let shuffledChoices = [];
  // Making sure that the correct answer is only marked once
  let correctAnswerChosen = false;

  // I found I had to shuffle the questions within the process of
  // creating choices as it made it easier to maintain the spreadsheet
  for (let i = choices.length; i != 0; i--) {
    let rand = Math.floor(Math.random() * (i - 1));
    // If the first answer is chosen, it is the correct one.
    if (rand == 0 && correctAnswerChosen == false) {
      // Combination of push and splice to remove from ordered array
      // to the shuffled one
      shuffledChoices.push(item.createChoice(choices.splice(rand, 1)[0], true));
      // Marking the correct answer as chosen,
      // so that no others are marked correct.
      correctAnswerChosen = true;
    } else {
      shuffledChoices.push(item.createChoice(choices.splice(rand, 1)[0]));
    }  
  }
  
  // Finally setting the choices.
  item.setChoices(shuffledChoices);

  // Creating the feedback
  let formFeedback = FormApp.createFeedback().setText(feedback).build();
  item.setFeedbackForIncorrect(formFeedback);
}
  • 您创建反馈的方式是正确的,我怀疑您只是混淆了数组和索引。这就是我试图简化您的代码并消除重复部分的原因。

  • 我将洗牌过程与多项选择题的制作结合起来。这是因为传入item.setChoices的随机数组必须由item.createChoice对象构建。无法在其他作用域中完成此操作,因为item不可用。

  • 以这种方式组合洗牌逻辑意味着您不需要在问题中使用字母前缀A)。您也不需要有正确答案的列,因为流程知道第一个答案是正确的。因此,您的工作表可以简化为:

  • 要使此脚本工作,需要以这种方式组织数据。(当然,您可以随心所欲地修改它)

参考资料

  • getDataRange
  • push
  • splice
  • shift
  • forEach

相关文章