在使用具有剪切和粘贴功能的 Apps 脚本时,如何处理来自 Google 表单的新数据?

How can I deal with new data from a Google Form while using an Apps Script with cut and paste functionality?

我在下面 link 的 Google 表格中有一个员工培训数据库:

Link to Google Spreadsheet

A Google 表单使用员工信息填充 "Add Employee Form Responses" sheet 的 A 到 J 列。该数据通过简单的 =cell 函数传输到 "Qualifications" sheet。问题是,我不知道为什么,当每个新表格完成并且表格答案填充 "Add Employee Form Responses" sheet 时,它会更改下一个空行中的单元格编号限定 sheet 到下一个随后的行号,其中 link 到 "Add Employee Form Responses" sheet 中的空白单元格。例如,在完成表格之前,资格 sheet 第 4 行中的所有单元格都来自 "Add Employee Form Responses" sheet 的第 4 行,但在填写表格后,第 4 行资格条件 sheet 是从第 5 行 "Add Employee Form Responses" sheet 中提取的,该行仍然为空。

我曾经有另一个 sheet,在两个 sheet 之间有一个查询函数,它工作得很好,但我已经添加了以下应用程序脚本(脚本编辑器的第 1 到 24 行) 在 "Qualifications" sheet 的 B 列中输入日期时剪切行并将其粘贴到 "Qualifications - Employees Left" sheet 中。这个问题是查询只是从 "Add Employee Form Responses" sheet 中再次检索数据并重新填充 "Qualifications" sheet。也就是说,刚刚从"Qualifications"sheet剪切粘贴到"Qualifications - Employees Left"sheetreturns到"Qualifications"sheet 来自 "Add Employee Form Responses" sheet 通过查询。


// Cut Employees Left from Qualifications sheet and 
// paste in Qualifications - Employees Left sheet
function onEdit(e) {
  var ss = e.source;
  var sheet = ss.getActiveSheet();
  var sheetName = "Qualifications"
  var range = e.range;
  var editedColumn = range.getColumn();
  var editedRow = range.getRow();
  var column = 2;
  var date = range.getValue();
  // Object.prototype.toString.call(date) === '[object Date]' --> checks if value is date
  // editedColumn == column && editedRow > 4 --> checks if edited cell is from 'Date Left'
  // sheet.getName() == sheetName --> checks if edited sheet is 'Qualifications'
  if(Object.prototype.toString.call(date) === '[object Date]' && editedColumn == column && editedRow > 4 && sheet.getName() == sheetName) {
    var numCols = sheet.getLastColumn();
    var row = sheet.getRange(editedRow, 1, 1, numCols).getValues();
    var destinationSheet = ss.getSheetByName("Qualifications - Employees Left");
    // Get first empty row:
    var emptyRow = destinationSheet.getLastRow() + 1;
    // Copy values from 'Qualifications'
    destinationSheet.getRange(emptyRow, 1, 1, numCols).setValues(row);
    sheet.deleteRow(editedRow);
    sheet.hideColumns(column);
  }

如果 "Qualifications" sheet 和 "Add Employee Form Responses" sheet 之间的行编号问题有一个简单的修复,我将很高兴。否则,我认为可以解决此问题的唯一方法是恢复查询功能,然后让应用程序脚本也从 "Add Employee Form Responses" sheet 中删除数据。我将不胜感激任何建议。我真的希望一切都自动化,因为会有很多计算机文盲用户。

您正在寻找一种更好的方法来动态记录新员工,并在 "Add Employee Form Responses" sheet 和您的 "Qualifications" sheet 上收到通知。目前您使用简单的公式,但这些公式不一定会自动挑选新员工。

在这个答案中,我建议您查看 "Qualifications" 上的数据从表单响应 sheet 物理复制到 "Qualifications" sheet 的场景。

出于开发目的,执行了以下步骤:

  • 创建了 "Qualifications" sheet
  • 的副本
  • 命名为副本 sheet "staff"。
  • 显示了 "staff"
  • 上的所有行
  • 将一名现有员工复制(copy/paste 个值)到第 5 行
  • 删除了从第 6 行到最后一行到最后一列的所有单元格的内容
  • 将脚本复制到绑定的项目中
  • 将函数安装为可安装的触发器 - 事件 = Spreadsheet/On 表单提交
  • 处理了一些新员工进行测试。
  • 确认新员工数据已添加到最后一行加上 "staff"

    function so5882862602(e) {

      //58828626
      // setup spreadsheet and sheets
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var formsheetname = "Add Employee Form Responses";
      var form = ss.getSheetByName(formsheetname);
      var staffsheetname = "staff";
      var staff = ss.getSheetByName(staffsheetname);

      // get Form Response
      //Logger.log(JSON.stringify(e));
      var row = e.range.getRow();
      var range = form.getRange(row,1,1,10);
      //Logger.log("DEBUG: The range is "+range.getA1Notation());  
      var values = range.getValues();  
      var formSurname = values[0][1]
      var formFirstName = values[0][2];
      var formaka = values[0][3];
      var formType = values[0][4]
      var formBranch = values[0][5];
      var formDOB = values[0][6];
      var formGender = values[0][7]
      var formNSN = values[0][8];
      var formNZQA = values[0][9];
      //var formTimeStamp = values[0][0];
      Logger.log("DEBUG: Employee="+formSurname+", "+formFirstName+",aka="+formaka+", Type="+formType+", Branch="+formBranch+", DOB="+formDOB+", Gender="+formGender+", NSN="+formNSN+", NZQA="+formNZQA);


      //update the staff sheet
      var staffupdate = [];
      var staffinal=[];

      // check the value of formaka and adjust name accordingly
      var staffname = "";
      // check the value of formaka
      if (formaka != ""){
        staffname = formSurname.toUpperCase()+", "+formFirstName+" ("+formaka+")";// name
      }
      else{
        staffname = formSurname.toUpperCase()+", "+formFirstName;// name
      }

      // push the values to a blank array
      staffupdate.push(staffname); // name
      staffupdate.push(""); // left
      staffupdate.push(formType);// TYPE
      staffupdate.push(formBranch); // branch
      staffupdate.push(formDOB); // DOB
      staffupdate.push(formGender);// Gender
      staffupdate.push(formNSN);// National Student Number
      staffupdate.push(formNZQA); // NZQA Unit Standards

      //push the array to a second array to create 2D
      staffinal.push(staffupdate);

      // get staff data
      var staffLR = staff.getLastRow();
      var staffupdaterange = staff.getRange(staffLR+1,1,1,8);
      Logger.log("DEBUG: The staff range = "+staffupdaterange.getA1Notation());


        // update the form values to the staff sheet
      staffupdaterange.setValues(staffinal);

    }