it-swarm.com.ru

Динамически обновлять параметры формы "Выбрать из списка" в Google Form из таблицы

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

Я пробовал этот код , но у меня он вообще не работал.

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

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

var idColumn = 1; // ID of the selected column

//gets document ID from spreadsheet 
//(not 100% sure the role of all of these lines, have worked it out from other examples of code online)
function spreadSheetGetter() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  var lr = rows.getLastRow();  

  var docId = sheet.getRange(lr,idColumn,1,1).getValue(); //gets the data from the last row in selected column

fillFormData(docId);
}


//fills for with document ID
function fillFormData(docId) {
var form = FormApp.openById('MY FORMS ID');
var item = form.addListItem();

item.setTitle('Select Existing Customer') //creates the choose from list question
     .setChoices([
         item.createChoice(docId), //data from row 1
         item.createChoice(docId) //data from row 2 etc...
       ])
}
4
Method

Это утверждение:

var docId = sheet.getRange(lr,idColumn,1,1).getValue();

получает только одно значение. Я думаю, что вам нужны все значения в столбце, поэтому используйте метод getValues() ('s' в конце), чтобы получить двумерный массив значений. И измените параметр numRows (количество строк для получения) на переменную lr. Кроме того, вы хотите начать в строке 2, вероятно. Синтаксис:

getRange(row, column, numRows, numColumns)
  • row - целое число, начинающее строку диапазона
  • column - Целочисленный начальный столбец диапазона
  • numRows - целое число возвращаемых строк
  • numColumns - целое число возвращаемых столбцов.

Итак, параметры должны быть установлены так:

var docId = sheet.getRange(2,idColumn,lr,1).getValues();

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

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

var thisValue = "";
var arrayOfItems = [];
var newItem = "";

for (var i=0;i<docId.length;i++) {
  thisValue = docId[i][0];
  newItem = "item.createChoice('" + thisValue + "')";
  arrayOfItems.Push(newItem);
};

Полная функция будет выглядеть примерно так:

//fills item with document ID
function fillFormData(docId) {
  var form = FormApp.openById('MY FORMS ID');
  var item = form.addListItem();

  var thisValue = "";
  var arrayOfItems = [];
  var newItem = "";

  for (var i=0;i<docId.length;i++) {
    thisValue = docId[i][0];
    Logger.log('thisValue: ' + thisValue);
    newItem = item.createChoice(thisValue);
    arrayOfItems.Push(newItem);
  };

  item.setTitle('Select Existing Customer') //creates the choose from list question
     .setChoices(arrayOfItems)
};
2
Sandy Good

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

Вот ссылка на описание FormRanger. В этом документе также есть учебник.

https://docs.google.com/document/d/1qidnsrTShKU9kPnYz4nubHs2cK9yWnQ2z_XBoqgdIhs/edit

2
krishnab

Надеюсь, я еще не опоздал, но мне удалось заставить решение, упомянутое в вопросе, работать, и это кажется лучшим вариантом, так как он обновляет уже созданную форму, нет необходимости создавать новую или новую опцию для этот. Я также изменил код, представленный Allnatural и ChrsF on оригинальным сообщением , чтобы он принимал именованные диапазоны (или регулярные диапазоны, если на то пошло), таким образом уменьшая количество листов, которые вы бы нужно в вашей таблице.

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

//Here you set the options for the question on your form you want to dinamically change and which named range will populate it
var LIST_DATA = [{formFieldTitle:"Who's your tutor", namedRange:"reg_opcoes"}]

//Inserts a menu entry that allows you to run the function to update the options of the form
function onOpen(e){
  var menuEntries = [];
  menuEntries.Push({name: "Update Lists", functionName: "updateLists"});
  SpreadsheetApp.getActiveSpreadsheet().addMenu("List Updater", menuEntries)
}

//The update function itself, it will run for as many options as you set in the LIST_DATA list
function updateLists() {
  var form = FormApp.openById('1Pl3i5Qr8Kq5C2UbBUqA0iZCsmaHXum5eWR1RfIaEL6g'); //Insert your form ID here
  var items = form.getItems();
  for (var i = 0; i < items.length; i += 1){
    for (var j = 0; j < LIST_DATA.length; j+=1) {
      var item = items[i]
      if (item.getTitle() === LIST_DATA[j].formFieldTitle){ //Here the titles of the questions are called
        updateListChoices(item.asListItem(), LIST_DATA[j].namedRange); //Here the range that populates que question with options is called
        break;
      }
    }
  }
}

//Function that actually gets the values from the range you defined
function updateListChoices(item, sheetName){
  var data = (SpreadsheetApp.getActiveSpreadsheet()
              /* 
                 If you want, you might change the option here to .getDataRange() and work with defined ranges.
                 For that, yoiu should also place a .getSheetName() before it, so that'll know of what interval you're talking about
              */
              .getRange(sheetName) 
              .getValues());
  var choices = [];
  for (var i = 0; i < data.length; i+=1){
    choices.Push(item.createChoice(data[i][0]));
  }
  item.setChoices(choices);
}

После того, как вы получили его в wokr, вы можете настроить seta triger для запуска функции «updateLists» для каждого изменения, внесенного в вашу электронную таблицу, тогда нет необходимости вручную обновлять параметр с помощью кнопки меню.

Я уже некоторое время ищу это решение, и я рад, что нашел его. Надеюсь, это вам тоже поможет.

2
Fogolin

Я отредактировал функции в ответе выше, чтобы они работали как с листа, так и с формы:

var sheetId = '<YOUR_SHEET_ID>';
var sheetName = 'sheet_1';
var column = 'C';
var formId = '<YOUR_FORM_ID>';
var listItemId = 12345678;

function spreadSheetGetter() {
  var sheet = SpreadsheetApp.openById(sheetId).getSheetByName(sheetName);
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var docId = sheet.getRange(sheetName+"!"+column+"2:"+column+numRows).getValues();
  fillFormData([].concat.apply([],docId));
}

function fillFormData(docId) {
  var form = FormApp.openById(formId);
  var item = form.getItemById(listItemId).asListItem();
  item.setChoiceValues(docId);
};

Я нашел идентификаторы для Sheets и Form из URL, вместо этого для идентификатора ListItem я использовал предоставленный код here :

var form = FormApp.getActiveForm();
var items = form.getItems();
for (var i in items) { 
  Logger.log(items[i].getTitle() + ': ' + items[i].getId());
}
0
ggagliano