Google Sheets根据参考值为赛程单元格着色的Apps Script效率优化方法
性能问题根因
- 原代码在嵌套循环中反复调用
getRange、getValue、setBackground等工作表读写接口,这类接口每次都需要和Google Sheets服务器交互,累计上千次调用就会触发超时限制。 findRow函数每次执行都会全量读取FDR表遍历查找队伍行号,重复调用产生了大量冗余计算。
优化后代码
优化核心是把所有需要的数据一次性读取到内存中计算,最终结果批量写入工作表,将读写操作压缩到个位数:
// 优化后的着色函数 function colorMeUp() { const ss = SpreadsheetApp.getActive(); const fixSheet = ss.getSheetByName('Fixtures'); const fdrSheet = ss.getSheetByName('FDR'); // 1. 一次性读取所有需要的数据到内存 // 读取FDR全表数据 const fdrData = fdrSheet.getDataRange().getValues(); // 预先生成 队伍名→行号 的映射,不需要每次遍历查找 const teamRowMap = {}; fdrData.forEach((row, idx) => { if (row[1]) { // 对应原逻辑的第二列(索引1)存队伍名 teamRowMap[row[1]] = idx + 1; // 行号是索引+1 } }); // 预读取难度对应的颜色表 const diffColors = fdrSheet.getRange(1, 8, 10, 1).getBackgrounds().map(row => row[0]); // 读取Fixtures表需要处理的所有单元格值 const fixRange = fixSheet.getRange(4, 2, 20, 39); // 行4到23共20行,列2到40共39列 const fixValues = fixRange.getValues(); // 初始化背景色二维数组,后续批量写入 const backgrounds = []; // 2. 内存中计算所有单元格颜色 for (let i = 0; i < fixValues.length; i++) { const rowBg = []; const masterTeam = fixValues[i][0]; // 每行第二列是参考队伍,对应索引0 const rowNumMaster = teamRowMap[masterTeam]; for (let j = 1; j < fixValues[i].length; j++) { // 从第三列开始是赛程,对应索引1 const tempTeam = fixValues[i][j]; const rowNumTemp = teamRowMap[tempTeam]; let adjustedMasterRow = rowNumMaster; if (rowNumTemp < 23) { adjustedMasterRow = rowNumMaster + 20; } // 从已经读入内存的fdrData里拿评分,不用再读表 const tempRating = fdrData[rowNumTemp - 1][3]; // 第四列索引是3,行号转索引要减1 const masterRating = fdrData[adjustedMasterRow - 1][3]; const fixDiff = masterRating + (6 - tempRating); rowBg.push(diffColors[fixDiff]); // 从预读的颜色数组里取颜色 } backgrounds.push(rowBg); } // 3. 一次性批量写入所有背景色 fixSheet.getRange(4, 3, 20, 38).setBackgrounds(backgrounds); }
优化效果
修改后代码的读写操作仅保留了4次读表、1次写表,没有冗余计算,执行速度会比原代码提升至少100倍,不会再触发超时限制。
内容的提问来源于stack exchange,提问作者DoofEvil
相关产品推荐
相关产品推荐

