如何在Google Apps Script中逐月存储数据以实现月度统计对比?
解决方案
要实现每月发送统计邮件时做双月对比,核心是保留历史月份的统计数据,不能用单一键覆盖旧值。可以通过给存储键添加YYYY-MM格式的年月前缀,把每个月的统计数据独立存储,这样就能随时调用上月数据做对比。
具体实现步骤
1. 新增年月格式化辅助函数
用来生成标准的年月字符串(比如2024-09),避免跨年时的月份冲突:
// 获取上月的YYYY-MM格式字符串(每月1号执行时,对应要统计的月份) function getTargetYearMonth() { const now = new Date(); now.setMonth(now.getMonth() - 1); const year = now.getFullYear(); const month = String(now.getMonth() + 1).padStart(2, '0'); return `${year}-${month}`; } // 根据指定年月,返回前一个月的YYYY-MM字符串 function getPrevYearMonth(targetMonthStr) { const [year, month] = targetMonthStr.split('-').map(Number); const date = new Date(year, month - 1, 1); date.setMonth(date.getMonth() - 1); return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`; }
2. 修改主流程代码
每月1号执行的脚本中,先取出上月历史数据,生成对比邮件,再保存当前月份的统计结果:
function sendMonthlyStats() { const scriptProperties = PropertiesService.getScriptProperties(); // 1. 确定当前要统计的月份(上月)和对比月份(上上月) const targetMonth = getTargetYearMonth(); const prevMonth = getPrevYearMonth(targetMonth); // 2. 取出对比月份的历史统计数据(如果存在) const prevStatsStr = scriptProperties.getProperty(`stats_${prevMonth}`); const prevStats = prevStatsStr ? JSON.parse(prevStatsStr) : null; // 3. 计算当前目标月份的统计数据(这里替换成你的实际统计逻辑) const monthName = new Date(targetMonth).toLocaleString('en-US', { month: 'long', year: 'numeric' }); const totalReferrals = /* 你的上月总推荐数统计逻辑 */; const intakesComplete = /* 你的上月完成Intake数统计逻辑 */; const intakesReturned = /* 你的上月退回Intake数统计逻辑 */; const completedVsReturned = /* 你的完成率vs退回率计算逻辑 */; // 4. 构建包含双月对比的邮件内容 let emailBody = `<h3>${monthName} 统计报告</h3> <ul> <li>总推荐数: ${totalReferrals}</li> <li>完成Intake数: ${intakesComplete}</li> <li>退回Intake数: ${intakesReturned}</li> <li>完成率vs退回率: ${completedVsReturned}</li> </ul>`; // 如果有历史数据,添加对比模块 if (prevStats) { emailBody += `<h3>与 ${prevStats.month} 对比</h3> <ul> <li>总推荐数变化: ${totalReferrals - prevStats.totalReferrals > 0 ? '+' : ''}${totalReferrals - prevStats.totalReferrals}</li> <li>完成Intake数变化: ${intakesComplete - prevStats.intakesComplete > 0 ? '+' : ''}${intakesComplete - prevStats.intakesComplete}</li> <li>退回Intake数变化: ${intakesReturned - prevStats.intakesReturned > 0 ? '+' : ''}${intakesReturned - prevStats.intakesReturned}</li> </ul>`; } // 5. 发送邮件 MailApp.sendEmail({ to: 'your-recipient@example.com', subject: `${monthName} 统计报告`, htmlBody: emailBody }); // 6. 保存当前月份的统计数据到PropertiesService const currentStats = { month: monthName, totalReferrals, intakesComplete, intakesReturned, completedVsReturned }; scriptProperties.setProperty(`stats_${targetMonth}`, JSON.stringify(currentStats)); }
3. 关键说明
- 存储结构优化:把整个月份的统计对象序列化为JSON字符串存储,比单独存每个字段更简洁易维护
- 年月标识:用
YYYY-MM作为键的前缀,确保跨年时不会出现月份重复的问题(比如2023-12和2024-12是两个独立的键) - 数据时效性:因为数据源实时变化,必须在每月1号执行脚本时立即计算并保存上月统计数据,确保拿到的是1号当天的准确值
内容的提问来源于stack exchange,提问作者Half Jesus
相关产品推荐
相关产品推荐

