使用Google Apps Script统计谷歌表格背景色(含合并单元格)遇阻
解决合并单元格按实际数量统计颜色单元格的问题
问题诊断
formula.match(/\((.*)\,/).pop()报错的核心原因是正则匹配未找到预期结果,返回null后调用pop()触发空值错误,大概率是公式格式不符合解析逻辑,或是拆分后的区域参数解析失败。
修复方案
方案1:全流程整合,跳过公式解析(推荐)
直接在菜单触发的函数里完成拆分、统计、恢复的完整流程,避免依赖公式解析带来的风险:
function calcHourlySplitByColour() { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const targetRange = sheet.getRange("A2:O30"); // 替换为你的日程表目标区域 const colorCounts = { purple: 0, orange: 0, green: 0 }; // 1. 记录合并单元格信息并拆分 const mergeInfo = breakApartRange(targetRange); // 2. 遍历单元格统计对应颜色数量 const cellColors = targetRange.getBackgrounds(); cellColors.forEach(row => { row.forEach(color => { // 替换为你实际使用的颜色代码 if (color === "#9C27B0") colorCounts.purple++; else if (color === "#FF9800") colorCounts.orange++; else if (color === "#4CAF50") colorCounts.green++; }); }); // 3. 计算时长(数量/2)并写入指定单元格 sheet.getRange("P2").setValue(colorCounts.purple / 2); sheet.getRange("P3").setValue(colorCounts.orange / 2); sheet.getRange("P4").setValue(colorCounts.green / 2); // 4. 恢复合并单元格 reMergeRange(targetRange, mergeInfo); } // 保留你的拆分合并单元格函数 function breakApartRange(range) { const mergeRecords = []; range.getMergedRanges().forEach(merge => { mergeRecords.push({ startRow: merge.getRow(), endRow: merge.getLastRow(), startCol: merge.getColumn(), endCol: merge.getLastColumn() }); merge.unmerge(); }); return mergeRecords; } // 保留你的恢复合并单元格函数 function reMergeRange(range, mergeRecords) { const sheet = range.getSheet(); mergeRecords.forEach(record => { sheet.getRange( record.startRow, record.startCol, record.endRow - record.startRow + 1, record.endCol - record.startCol + 1 ).merge(); }); } function onOpen() { SpreadsheetApp.getUi() .createMenu("统计工具") .addItem("计算场景时长", "calcHourlySplitByColour") .addToUi(); }
方案2:修复正则解析逻辑(若需保留公式调用)
如果必须通过公式调用统计函数,给正则匹配增加空值判断:
function countColouredCells2(range, color) { const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let targetRange; // 增加错误处理,避免空值调用pop() const formula = SpreadsheetApp.getActiveRange().getFormula(); const matchResult = formula.match(/\((.*)\,/); if (!matchResult || matchResult.length < 2) { return "参数解析错误"; } const rangeStr = matchResult.pop().trim(); targetRange = sheet.getRange(rangeStr); // 后续统计逻辑... }
注意事项
- 替换代码中的颜色代码为你日程表实际使用的背景色(可通过单元格
getBackground()方法获取准确值) - 确认目标区域范围与你的日程表单元格范围一致
- 测试前备份表格,避免合并单元格恢复异常
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

