Google Sheet Apps Script 条件复制行range未定义报错如何解决
问题排查
- 核心报错原因1:匹配条件失效导致
range变量未初始化
你代码中的range仅在匹配dataValues2[j][p] === FoundName && dataValues2[j][q] === RevNo-1的条件块中声明,如果业务数据中没有符合该条件的行,range不会被赋值,相关调用就会报未定义错误。最常见的触发场景是从M-Front表M列取到的RevNo不是数字类型(比如存的是带前缀的字符串如"Rev.0"),RevNo-1计算结果为NaN,永远无法匹配上M-Items表C列的版本号。 - 核心报错原因2:行号计算逻辑错误
插入新行的代码sheet2.insertRowsAfter(sheet2.getLastRow(), 1)执行后,sheet2.getLastRow()已经是新增空行的行号,你后续复制目标写的sheet2.getLastRow() + 1指向了不存在的行,会触发范围无效的报错,容易被误判为range未定义。 - 其他隐含问题:遍历过程中修改表格行结构会导致行号错位,你循环的边界
lastRow2是遍历前获取的固定值,插入新行后原有数据的行号发生偏移,后续循环的行匹配会全部错位。
修复方案
以下是修复后的完整代码,已同步优化版本号升级逻辑符合你要求的Rev.x自增规则:
//*GLOBALS* var SpreadsheetID = "1Zgs1jzjIeaBpd5Ms7emQgxhVJBMtlEOlDNDfxlhSRiY"; function myFunctionn() { var SheetName1 = "M-Front"; var ss = SpreadsheetApp.openById(SpreadsheetID); var sheet1 = ss.getSheetByName(SheetName1); if (!sheet1) { throw new Error("未找到M-Front工作表"); } // 取M-Front最后一行数据 var lastRow = sheet1.getLastRow(); var dataRange = sheet1.getRange(lastRow, 1, 1, sheet1.getLastColumn()); var dataValues = dataRange.getValues(); var FoundName = dataValues[0][0]; // 取A列报价名称 var RevNo = dataValues[0][12]; // 取M列版本号 // 校验版本号是数字 if (isNaN(Number(RevNo))) { throw new Error("M-Front表M列的版本号不是有效数字"); } RevNo = Number(RevNo); // 处理明细工作表 var SheetName2 = "M-Items"; var sheet2 = ss.getSheetByName(SheetName2); if (!sheet2) { throw new Error("未找到M-Items工作表"); } var lastRow2 = sheet2.getLastRow(); var lastColumn2 = sheet2.getLastColumn(); var dataValues2 = sheet2.getRange(1, 1, lastRow2, lastColumn2).getValues(); var p = 0; // A列报价名称索引 var q = 2; // C列版本号索引 // 先收集所有匹配的行号,避免遍历过程中修改表格导致错位 var matchRows = []; for (var j = 0; j < lastRow2; j++) { if (dataValues2[j][p] === FoundName && Number(dataValues2[j][q]) === RevNo - 1) { matchRows.push(j + 1); // 转成表格真实行号 } } if (matchRows.length === 0) { console.log("未找到匹配的明细行,无需执行复制"); return; } // 批量处理匹配行的复制、版本号升级 matchRows.forEach(rowNum => { var sourceRange = sheet2.getRange(rowNum, 1, 1, lastColumn2); // 插入新行到最后一行下方 sheet2.insertRowsAfter(sheet2.getLastRow(), 1); var newRowNum = sheet2.getLastRow(); // 复制整行内容 sourceRange.copyTo(sheet2.getRange(newRowNum, 1, 1, lastColumn2), {contentsOnly: false}); // 更新C列版本号 sheet2.getRange(newRowNum, 3).setValue(RevNo); // 更新B列报价编号,升级Rev版本号 var oldQuoteNo = sourceRange.getValues()[0][1]; // 取B列原报价号 var newQuoteNo = oldQuoteNo.replace(/Rev\.(\d+)$/, (match, num) => `Rev.${parseInt(num) + 1}`); sheet2.getRange(newRowNum, 2).setValue(newQuoteNo); }); }
使用注意事项
- 请确保M-Front表M列存储的是纯数字版本号(比如直接存0、1,不要存
Rev.0格式) - 请确保M-Items表B列的报价编号格式是
xxx-Rev.x的规则,版本号升级逻辑会自动匹配该格式自增 - 如果你的版本号存储规则和上述不同,可以自行调整代码中版本号提取、拼接的逻辑
内容的提问来源于stack exchange,提问作者Biha
相关产品推荐
相关产品推荐

