Google Apps脚本 - sheet.deleterow()删除行和下一行?

时间:2014-05-22 08:13:14

标签: google-apps-script google-sheets google-spreadsheet-api

我的电子表格中的谷歌应用程序脚本出现了问题 - 这段代码运行得很好但是我有一个问题,有时它会删除行,然后直接删除下一行?我花了几个小时质疑这个问题,当我自己执行代码时,它完美无缺,但是当我从电子表格中执行它时,它不起作用?

计划是当用户将值Y输入单元格时,这意味着有人已完成并将信息从学习单中复制到已完成的工作表中 - 当此代码被触发时,有时会删除该行应该,但有时候下面的行 - 为什么这样,无论如何要解决它?

function myOnEdit(e) {
// -----------------------------------------------------------------------------
// This function will run whenever a cell is edited
// -----------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Get Active sheet
// -------------------------------------------------------------------------
var sheet = ss.getActiveSheet();
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// Get Active cell
// -------------------------------------------------------------------------
var mycell = ss.getActiveSelection();
var cellcol = mycell.getColumn();
var cellrow = mycell.getRow();
// -------------------------------------------------------------------------
if (sheet.getName() == "In Learning"){ // Check to see if the sheet is "In Learning"
if (cellcol == 19 && cellrow > 2){ // Check to see if the column is the learner complete column
  if (mycell.getValue() == "Y"){
    var targetSheet = ss.getSheetByName("Completions"); // Get the Completions Sheet
    var targetrow = getFirstEmptyRow(targetSheet)+1; // Find the last row (prevents loads of empty rows horray)
    var target = targetSheet.getRange(targetrow, 1); // Copy the learner information
    sheet.getRange(cellrow, 1, 1, cellcol-1).moveTo(target); // Move the information   
    sheet.deleteRow(cellrow); // Delete it from in learning
    SpreadsheetApp.getActiveSpreadsheet().toast('Learner has been completed', 'Completed', 3); // Alert the user
    sendEmail(learnerObjects, (cellrow-1));
    deleted = true;
  }
  else if (mycell.getValue() == "W"){ 
    var targetSheet = ss.getSheetByName("Withdrawals"); // Get the withdrawals sheet
    var targetrow = getFirstEmptyRow(targetSheet)+1; // Find the last row
    sheet.getRange(cellrow, 1, 1, 4).moveTo(targetSheet.getRange(targetrow, 1)); // Copy learner information and move it
    sheet.getRange(cellrow, 10, 1, 1).moveTo(targetSheet.getRange(targetrow, 5)); // Copy learner information and move it
    sheet.getRange(cellrow, 6, 1, 2).moveTo(targetSheet.getRange(targetrow, 6)); // Copy learner information and move it
    sheet.deleteRow(cellrow); //Delete it from in learning
    SpreadsheetApp.getActiveSpreadsheet().toast('Learner has been Withdrawn', 'Withdrawn', 3); // Alert the user
    deleted = true;
  }
  else {
    mycell.setValue("N");
  }
}
switch(cellcol){ // Otherwise check to see if the user is messing with formulas
  case 12: mycell.setFormula("=CONTINUE(L2, " + cellrow-1 + ", 1)");
    SpreadsheetApp.getActiveSpreadsheet().toast('Formula Corrected', 'Warning', 3);
    break;
  case 14: mycell.setFormula("=CONTINUE(N2, " + cellrow-1 + ", 1)");
    SpreadsheetApp.getActiveSpreadsheet().toast('Formula Corrected', 'Warning', 3);
    break;
  case 15: mycell.setFormula("=CONTINUE(O2, " + cellrow-1 + ", 1)");
    SpreadsheetApp.getActiveSpreadsheet().toast('Formula Corrected', 'Warning', 3);
    break;
}
if (deleted == false && sheet.getRange(cellrow,19).getValue() == "")
{
  sheet.getRange(cellrow,19).setValue("N");
}
}
if (sheet.getName() == "Completions"){
if (cellcol == 19 && cellrow > 1){ // Check to see if the column is the learner complete column
  if (mycell.getValue() == "Y"){
    var targetSheet = ss.getSheetByName("In Learning"); // Get the Completions Sheet
    var targetrow = getFirstEmptyRow(targetSheet)+1; // Find the last row (prevents loads of empty rows horray)
    var target = targetSheet.getRange(targetrow, 1); // Copy the learner information
    sheet.getRange(cellrow, 1, 1, cellcol-1).moveTo(target); // Move the information
    sheet.deleteRow(cellrow); // Delete it from in learning
    SpreadsheetApp.getActiveSpreadsheet().toast('Learner completion has been revoked', 'Revoked Completion', 3); // Alert the user
    deleted = true;
  }
  else {
    mycell.setValue("N");
  }
}
}
}

3 个答案:

答案 0 :(得分:0)

请改为尝试:

var mycell = e.source.getActiveSelection();

答案 1 :(得分:0)

在提交表单时,这听起来与onsubmit类似。这是一个已知的Google问题,其中脚本有时会运行两次 - 我已经看到用户登录生成事件的位置与编写脚本的用户名不同。我发现脚本运行时两个用户都在重复我想要实现的操作。

我的解决方法是检查工作表中的单元格,查找每次脚本运行时设置的值,这样脚本会先检查它是否在运行代码块之前已经运行了。

答案 2 :(得分:0)

这是一个奇怪的。使用函数onEdit(e)的组合对简单脚本进行测试不会修复它,例如:

function onEdit(e){ 
    var mycell = e.range // or SpreadsheetApp.getActiveSheet().getActiveRange()
    e.source.deleteRow(mycell.getRow())// or SpreadsheetApp.getActiveSheet().deleteRow(mycell.getRow())   
} 

相反,所有变体似乎都会连续创建两个.deleteRow()实例,并按照相关说明进行确认。 onEdit的第一次迭代可能会删除该行,然后由于删除而触发该行上的onEdit的第二个实例(另一个changeType)。无法访问changeType,因为它是一个简单的触发器。

这是一个使用PropertiesService的解决方法,似乎解决了我的用例问题:

function onEdit(e){

var delete_count = PropertiesService.getScriptProperties().getProperty("delete_count"); 

if (delete_count == null)  {
   e.source.deleteRow(e.range.getRow())//could call some other function here
   var properties = PropertiesService.getScriptProperties(); 
   properties.setProperty("delete_count", 1)   
  }
  PropertiesService.getScriptProperties().deleteProperty("delete_count")  
}

基本上,只能阻止其中一个额外的onEdit(e) - > .deleteRow()实例。也许可安装而不是简单的触发器也可以工作。