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

如何让Google Apps Script仅检测目标Sheet中I列的最后一行?

解决方案

问题根源在于getLastRow()会将包含空值公式的行视为已使用行,导致起始粘贴位置错误。我们需要单独针对I列(唯一标识列)计算最后一行有实际内容的行号,替代原有的全局getLastRow()。

修改后的完整代码

function copy_rows() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const sourceSheet = ss.getSheetByName("source_sheet");
  const targetSheet = ss.getSheetByName('target_sheet');

  // 计算I列(第9列)的最后一行有内容的行号
  const targetColIValues = targetSheet.getRange(1, 9, targetSheet.getMaxRows()).getValues().flat();
  let targetLastRow = 0;
  // 从底部反向查找,找到第一个非空值的行
  for (let i = targetColIValues.length - 1; i >= 0; i--) {
    if (targetColIValues[i] !== "") {
      targetLastRow = i + 1;
      break;
    }
  }

  let lastRow = sourceSheet.getLastRow();
  let sourceRange = sourceSheet.getRange(2, 3, lastRow - 1, 4);  // 修正:原范围行数应为lastRow-1(从第2行开始)
  
  Logger.log(lastRow);
  let targetCounter = 1;

  // 仅获取I列从第1行到实际最后一行的数据
  let targetColumnUniqueIdentifier = targetSheet.getRange(1, 9, targetLastRow, 1).getValues();  
  let existingValuesInTargetSheet = targetColumnUniqueIdentifier.flat();

  for (var i = 0; i < sourceRange.getValues().length; i++) {
    let rowValues = sourceRange.getValues()[i];
    let id = rowValues[1];  // 唯一标识在sourceRange的第2列(索引1)
    
    if (existingValuesInTargetSheet.indexOf(id) === -1) {
      targetSheet.getRange(targetLastRow + targetCounter, 8, 1, 4).setValues([rowValues]);
      targetCounter++;
      existingValuesInTargetSheet.push(id); 
    } else {
      console.log("发现重复值,已跳过。");
    }
  }
}

关键修改点说明

  1. 替换全局最后行计算:用反向遍历I列的方式,精准定位到最后一个有实际内容的行,忽略Z列的空公式行。
  2. 修正源数据范围:原代码中sourceSheet.getRange(2, 3, lastRow, 4)的行数参数错误,改为lastRow - 1(因为从第2行开始,总共有lastRow-1行有效数据),避免读取空行。
  3. 缩小唯一标识列的读取范围:仅读取I列到实际最后一行的数据,减少不必要的内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:43:15