我可以基于Google表单在Google电子表格中添加自动递增字段吗?


20

是否可以在Google表单中为其插入电子表格的每一行以及时间戳记赋予唯一值?


创建表单时,会自动添加AFAIK时间戳。当您查看电子表格栏中的内容时,第一个通常是时间戳记(除非出于某种原因将其删除,否则我真的不知道会发生什么)
Robert Koritnik 2012年

我猜自从给出答案以来,情况有所改变,因为在创建触发器并将代码添加到脚本之后,提交表单时没有任何反应。是否有人对上述解决方案在新版Google Sheeth上起作用有任何建议?
user3255228

Answers:


11

您可以通过添加脚本触发器来做到这一点。

假设您当前的表格有两列,Timestamp并回答一个问题。因此,您当前在A和B列中填充了数据。假设您希望列C具有自动递增编号。

您需要先转到Tools > Script Editor

在“脚本编辑器”窗口中,输入以下脚本:

function onFormSubmit(e) {

var sheet = SpreadsheetApp.getActiveSheet();
var row =  SpreadsheetApp.getActiveSheet().getLastRow();

sheet.getRange(row,3).setValue(row);


}

保存脚本,然后转到Triggers菜单并选择Current script's triggers

填充下拉列表,如下所示:

Google脚本触发器

请点击 Save

然后保存并关闭Google App脚本窗口。

现在,提交表单后,它将填充C列中的行号以及通过表单提交的数据。

在要更改保存行号的列中,您需要更改脚本的这一行:

sheet.getRange(row,3).setValue(row);

并将值3更改为相应的列索引号。


是否可以使用此脚本,但是我需要一个唯一的编号,这样,如果我删除或添加一行,就不会搞砸它的示例:我具有ID或行1、2、3、4、5、6,但我手动删除表单提交后的ID 5将移至第5行,因此表单提交的下一个ID将再次为6,我将重复一遍。那么是否可以使用时间戳并从中制作一个唯一的自动递增数字?

甚至更好的是,我现在使用它向所有数据控制的URL发出get请求,并将其直接放入我的应用程序中
Toby Allen

7

除了Barry的出色答案之外,如果您希望能够删除行并仍保留唯一ID,则可以使用一个静态单元格来维护计数。然后,您可以使用此数字,并在表的每个新条目上增加它。

因此,修改方法是将数字保留在电子表格中的某个位置(以下代码中的“ M1”),然后将代码修改为如下所示:

function onFormSubmit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getLastRow();

   var bugCount = sheet.getRange("M1").getValue();
   bugCount++;

   sheet.getRange(row,1).setValue(bugCount);
   sheet.getRange("M1").setValue(bugCount);
}

同样,更改倒数第二行以更改ID的放置位置。


我已经应用了此方法,但是在删除数据行之间的行的情况下这并不成功。因此,只要删除行发生,它就应该更新隐藏值

如果仅需要唯一的ID(按照原始问题),则该编号不需要删除就更新。如果减少删除值,您将获得重复的ID。
Danny Parker 2012年

7

基于先前的两个答案(来自Barry和Danny):

假设ID列为A列。选择一个“下一个ID”单元格并将其设置为以下公式(假设它位于“ P1”中):

=MAX(A:A)+1

使用“工具”菜单下的脚本编辑器创建脚本,然后粘贴以下内容:

function onFormSubmit(e) {
  // Get the active sheet
  var sheet = SpreadsheetApp.getActiveSheet();
  // Get the active row
  var row = sheet.getActiveCell().getRowIndex();
  // Get the next ID value.  NOTE: This cell should be set to: =MAX(A:A)+1
  var id = sheet.getRange("P1").getValue();
  // Check of ID column is empty
  if (sheet.getRange(row, 1).getValue() == "") {
    // Set new ID value
    sheet.getRange(row, 1).setValue(id);
  }
}

使用脚本编辑器中的“触发器”菜单添加脚本触发器: 在此处输入图片说明


4

除了上述答案之外-此解决方案不需要额外的电子表格单元格。

您可以使用内置事件处理程序来提交表单以获得唯一的ID。因为电子表格只是表单的目的地,所以删除行实际上并不会删除响应。考虑到这一点...

