如何让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("发现重复值,已跳过。"); } } }
关键修改点说明
- 替换全局最后行计算:用反向遍历I列的方式,精准定位到最后一个有实际内容的行,忽略Z列的空公式行。
- 修正源数据范围:原代码中
sourceSheet.getRange(2, 3, lastRow, 4)的行数参数错误,改为lastRow - 1(因为从第2行开始,总共有lastRow-1行有效数据),避免读取空行。 - 缩小唯一标识列的读取范围:仅读取I列到实际最后一行的数据,减少不必要的内存占用。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

