Google Apps Script中getRangeList报错:getValues不是函数的解决方法
问题
我需要将不同工作表的数据求和汇总到目标表中。最初的代码会同时对数字和字符串求和,为了只对指定单元格求和并避免字符串求和,我改用getRangeList()定义多个范围,但运行时报错:getValues is not a function。请问该场景下如何正确使用getRangeList()?应该用什么替代getValues()?
初始代码
function myFunction() { var sheet_origin1=SpreadsheetApp .openById("ID1") .getSheetByName("Calcul/Machine"); var sheet_origin2=SpreadsheetApp .openById("ID2") .getSheetByName("Calcul/Machine"); var sheet_destination=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //define range as a string in A1 notation var range="BS4:FR71" var values1=sheet_origin1.getRange(range).getValues(); var values2=sheet_origin2.getRange(range).getValues(); var destinationrange=sheet_destination.getRange("A4:CZ71"); //Here you sum the values of equivalent cells from different sheets for(var i=0; i<values1.length;i++) { for(var j=0; j<values1[0].length;j++) { sum=values1[i][j]+values2[i][j]; destinationrange.getCell(i+1,j+1).setValue(sum); } } }
修改后报错的代码
function myFunction() { var sheet_origin1=SpreadsheetApp .openById("ID1") .getSheetByName("Calcul/Machine"); var sheet_origin2=SpreadsheetApp .openById("ID2") .getSheetByName("Calcul/Machine"); var sheet_destination=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); //define range as a string in A1 notation var range=(["BU4:CF71", "CJ4:CU71"]) var values1=sheet_origin1.getRangeList(range).getValues(); var values2=sheet_origin2.getRangeList(range).getValues(); var destinationrange=sheet_destination.getRange("A4:CZ71"); //Here you sum the values of equivalent cells from different sheets for(var i=0; i<values1.length;i++) { for(var j=0; j<values1[0].length;j++) { sum=values1[i][j]+values2[i][j]; destinationrange.getCell(i+1,j+1).setValue(sum); } } }
解决方案
1. 报错核心原因
getRangeList()返回的是RangeList对象,而非单个Range对象,它本身没有getValues()方法——只有单个Range对象才支持调用getValues(),这就是触发报错的直接原因。
2. 正确使用RangeList的方式
要获取RangeList中所有范围的数据,需要遍历RangeList包含的每个Range实例,逐个调用getValues(),再将结果整合处理。同时要加入类型判断,只对数字值进行求和,跳过字符串或非数字内容。
3. 优化后的代码示例
function myFunction() { var sheet_origin1 = SpreadsheetApp.openById("ID1").getSheetByName("Calcul/Machine"); var sheet_origin2 = SpreadsheetApp.openById("ID2").getSheetByName("Calcul/Machine"); var sheet_destination = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // 指定需要求和的多个目标范围 var targetRanges = ["BU4:CF71", "CJ4:CU71"]; // 遍历每个范围,分别处理求和逻辑 targetRanges.forEach(function(a1Notation) { // 获取源表当前范围的值 var values1 = sheet_origin1.getRange(a1Notation).getValues(); var values2 = sheet_origin2.getRange(a1Notation).getValues(); // 获取目标表对应范围的初始值(用于保留非数字内容或直接覆盖) var destValues = sheet_destination.getRange(a1Notation).getValues(); // 逐单元格判断类型并求和 for (var i = 0; i < values1.length; i++) { for (var j = 0; j < values1[0].length; j++) { var val1 = values1[i][j]; var val2 = values2[i][j]; // 仅对数字类型的值执行求和,非数字设为空或保留原有值 if (typeof val1 === 'number' && typeof val2 === 'number') { destValues[i][j] = val1 + val2; } else { destValues[i][j] = ""; // 若需保留目标表原有值,可改为 destValues[i][j] } } } // 一次性写入目标范围,大幅提升运行效率 sheet_destination.getRange(a1Notation).setValues(destValues); }); }
4. 关键优化点
- 遍历每个指定范围,单独获取数据,避免直接调用RangeList不存在的
getValues()方法 - 增加类型校验,仅对数字值求和,彻底避免字符串被强制拼接的问题
- 使用
setValues()一次性写入整范围数据,比循环调用setValue()性能提升显著
内容的提问来源于stack exchange,提问作者Maxime Mouysset
相关产品推荐
相关产品推荐