编辑:消除了对ID的需要,并处理了日期格式问题。

/**
* This function extracts the relevant properties from the event handler,
* then uses them to get the uniqueID and record the response
* @param {Object} e The event parameter for form submission to a spreadsheet;
*     e has the following properties values, range, namedValues
*/

function onFormSubmit(e) {
  var uniqueID = getUniqueID(e.values);
  recordResponseID(e.range, uniqueID);
}

/**
* Records the unique ID for this response to the correct cell.
* @param  {Object} eventRange Range in which the response is written
* @param  {Integer} uniqueID   Unique id for this range
*/

function recordResponseID(eventRange, uniqueID) {
  var row = eventRange.getRow();
  var column = eventRange.getLastColumn() + 1;
  var sheet = SpreadsheetApp.getActiveSheet();
  sheet.getRange(row, column).setValue(uniqueID);

}
/**
* A shortcut function to get the form that is connected to this spreadsheet
* @return {Form}          The form associated with this spreadsheet.
**/

function getConnectedForm() {
  var formUrl = SpreadsheetApp.getActiveSpreadsheet().getFormUrl();
  var form =  FormApp.openByUrl(formUrl);
  return form;
}

/**
* Returns a unique ID for the response, by finding the actual Response that
* has the same properties.
* @param  {Array} eventValues Array of: Timestamp_string, form_response_value...
* @return {Integer}             The unique id (by 1 based array position) of the Response
*/

function getUniqueID(eventValues) {
  var isMatch = false;
  var eventItems = eventValues.slice(1);

  var responses = getConnectedForm().getResponses();
  //loop backwards through responses (latest is most likely)
  for (var i = responses.length - 1; i > -1; i--) {
    var responseItems = responses[i].getItemResponses();
    //check each value matches

    for (var j = 0; j < responseItems.length; j++) {
      if (responseItems[j].getResponse() !== eventItems[j]) {
        break;
      }
      isMatch = true;
    }
    if (isMatch) {
      return i + 1;
    }
  }
}

function testOnSubmit() {
  var answers = [
    ["Sue", "39", "Okay I suppose"],
    ["John", "22", "Great"],
    ["Jane", "45", "yeah no"],
    ["Bob", "33", "Super"]
  ];

  var form = getConnectedForm();
  var items = form.getItems();
  for (var i = 0; i < answers.length; i++) {
    var formResponse = form.createResponse();
    for (var j = 0; j < items.length; j++) {
      var item = items[j];
      var itemResponse = item.asTextItem().createResponse(answers[i][j]);
      formResponse.withItemResponse(itemResponse);
    }
    formResponse.submit();
    Utilities.sleep(500);
  }

}

我不明白 提交表单后如何调用?
CodyBugstein 2015年

@Imray:我认为这必须是电子表格中的脚本。您可以在电子表格中设置触发器,以便在提交表单时运行功能。如果可行,我将在该答案中添加该事实(我需要检查)。
加里S.16年

1
getUniqueID通过简单地返回到目前为止的响应长度,可以大大简化该函数(这就是上述函数的逻辑以相当复杂的方式进行的操作)。该函数基本上是一行:return getConnectedForm().getResponses().length;
Abid H. Mujtaba

2

这是其他答案的衍生形式,但对将来的用户可能有用。

function onEdit(e) 
{
   var sheet = SpreadsheetApp.getActiveSheet();
   var row =  SpreadsheetApp.getActiveSheet().getActiveCell().getRow();

   var bugCount = sheet.getRange("M2").getValue();
   bugCount++;

   if (sheet.getRange(row, 1).getValue() == "") {
      sheet.getRange(row,1).setValue(bugCount);
      sheet.getRange("M2").setValue(bugCount);    
   }

}

主要区别在于,只有在未指定有效值的情况下,它才会在活动行中更新该行的第1列。

您应将其他答案中提到的触发器设置为on。

将触发器设置为编辑


0

对于“是否有可能在Google表单中为其插入电子表格的每一行以及时间戳赋予唯一值?” 同时还允许在添加进一步的响应之前在表单响应表中删除一行而不重复值,这应该可以:

=iferror(ArrayFormula(match(A1:A,A:A,0)),"")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.