Google Sheets脚本跨表日期匹配条件不生效问题求助
问题:Google Apps Script日期匹配条件未触发,无法合并数据
我编写了如下Google Apps Script的trackProgress函数,用于在Data和Progress两个Sheet中匹配日期,但日志显示存在多组日期相等的情况,条件判断却未触发,无法将匹配行的信息合并到新数组中。
原代码:
function trackProgress() { var out = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data"); out.getRange("dataRange").sort({ column: 1, ascending: true }); var progress = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Progress"); progress.getRange("Plog").sort({ column: 1, ascending: true }); var dRows = out.getLastRow(); var pRows = progress.getLastRow(); var pdate = progress.getRange("Pdate").getValues(); var pCRpro = progress.getRange("CRpro").getValues(); var pMpro = progress.getRange("Mpro").getValues(); var outUser = out.getRange("UID").getValues(); var outWeight = out.getRange("Rweight").getValues(); var outDate = out.getRange("Date").getValues(); var data; //[["Date", "CR", "CR Proj", "M", "M Proj"]] for (var i = 0; i <= dRows; i++) { for (var g = 0; g <= pRows; g++) { Logger.log(outDate[i]+" "+pdate[g]) if (outDate[i] == pdate[g]) { Logger.log("date match") if (outUser[i] == "Munchkin") { data = data.concat([[outDate[i], "", pCRpro[i], outWeight[i], pMpro[i]]]); } if (outUser[i] == "CR") { data = data.concat([[outDate[i], outWeight[i], pCRpro[i], pMpro[i]]]); } } } } Logger.log(data) }
解决方案
问题根源分析
- 日期对象直接比较失效:Google Sheets中通过
getValues()获取的日期是Date对象实例,即使日期时间完全相同,==也会因为对象引用不同返回false,必须通过时间戳比较。 - 数组索引越界:
getLastRow()返回的是从1开始的行号,而数组索引从0开始,循环条件i <= dRows会访问超出数组长度的元素,导致undefined。 data未初始化:初始var data;为undefined,直接调用concat会抛出错误。- 索引匹配错误:找到日期匹配时,误用了Data表的索引
i去取Progress表的数据(如pCRpro[i]),应该用Progress表的索引g。 - 数组结构不一致:用户为"CR"时生成的数组只有4个元素,与表头的5列结构不匹配,后续写入会出错。
修正后的代码
function trackProgress() { var out = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data"); out.getRange("dataRange").sort({ column: 1, ascending: true }); var progress = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Progress"); progress.getRange("Plog").sort({ column: 1, ascending: true }); var dRows = out.getLastRow(); var pRows = progress.getLastRow(); // 获取二维数组,注意每个元素是[值]的结构 var pdate = progress.getRange("Pdate").getValues(); var pCRpro = progress.getRange("CRpro").getValues(); var pMpro = progress.getRange("Mpro").getValues(); var outUser = out.getRange("UID").getValues(); var outWeight = out.getRange("Rweight").getValues(); var outDate = out.getRange("Date").getValues(); // 初始化空数组,避免concat报错 var data = []; // 循环遍历Data表的每一行(索引从0到dRows-1) for (var i = 0; i < dRows; i++) { // 跳过空行或日期为空的情况 if (!outDate[i][0]) continue; // 遍历Progress表的每一行 for (var g = 0; g < pRows; g++) { if (!pdate[g][0]) continue; // 用getTime()获取时间戳进行日期比较 if (outDate[i][0].getTime() === pdate[g][0].getTime()) { Logger.log("date match: " + outDate[i][0]); if (outUser[i][0] === "Munchkin") { data.push([ outDate[i][0], "", pCRpro[g][0], outWeight[i][0], pMpro[g][0] ]); } if (outUser[i][0] === "CR") { // 补全5个元素,与表头结构一致 data.push([ outDate[i][0], outWeight[i][0], pCRpro[g][0], "", pMpro[g][0] ]); } } } } Logger.log(data); // 如果需要写入表格,可以添加以下代码: // out.getRange(out.getLastRow()+1, 1, data.length, data[0].length).setValues(data); }
关键修正点说明
- 日期比较:改用
outDate[i][0].getTime() === pdate[g][0].getTime(),通过时间戳确保日期完全匹配。 - 循环边界:将
i <= dRows改为i < dRows,g <= pRows改为g < pRows,避免索引越界。 - 数组初始化:
var data = [],确保可以正常调用push或concat。 - 索引修正:取Progress表数据时使用
g索引,保证对应行的数据正确。 - 结构一致性:为"CR"用户的数组补全5个元素,避免后续数据写入时的维度错误。
- 空行过滤:添加
if (!outDate[i][0]) continue跳过空行,减少无效循环。
内容的提问来源于stack exchange,提问作者Matt Marshall
相关产品推荐
相关产品推荐

