You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
  }
}
问题原因
  1. 重复删除最后一行:使用moveTo移动行后,原行内容会被清空,若原行是工作表最后一行,Google Sheets会自动删除这个空行;但你又手动调用了deleteRow,导致最后一行被额外处理,出现“同时移动目标行和最后一行”的情况。
  2. 逻辑分支冲突:代码里多个独立的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);
    }
  }
}
修复说明
  1. 避免重复删除:新增isLastRow判断,只有当编辑的行不是工作表最后一行时,才手动调用deleteRow,避免和Google Sheets自动删除空行的操作冲突。
  2. 链式逻辑分支:把所有条件改成else if链式结构,确保一个编辑操作只会触发一个逻辑分支,不会重复执行移动/删除。
  3. 修复Not awarded反向逻辑:原代码中Not awarded工作表的反向操作有冲突,现在通过隐藏列Z记录行的来源表,取消勾选时能准确移回原工作表。使用前记得把列Z设置为隐藏(右键列标选择“隐藏列”)。

内容的提问来源于stack exchange,提问作者zbayle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 17:36:33