我的电子表格中的谷歌应用程序脚本出现了问题 - 这段代码运行得很好但是我有一个问题,有时它会删除行,然后直接删除下一行?我花了几个小时质疑这个问题,当我自己执行代码时,它完美无缺,但是当我从电子表格中执行它时,它不起作用?
计划是当用户将值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");
}
}
}
}
答案 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()实例。也许可安装而不是简单的触发器也可以工作。