Google Apps Script日期匹配失效:Index Match脚本异常求助
问题排查与修复方案
你的脚本有两个核心问题导致日期场景失效,同时还有一个隐藏的更新逻辑错误:
1. 日期类型不匹配导致匹配失败
你用getDisplayValues()获取entry表C7:I7的日期,得到的是字符串格式(比如"14.11.2024"),但database表A列用getValues()获取的是Date对象。indexOf无法匹配不同类型的值,所以即使日期实际存在,也会被判定为“无匹配”。
2. 更新逻辑错位
找到匹配项后,你用entry数组的索引i去更新dbColBValues[i],但idxMatch才是database中匹配项的真实索引,用i会导致更新错误的行(比如entry第2个值匹配到database第5行,却错误更新database第2行的B列)。
修复后的完整脚本
function CopyEntry2Db() { var ss = SpreadsheetApp.getActiveSpreadsheet(); var entrySheet = ss.getSheetByName("entry"); var dbSheet = ss.getSheetByName("database"); // 定义统一的日期格式化规则(和你的显示格式一致) var dateFormat = "dd.MM.yyyy"; var timeZone = "GMT+1"; // 获取entry表C7:I7的值(Date对象),并格式化为统一字符串 var entryRow4Dates = entrySheet.getRange("C7:I7").getValues().flat(); var entryRow4 = entryRow4Dates.map(function(date) { // 只处理Date类型的值,非日期直接保留原内容 return date instanceof Date ? Utilities.formatDate(date, timeZone, dateFormat) : date; }); // 获取entry表C4:I4的值 var entryRow7 = entrySheet.getRange("C4:I4").getValues().flat(); // 获取database表A、B列的数据,并将A列日期格式化为统一字符串 var dbSheetLR = dbSheet.getLastRow(); if (dbSheetLR < 2) { // 处理database表只有表头的情况 var dbColAValues = []; var dbColBValues = []; } else { var dbColADates = dbSheet.getRange(2, 1, dbSheetLR - 1, 1).getValues().flat(); var dbColBValues = dbSheet.getRange(2, 2, dbSheetLR - 1, 1).getValues().flat(); // 格式化database A列的日期为统一字符串 dbColAValues = dbColADates.map(function(date) { return date instanceof Date ? Utilities.formatDate(date, timeZone, dateFormat) : date; }); } var tempArray = []; // 循环处理每个entry值 for (var i = 0; i < entryRow4.length; i++) { var idxMatch = dbColAValues.indexOf(entryRow4[i]); if (idxMatch === -1) { // 无匹配,加入待追加数组 tempArray.push([entryRow4[i], entryRow7[i]]); } else { // 有匹配,更新database B列对应位置的值 dbColBValues[idxMatch] = entryRow7[i]; } } // 更新database B列数据(用更简洁的方式转二维数组) if (dbColBValues.length > 0) { var nArr = dbColBValues.map(function(val) { return [val]; }); dbSheet.getRange(2, 2, nArr.length, 1).setValues(nArr); } // 追加新数据到database if (tempArray.length > 0) { dbSheet.getRange(dbSheetLR + 1, 1, tempArray.length, 2).setValues(tempArray); } }
关键修改说明
- 统一日期格式化:将entry和database的日期都转成
dd.MM.yyyy格式的字符串,确保类型和格式完全一致,indexOf能正确匹配。 - 修正更新索引:用
idxMatch(database中的匹配位置)替代i(entry中的索引)更新B列值,避免更新错位。 - 边界处理:增加了database表只有表头时的空数组处理,防止报错。
- 简化数组转换:用
map替代while循环转二维数组,代码更简洁易读。
内容的提问来源于stack exchange,提问作者John Kater
相关产品推荐
相关产品推荐

