使用自动插入行Google电子表格分配数据(用户名和密码)

时间:2013-12-02 11:02:23

标签: google-apps-script google-sheets

所以故事是我正在使用谷歌表格来收集参与者的详细信息以进行反馈调查。

他们会填写姓名,电子邮件,年龄,手机型号等内容,这些都会被放入一个可爱的谷歌电子表格中。

在此电子表格中,列出了2列中预先确定的用户名和密码。

麻烦的是每一个新的响应都会产生一个新的行,这反过来会推动用户名和密码,所以我必须切断&将它们粘贴起来。

有没有办法让两列保持静态(固定),以便用用户名和密码填充新条目(新行)。

我在google论坛和这里搜索过低,但如果你发现类似的问题,如果有人能指出我正确的方向,这将是一个很大的帮助!

谢谢!

Greggeless

1 个答案:

答案 0 :(得分:2)

正如您所注意到的,Forms服务不只是在当前数据的末尾添加响应;它还会在电子表格中插入一个新行,以便为下次提交做好准备。在此“之前”屏幕截图中,请注意由Forms管理的“数据表”具有灰色背景,而其他凭据列不具有:

Screenshot 1 - before submission

现在,“After”截图。一旦提交了几个表格,我们的凭证就会有差距!

Screenshot 2 - after submission

我们可以使用可安装的电子表格表单提交触发功能从表单提交活动中恢复。 (如果您之前从未处理过Google Apps脚本中的触发器功能,请参阅Understanding TriggersUnderstanding Events。)

我们将使用的算法是:

  1. 考虑到包含新表单提交的范围,向右和向下offset以获取未使用的凭据以及任何引入的差距。

  2. 删除包含空格的行。这是使用javascript技巧完成的,包括Array.filter()方法。

  3. 清除原始凭据范围,并使用整理的凭据进行更新。

  4. 以下是代码:

    /**
     * Spreadsheet Form Submission installable trigger function.
     * Each form submission will bump the username and password (credential)
     * columns down. This function will close them up again.
     *
     * @param {event} e See https://developers.google.com/apps-script/understanding_events
     */
    function onFormSubmit( e ) {
      var credColumns = 2; // # of columns of credential info to right of form
      var sheet = e.range.getSheet();
      var data = sheet.getDataRange().getValues();
      var toBottom = sheet.getLastRow() - e.range.getRow() + 1; // # rows from new submission to bottom of sheet
      var credentialRange = e.range.offset(0, e.values.length, toBottom, credColumns);
      var crA1 = credentialRange.getA1Notation();
    
      // Filter the credentials, removing blanks
      var credentialData = credentialRange.getValues()
                                          .filter(function(cred) {
                                            return cred.join('') != '';
                                          });
    
      debugger;  // pause if running in debugger
    
      // Write tidied credentials to spreadsheet
      credentialRange.clearContent();
      credentialRange.offset(0, 0, credentialData.length, credentialData[0].length).setValues(credentialData);
    }
    
    /**
     * Form Submission test function, adapted from
     * http://stackoverflow.com/questions/16089041/how-can-i-test-a-trigger-function-in-gas/16089067#16089067
     */
    function test_onFormSubmit() {
      var extraColumns = 2; // Non-Form columns, to the right
      var dataRange = SpreadsheetApp.getActiveSheet().getDataRange();
      var data = dataRange.getValues();
      var numFormColumns = data[0].length - extraColumns;
      var headers = data[0].slice(numFormColumns);
      // Start at row 1, skipping headers in row 0
      for (var row=1; row < data.length; row++) {
        var e = {};
        e.values = data[row].slice(numFormColumns);
        e.range = dataRange.offset(row,0,1,numFormColumns);
        e.namedValues = {};
        // Loop through headers to create namedValues object
        for (var col=0; col<headers.length; col++) {
          e.namedValues[headers[col]] = e.values[col];
        }
        // Pass the simulated event to onFormSubmit
        onFormSubmit(e);
      }
    }
    

    现在提交表单后,表单得到了很好的清理:

    Screenshot 3 - Way After

    替代

    如果您确信需要保留这些非形式列,那么您现在已经有了这样做的方法。但是,请考虑另一种方式。

    您可以将它们保存在单独的工作表中,而不是将未使用的凭据堆叠起来等待表单提交。然后,使用不同的表单提交触发器功能,您只需要从该表单中选择下一个未使用的凭据,然后将它们附加到新行。当然,您也希望将它们标记为已使用。

    这种方法应该比上面提供的代码更有效。

    为什么不删除添加的行?

    使用单行程序,我们可以使用触发器功能删除新添加的行:

    function onFormSubmit( e ) {
      e.range.getSheet().deleteRow(e.range.getRow()+1);
    }
    

    这种方法存在危险。由于表单提交是异步的,因此多个用户可能几乎同时提交表单。当发生这种情况时,会多次调用此触发器函数,盲目删除行可能会删除用户的提交。

    Lock Service也无法帮助我们。虽然我们可以使用Lock来确保只有一个onFormSubmit()的调用正在运行,但我们无法控制表单本身或表单响应的插入。