Google Apps Script自定义ID计数器跳号问题求助
解决Google Apps Script计数器跳号问题
问题根源分析
你的代码出现跳号和逻辑不符的问题,核心原因有三点:
- 重置逻辑与需求冲突:代码中写的是
if (counter > 99) counter = 0;,但需求是计数器递增至365后重置,直接导致计数器提前重置、逻辑混乱。 - 并发竞态条件:多个请求同时触发
doGet时,会同时读取counter值,各自递增后再写入,导致计数器跳号或生成重复ID。比如两个请求同时读到counter=10,都用10生成ID,再将counter设为11,既会出现重复ID,也会跳过后续计数。 - 未按日期重置计数器:ID包含
ddMM日期段,但代码未判断日期变化,跨天后计数器不会重置,不符合日期+计数的ID设计逻辑。
修复后的完整代码
function doGet(e) { var ss = SpreadsheetApp.getActive(); var sheet1 = ss.getSheetByName("Stocks"); var sheet2 = ss.getSheetByName('Stocks_Synthesis'); var scriptProperties = PropertiesService.getScriptProperties(); var lock = LockService.getScriptLock(); try { // 等待30秒获取锁,超时终止请求避免死锁 lock.waitLock(30000); var currentDate = Utilities.formatDate(new Date(), "GMT+4", "ddMM"); var storedDate = scriptProperties.getProperty('currentDate') || ""; var counter = Number(scriptProperties.getProperty('counter')) || 0; // 跨天自动重置计数器 if (storedDate !== currentDate) { counter = 0; scriptProperties.setProperty('currentDate', currentDate); } // 生成带两位前导零的计数器部分,保证ID格式统一 var formattedCounter = counter.toString().padStart(2, '0'); var ID = "FS" + currentDate + formattedCounter; // 递增计数器,达到365时重置为0 counter++; if (counter > 365) { counter = 0; } scriptProperties.setProperty('counter', counter); } finally { // 无论请求成功与否,必须释放锁 lock.releaseLock(); } var TimeStamp = Utilities.formatDate(new Date(), "GMT+4", "dd-MM-yy HH:mm:ss"); var Link = "check your inbox"; const { Region, Place, Staff, Shop, Location, Date_Checked, Time_Checked, Remarks, Hkey } = e.parameter; const row = [TimeStamp, ID, Region, Place, Staff, Shop, Location, Date_Checked, Time_Checked, Link, Remarks]; if (Hkey == 'AB12xyz') { const res = [...Array(20)].reduce((ar, _, h) => { var i = h + 1; var computer = e.parameter['computer' + i]; if (computer) { ar.push([...row, computer, ...['brand', 'cpu', 'ram'].map(f => e.parameter[`${f}${i}`] || "")]); } return ar; }, []); if (res.length == 0) return; [sheet1, sheet2].forEach(sheet => sheet.getRange(sheet.getLastRow() + 1, 1, res.length, res[0].length).setValues(res)); } return ContentService.createTextOutput("ok"); }
关键修改说明
- 添加脚本锁:通过
LockService实现计数器的原子性读写,彻底解决并发请求导致的跳号/重复问题,同一时间仅一个请求能操作计数器。 - 日期同步重置:新增
currentDate属性存储当前日期,每次请求校验日期,跨天自动重置计数器,符合ID的日期+计数设计逻辑。 - 修正重置条件:将计数器重置阈值从99改为365,匹配需求中“递增至365后重置”的要求。
- 优化ID格式:用
padStart(2, '0')统一为计数器补两位前导零,避免原代码中zero变量的逻辑混乱,保证ID格式一致(如FS010101、FS010199)。 - 安全锁释放:用
try...finally确保锁一定会被释放,避免因请求异常导致的死锁。
内容的提问来源于stack exchange,提问作者P.J
相关产品推荐
相关产品推荐

