从电子表格中的列动态更新Google表单“从列表中选择”选项

时间:2015-05-22 04:07:22

标签: google-apps-script google-sheets google-form

我正在尝试设置一个Google表单,该表单将创建一个“从列表中选择”的问题,每个选项都是从特定列中的行中提取的。

我尝试了this code,但它根本不适用于我。

我到目前为止的代码如下。我能够使用特定列中的一行(在这种情况下是列的最后一行)中的数据创建所需的表单问题。

如果有人可以通过指导我如何将每个选定的行分配到一个问题选项的正确方向来提供帮助。 此外,如果这些是每次更新电子表格时动态更新问题选项的某种方式。

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 个答案:

答案 0 :(得分:3)

本声明:

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

答案 1 :(得分:2)

我不确定这是否会对您有所帮助,但有一种比自己编码此操作更简单的方法。有一个名为FormRanger的谷歌表单附加组件将自动填充&#34;从列表中选择&#34;基于信息的问题形成另一个电子表格的行。您可以通过转到表单的加载项菜单然后添加新的加载项来安装它。

以下是FormRanger说明的链接。本文档中还有一个教程。

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

答案 2 :(得分:2)

希望我不会为此迟到但我设法让问题中提到的解决方案起作用,这似乎是一个更好的选择,因为它更新已经构建的表单,不需要创建新的表单或者新的选择。我还修改了AllnaturalChrsFthe original post提供的代码,以便它接受命名范围(或者常规范围),因此减少了您需要的工作表数量你的电子表格。

您应该将此脚本放在带有选项的电子表格中,这样无论何时更改它或按设定的间隔,它都可以运行:

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

使用它之后,您可以选择触发在电子表格中进行的每次更改时运行“updateLists”功能,然后无需使用菜单按钮手动更新该选项。

我一直在寻找这个解决方案已有一段时间了,我很高兴我找到了它。希望它也能帮到你。

答案 3 :(得分:1)

我已经编辑了上面答案中的函数,使其既可以在Sheet中工作,也可以从Form中工作:

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

我从URL中找到了表格和表单的ID,而我使用了here提供的代码作为ListItem ID:

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