Google Apps Script复选框触发行移动时多移行问题求助
问题描述
我写了一段Google Apps Script,想实现勾选/取消复选框时自动将对应行移动到其他工作表的功能。逻辑上看似可行,但现在勾选复选框时,会同时移动目标行和最后一行,求解决方法。我打算之后重构代码替换大量if语句,但当前得先让代码正常运行。
规则:若工作表XA中Y列值为TRUE,将该行移动至工作表Xb并删除原行,此逻辑适用于4个复选框。原代码如下:
function onEdit(e) { var sh = e.range.getSheet(); if(sh.getName() == "Working on" && e.range.columnStart == 9 && e.value == "TRUE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Submited Routes"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } else if(sh.getName() == "Submited Routes" && e.range.columnStart == 9 && e.value == "FALSE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Working on"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } if(sh.getName() == "Working on" && e.range.columnStart == 11 && e.value == "TRUE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Missed"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } else if(sh.getName() == "Missed" && e.range.columnStart == 11 && e.value == "FALSE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Working on"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } // NOT AWARDED AUTOMATED MOVE AND DELTE if(sh.getName() == "Submited Routes" && e.range.columnStart == 15 && e.value == "TRUE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Not awarded"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } else if(sh.getName() == "Not awarded" && e.range.columnStart == 15 && e.value == "FALSE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Submited Routes"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } if(sh.getName() == "Working on" && e.range.columnStart == 15 && e.value == "TRUE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Not awarded"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } else if(sh.getName() == "Not awarded" && e.range.columnStart == 15 && e.value == "FALSE") { var numColumns = sh.getLastColumn(); var tsh = e.source.getSheetByName("Working on"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(e.range.rowStart, 1, 1, numColumns).moveTo(trg); sh.deleteRow(e.range.rowStart); } }
问题原因
- 重复删除最后一行:使用
moveTo移动行后,原行内容会被清空,若原行是工作表最后一行,Google Sheets会自动删除这个空行;但你又手动调用了deleteRow,导致最后一行被额外处理,出现“同时移动目标行和最后一行”的情况。 - 逻辑分支冲突:代码里多个独立的
if语句,同一个编辑操作可能触发多个分支,导致重复执行移动和删除操作。
修复后的代码
function onEdit(e) { var sh = e.range.getSheet(); var editedRow = e.range.rowStart; var numColumns = sh.getLastColumn(); var isLastRow = editedRow === sh.getLastRow(); // Working on → Submited Routes(I列勾选) if(sh.getName() === "Working on" && e.range.columnStart === 9 && e.value === "TRUE") { var tsh = e.source.getSheetByName("Submited Routes"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); if(!isLastRow) sh.deleteRow(editedRow); } // Submited Routes → Working on(I列取消勾选) else if(sh.getName() === "Submited Routes" && e.range.columnStart === 9 && e.value === "FALSE") { var tsh = e.source.getSheetByName("Working on"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); if(!isLastRow) sh.deleteRow(editedRow); } // Working on → Missed(K列勾选) else if(sh.getName() === "Working on" && e.range.columnStart === 11 && e.value === "TRUE") { var tsh = e.source.getSheetByName("Missed"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); if(!isLastRow) sh.deleteRow(editedRow); } // Missed → Working on(K列取消勾选) else if(sh.getName() === "Missed" && e.range.columnStart === 11 && e.value === "FALSE") { var tsh = e.source.getSheetByName("Working on"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); if(!isLastRow) sh.deleteRow(editedRow); } // Submited Routes → Not awarded(O列勾选) else if(sh.getName() === "Submited Routes" && e.range.columnStart === 15 && e.value === "TRUE") { var tsh = e.source.getSheetByName("Not awarded"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); // 移动时标记来源表到隐藏列Z tsh.getRange(tsh.getLastRow(), 26).setValue("Submited Routes"); if(!isLastRow) sh.deleteRow(editedRow); } // Working on → Not awarded(O列勾选) else if(sh.getName() === "Working on" && e.range.columnStart === 15 && e.value === "TRUE") { var tsh = e.source.getSheetByName("Not awarded"); var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); // 移动时标记来源表到隐藏列Z tsh.getRange(tsh.getLastRow(), 26).setValue("Working on"); if(!isLastRow) sh.deleteRow(editedRow); } // Not awarded → 原来源表(O列取消勾选) else if(sh.getName() === "Not awarded" && e.range.columnStart === 15 && e.value === "FALSE") { var sourceSheetName = sh.getRange(editedRow, 26).getValue(); var tsh = e.source.getSheetByName(sourceSheetName); if(tsh) { var trg = tsh.getRange(tsh.getLastRow() + 1, 1); sh.getRange(editedRow, 1, 1, numColumns).moveTo(trg); if(!isLastRow) sh.deleteRow(editedRow); } } }
修复说明
- 避免重复删除:新增
isLastRow判断,只有当编辑的行不是工作表最后一行时,才手动调用deleteRow,避免和Google Sheets自动删除空行的操作冲突。 - 链式逻辑分支:把所有条件改成
else if链式结构,确保一个编辑操作只会触发一个逻辑分支,不会重复执行移动/删除。 - 修复Not awarded反向逻辑:原代码中Not awarded工作表的反向操作有冲突,现在通过隐藏列Z记录行的来源表,取消勾选时能准确移回原工作表。使用前记得把列Z设置为隐藏(右键列标选择“隐藏列”)。
内容的提问来源于stack exchange,提问作者zbayle
相关产品推荐
相关产品推荐

