Excel宏迁移为Google Script后大数据量运行超时问题求助
你当前脚本超时的核心问题是循环内反复调用Spreadsheet的读写接口(getRange()、getValue()、setValue()),这类接口属于跨服务调用,单次耗时就很高,上千条数据的双层循环会产生数万次调用,必然触发超时。
优化方案是将所有数据一次性读取到内存中做数组运算,最后批量写入结果,同时用哈希映射替换双层循环,把时间复杂度从O(n*m)降到O(n+m),优化后处理上千条数据基本可以在1秒内跑完。
优化后代码如下:
function getTransportDates() { const ss = SpreadsheetApp.getActive(); // 提前获取两个工作表实例,避免重复查询 const bilanSheet = ss.getSheetByName('BILAN'); const inputSheet = ss.getSheetByName('INPUT'); // 一次性读取INPUT表需要的所有数据(第4行开始的A、B列) const inputRows = inputSheet.getRange(4, 1, inputSheet.getLastRow() - 3, 2).getValues(); // 构建地址-日期映射表,后续直接查映射不需要循环匹配 const addrDateMap = {}; inputRows.forEach(row => { const addr = row[1]; // B列是匹配地址 const date = row[0]; // A列是运输日期 if (!addrDateMap[addr]) addrDateMap[addr] = []; addrDateMap[addr].push(date); }); // 一次性读取BILAN表需要的所有数据(第4行开始的A到J列) const bilanLastRow = bilanSheet.getLastRow(); const bilanRows = bilanSheet.getRange(4, 1, bilanLastRow - 3, 10).getValues(); // 内存中完成所有行的逻辑处理 bilanRows.forEach(row => { // 原逻辑:第9列(I列)值大于0才拼接日期 if (row[8] > 0) { const targetAddr = row[0]; // A列是匹配地址 const dates = addrDateMap[targetAddr] || []; // 拼接日期字符串,赋值给第10列(J列) row[9] = dates.join(' // '); // 如果需要格式化日期,可替换为下行逻辑 // row[9] = dates.map(d => d.toISOString().split('T')[0]).join(' // '); } else { row[9] = ''; } }); // 一次性把处理好的所有结果写回BILAN表,仅1次写入操作 bilanSheet.getRange(4, 1, bilanLastRow - 3, 10).setValues(bilanRows); }
代码逻辑和你原实现完全一致,没有修改业务规则,可直接替换使用。
内容的提问来源于stack exchange,提问作者Jonathan Le Maire
相关产品推荐
相关产品推荐

