Как извлечь элементы ответа из формы Google

Я сделал форму для сбора двух данных.

  1. Адрес электронной почты.
  2. Группа, на которую пользователь хочет подписаться.

У каждой группы есть своя таблица. [Согласно опубликованному коду, каждый имеет свой собственный лист в одной и той же электронной таблице.]

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

Это то, что я делал до сих пор. Я застрял..

Есть ли способ получить данные конкретно из определенного текстового поля / параметров .. и т. Д.?

Единственный способ, который я знаю, - это зациклить все данные и получить их 1 на 1 .. и это затрудняет для меня связывание 2 данных вместе ... например: "[email protected]" subscribed to "Group 1"

function onFormSubmit() {
  var form = FormApp.getActiveForm();

  var formResponses = form.getResponses();
  for (var i = 0; i < formResponses.length; i++) {
    var formResponse = formResponses[i];
    var itemResponses = formResponse.getItemResponses();
    for (var j = 0; j < itemResponses.length; j++) {
      var itemResponse = itemResponses[j];

      // Checks if it is multiple choice option
      if (itemResponse.getItem().getType() == FormApp.ItemType.MULTIPLE_CHOICE) {

        // If user chooses group 1, open spreadsheet and store user's email in 1st column
        if (itemResponse.getResponse() == "1") {
          var ss = SpreadsheetApp.openById("id goes here");
          var sheet = ss.getSheetByName("Group subscription email");
        }
      }


    }
  }
}

person chopz    schedule 08.10.2014    source источник


Ответы (1)


Есть ли способ получить данные конкретно из определенного текстового поля / параметров .. и т. Д.?

Да, и это упростит вашу задачу. Соответствующая документация - это объекты событий.

При запуске вашей функции триггера будет предоставлен объект события. В вашем случае, событие отправки формы Forms, событие включает FormResponse объект, доступный по атрибуту response. Нет необходимости просматривать ответы или открывать форму.

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

Простой подход - требуются все ответы

Пока ваши вопросы являются обязательными, массив, возвращаемый getItemResponses(), будет содержать ответы элементов в том порядке, в котором они появляются в форме.

/**
 * Trigger function for Google Forms "Form submit" event.
 * Simple, assumes all answers are provided, no error checking.
 */
function onFormSubmit(e) {
  var formResponse = e.response;
  // If all questions are required, getItemResponses returns responses in form-order
  var itemResponses = formResponse.getItemResponses();
  var email = itemResponses[0].getResponse();  // returns a string
  var group = itemResponses[1].getResponse();

  var sheet = getGroupSheet( group );         // use helper function to get right sheet

  if (sheet) {
    sheet.appendRow([email]);               // Add subscriber as a single-cell row
  }
}

/**
 * Gets the sheet for the indicated group.
 * Helper function for onFormSubmit().
 *
 * @param {string} group   The ID of the group, from user's response
 *
 * @returns {Sheet}        Sheet object for the given group,
 *                         null if group is unknown.
 */
function getGroupSheet( group ) {
  var ssId = "id goes here";
  switch (group) {
    case "1":
      var name = "Group subscription email";
      break;
//  case "2":                                  // Add cases to handle other groups
//    var name = "Other sheet name";
//    break;
    default:                                   // If the group is unknown, log it
      name = "";
      Logger.log("Unexpected group ID ("+group+")");
      break;
  }

  if (name) {
    var result = SpreadsheetApp.openById(ssId).getSheetByName(name);
  }
  else {
    result = null;                             // Return null for unknown groups
  }
  return result;
}

Адаптируемый подход # 1 - индексы элементов

Знание того, что присутствовали все элементы ответа, действительно упростило задачу, но мы не всегда можем полагаться на это. Если есть вероятность, что элементы ответа можно оставить пустыми, нам нужно будет перейти к конкретным ответам.

Есть несколько способов сделать это. Посмотрим на два. Во-первых, используя индексы элементов:

/**
 * Trigger function for Google Forms "Form submit" event.
 * Flexible - checks for specific response items by getting the item index
 * for each response item. Example: if user answered questions 1 and 3, but not 2,
 * e.response would contain itemResponses for items 0 and 2, but not 1.
 */
function onFormSubmit2(e) {
  var formResponse = e.response;
  var itemResponses = formResponse.getItemResponses();

  for (var i=0; i<itemResponses.length; i++) {
    switch (itemResponses[i].getItem().getIndex()) {
      case 0:
        var email = itemResponses[i].getResponse();  // returns a string
        break;
      case 1:
        var group = itemResponses[i].getResponse();
        break;
    }
  }  

  var sheet = getGroupSheet( group );         // use helper function to get right sheet

  if (sheet) {
    sheet.appendRow([email]);               // Add subscriber as a single-cell row
  }
}

Адаптируемый подход # 2 - заголовки пунктов (текст вопроса)

Использование индексов освободило нас от требования давать все ответы, но по-прежнему является хрупким; если бы форма была изменена, потребовались бы усилия по обслуживанию, чтобы индексы оставались выровненными.

Усовершенствование, которое мы можем использовать, - это использовать текст вопросов для выбора наших ответов. Нам все равно придется быть осторожными, если вопросы будут изменены, но этот подход устойчив к изменениям порядка или вопросов или добавлению элементов, не связанных с вопросами, таких как изображения, разрывы страниц, видео или заголовки.

/**
 * Trigger function for Google Forms "Form submit" event.
 * More Flexible - checks for specific response items by getting the item title
 * for each response item. No need to know the exact order of questions this way,
 * as long as we know what the question was. (Ideal if the form is
 * created programmatically.)
 */
function onFormSubmit3(e) {
  var formResponse = e.response;
  var itemResponses = formResponse.getItemResponses();

  for (var i=0; i<itemResponses.length; i++) {
    switch (itemResponses[i].getItem().getTitle()) {
      case "Email Address":
        var email = itemResponses[i].getResponse();  // returns a string
        break;
      case "Group":
        var group = itemResponses[i].getResponse();
        break;
    }
  }  

  var sheet = getGroupSheet( group );         // use helper function to get right sheet

  if (sheet) {
    sheet.appendRow([email]);               // Add subscriber as a single-cell row
  }
}
person Mogsdad    schedule 09.10.2014
comment
Это невероятно подробно. Огромное спасибо! Это сделало коды намного проще для понимания - person chopz; 13.10.2014
comment
Привет, Могсдад, Скрипт работает нормально. Я проверил стенограмму казни, все в порядке. Но когда я просматриваю свою электронную таблицу, она возвращает «[Ljava.lang.Object; @ 4c9b0c7e». Я предполагаю, что мне нужно какое-то преобразование из массива в строку? - person chopz; 13.10.2014
comment
Догадаться. Изменен sheet.appendRow ([[email]]); в sheet.appendRow ([электронная почта]); - person chopz; 14.10.2014
comment
Спасибо - моя опечатка исправлена. - person Mogsdad; 14.10.2014
comment
что, если я столкнусь с ошибкой: You do not have permission to call Form.getResponses? - person blubberbo; 04.11.2018
comment
Пришлось прекратить читать на адаптируемом подходе №1 и прокрутить назад, чтобы проголосовать за это. Образцовый ответ. - person New_2_Code; 10.06.2020