Создание формы / теста Google из электронной таблицы Google

#javascript #forms #google-apps-script #google-sheets #spreadsheet

#javascript #формы #google-приложения-скрипт #google-таблицы #электронная таблица

Вопрос:

Я пытаюсь создать форму вопроса с множественным выбором, которая будет создана на основе данных в электронной таблице Google. Мне удалось создать форму из 60 вопросов, в каждом из которых было по 4 варианта, и установить правильный выбор на основе информации, имеющейся у меня в электронной таблице.

Последнее, что мне нужно сделать, это вставить правильную обратную связь для каждого вопроса на основе столбца G в моей электронной таблице, которая содержит обратную связь для каждого вопроса.

Редактировать: вот изображение того, как будет выглядеть моя электронная таблица и форма

Картинка для электронной таблицы

Изображение того, как должны выглядеть вопросы формы

Изображение того, как выглядят вопросы формы (без обратной связи)

Проблема в том, что она не реализуется, максимум, что я мог, это установить фиксированную обратную связь / слово для всех вопросов, но было невозможно импортировать конкретную обратную связь для каждого вопроса в раздел отзывов каждого вопроса, кто-нибудь может помочь с этим, ниже мой код:

 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;
}
 

Комментарии:

1. Возможно, вы можете отправить свои ответы в службу свойств и отправить их с помощью триггера onFormSubject в электронной таблице. Вам нужно будет выяснить, как идентифицировать каждый ответ, чтобы он был отправлен правильному респонденту.

Ответ №1:

Предлагаемое изменение в script

Ваш код был длинным, и мне было проще переписать его с помощью нескольких дополнительных инструментов, таких как getDataRange , push и splice и forEach .

Казалось, что вы правильно вызываете методы, но поскольку вам приходилось повторяться в нескольких местах и отслеживать множество массивов и индексов, вероятно, возникла небольшая ошибка.

Это рабочий скрипт, адаптированный из вашего:

 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 amp;amp; 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) . Вам также не нужен столбец с правильным ответом, потому что процесс знает, что первый ответ правильный. Таким образом, ваш лист можно упростить до этого:

    введите описание изображения здесь

  • Чтобы этот скрипт работал, данные должны быть организованы таким образом. (Хотя, конечно, вы можете адаптировать его в любом случае, если хотите)

Ссылки