表单上的应用程序脚本如何将额外数据存储到工作表中?

时间:2015-01-25 23:56:59

标签: google-apps-script google-form

问:附加到表单的AppsScript如何将额外的数据存储到工作表中?

情况:我们有一个(长)Google表单,可以将许多数据存储到Google表格中。通常需要编辑条目,并且使用原始表单编辑比尝试直接编辑到工作表更容易。 (有些项目是文本,有几段长。)我想在电子表格中存储一个额外的数据,特别是编辑器可以使用该表格编辑行条目的URL。

我已经可以获取所有表单数据,并且可以使用formResponse.getEditResponseUrl()获取正确的URL。我可以通过电子邮件将所有这些内容发送给用户,通常是收集所有表单条目的编辑。 (感谢StackOverflow中的许多有用的答案让我这么做!)但是编辑器必须手动将URL复制并粘贴到电子表格的正确行中的附加列中。

我在“工作表”类中看到一个接口,用于向电子表格添加一列,但我不知道如何填充表单刚刚存储的特定行的额外列。我们已手动添加了该列,并确认在通过表单进行编辑时Google不会覆盖该列。如何将一小段数据存储到工作表中?

我错过了什么?任何帮助将不胜感激。谢谢。

[补充说明2015-02-06]

  • 我们有一个很长的表格,有些人提交,其他人编辑。编辑将使用表单完成,而不是直接在电子表格中编辑,因此我们需要允许编辑者重新编辑响应的URL。

  • 我希望在表单提交期间将该网址存储到电子表格中,以便有权访问该表单的编辑可以找到它。

  • 在表单方面的脚本中,我可以轻松计算该URL,但现在如何将其存储在工作表的额外列中?

  • 目前,在我的表单端脚本中,我收到了URL并将其与所有表单数据一起发送到编辑的电子邮件中。分发名单。然后,其中一个编辑器从电子邮件中复制URL并将其粘贴到工作表中。 (大多数情况下,进入正确的行,甚至。:-)这是一个可能容易出错的手动步骤。)

  • 第二个问题:表单中的行号与form.getResponses()中的响应数字有什么关系?当提交新项目(即,新行)时,行号和响应号似乎漂移,并且编辑旧项目。是否可以合理地预测编辑器将在其中找到表单数据的表格行号?

再次感谢您提供的任何帮助。我们有一个可生存的临时解决方案。但是,在接下来的几个月里有大约一百个表格条目,我希望尽可能地对这个过程进行错误验证。

瑞克

2 个答案:

答案 0 :(得分:4)

所以,我只是偶然发现了你的问题,希望我能正确理解。

可能出现的问题:

  • 脚本错误地绑定到表单附带的电子表格而不是表单本身(根据您的描述,这在您的案例中不是问题)

  • 提交插入和其他列编辑之间或同时提交之间的竞争条件(参见代码中的第27-32行)

  • 直接访问电子表格,无需事先从电子表格中选择工作表,即使电子表格只包含一张工作表! (见代码第36-37行)

  • 使用列数字索引,而不是相应的列字母作为getRange()方法的参数,该方法仅接受列字母AFAIK(参见代码中的第42-43行)

下面你有代码应该解决所有这些问题(我没有测试过,但它是一个非常类似场景的完美工作解决方案的改编):

// Converts sheet column numeric index to corresponding column letter
function columnToLetter(column)
{
  var temp, letter = '';
  while (column > 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}

以下功能必须从表单注册到“表单提交”事件 - 而不是从电子表格注册! (脚本工具栏 - >资源 - >当前项目的触发器 - >添加新触发器)

// Associated the sheet rows with response URLs in an additional column
function onFormSubmit(e)
{
  try
  {
    // Get the response Url, either from FormApp:
    var responseUrl = FormApp.getActiveForm().getEditResponseUrl();
    // Or alternatively get it from the event:
//  var responseUrl e.response.getId().getEditResponseUrl();
    // ....................
    // Other URL processing
    // ....................

    // Get a public lock on this script, because we're about to modify a shared resource.
    var lock = LockService.getPublicLock();
    // Wait for up to 30 seconds for other processes to finish.
    lock.waitLock(30000);
    // Wait for row insertion to finish, so that sheet.getLastRow() method gets the updated number of rows
    Utilities.sleep(1000); // 1 second

    // Here insert the URL to your spreadsheet
    var spreadsheetUrl = "https://docs.google.com/spreadsheets/d/YGUgHi28_gYUffGYGGH_78hkO1Pk/edit";
    // Gets the first sheet inside the spreadsheet (if you have multiple sheets, just change the value [0])
    var sheet = SpreadsheetApp.openByUrl(spreadsheetUrl).getSheets()[0];
    // Get updated number of rows and columns, after form submit inserted the new row
    var lastRow = sheet.getLastRow();
    var lastColumn = sheet.getLastColumn();

    // Get the exact cell, next to the right of the new row, by converting the column index to corresponding letter
    var lastCell = columnToLetter(lastColumn) + lastRow.toString();
    // Set the content of the cell with the new URL
    sheet.getRange(lastCell).setValue(responseUrl);

    // Release the lock so that other processes can continue.
    lock.releaseLock();    
  }
  catch (error)
  {
    // If there's an error, show the error message
    return error.toString();
  }
}

如有任何其他问题,请写评论。希望它有所帮助。

答案 1 :(得分:1)

您可以使用表单提交范围参数来获取表单中放置的表单数据的行/电子表格范围。然后使用范围偏移方法将数据推送到表格数据的最后一列之后的列中。

请注意,如果使用HYPERLINK公式,则必须转义作为参数传递的引号。

e.g。

function formProcessing(e){
  var formData = e.values;
  var dataRange = e.range; // gets the range on the spreadsheet
  /*
   do all your processing


 */
  var url = "http://www.google.com"; // whatever url to put in spreadsheet

  // add the url value to the spreadsheet
   formRange.getCell(1,formRange.getLastColumn()).offset(0,1).setValue(url);
    // or if you want a named link
  //formRange.getCell(1,formRange.getLastColumn()).offset(0,1).setFormula("HYPERLINK(\"" + url + "\", \"Edit Form\")");
}

enter image description here

enter image description here