Google Apps Script竞态条件处理:谷歌表格多人编辑任务队列优化
谷歌表格脚本竞态问题与功能扩展需求
我有一份支持多人编辑的谷歌表格,通过Google Apps Script实现了以下功能:当源工作表ScriptTestingSource中第18列的复选框被设为TRUE时,将该行的部分数据复制到目标工作表ScriptTestingTarget,以此启动内部跟踪流程。
原脚本在单个任务场景下运行正常,但当用户快速勾选多个行的复选框时,会出现目标工作表新行被重复覆盖的竞态问题。
原脚本代码如下:
function onEdit(e){ //get the sheet where the edit occurs var ss = SpreadsheetApp.getActive(); var sourceSheet = e.range.getSheet(); var sourceRange = e.range; var sourceRow = sourceRange.getRow(); var sourceColumn = sourceRange.getColumn(); if((sourceSheet.getName() == "ScriptTestingSource") && e.range.columnStart==18 && e.range.rowStart >= 2){ if(e.value == "TRUE"){ var targetSheet = ss.getSheetByName("ScriptTestingTarget"); var sourceValues = sourceSheet.getRange(sourceRow,1,1,11).getValues(); //splice off unneeded values sourceValues[0].splice(7,1) sourceValues[0].splice(3,2) sourceValues[0].splice(0,1) //insert new row on on target sheet var targetRows = targetSheet.getDataRange().getNumRows() targetSheet.insertRowsAfter(targetRows,1); targetSheet.getRange(targetRows+1,1,1,7).setValues(sourceValues) } } }
尝试的队列解决方案(无法正常运行)
为解决竞态问题,我尝试将任务逻辑从onEdit函数中剥离,改用数组作为任务队列来依次处理任务,但编写的脚本无法正常运行:
var workQueue = []; var working = false; function onEdit(e){ var ss = SpreadsheetApp.getActive(); var sourceSheet = e.range.getSheet(); var sourceRange = e.range; var sourceRow = sourceRange.getRow(); var sourceColumn = sourceRange.getColumn(); if((sourceSheet.getName() == "ScriptTestingSource") && e.range.columnStart==18 && e.range.rowStart >= 2){ if(e.value == "TRUE"){ workQueue.push([0,sourceSheet,sourceRange,sourceRow,sourceColumn]) if(workQueue.length<1 && working==false){ doWork(); } } } } function doWork(){ working=true; while(workQueue.length>0){ workOrder = workQueue[0] switch(workOrder[0]){ //0: copy data for carrier tracking to sheet case 0: //copy data to sheet order var sourceSheet = workOrder[1]; var sourceRange = workOrder[2]; var sourceRow = workOrder[3]; var sourceColumn = workOrder[4]; //get values from sheet var sourceValues = sourceSheet(sourceRow,1,1,11); //trim and clean data sourceValues[0].splice(7,1); sourceValues[0].splice(3,2); sourceValues[0].splice(0,1); //insert new row in target sheet var targetSheet = ss.getSheetByName("ScriptTestingTarget"); var targetRows = targetSheet.getDataRange().getNumRows(); targetSheet.insertRowsAfter(targetRows,1); targetSheet.getRange(targeRows+1,1,1,7).setValues(sourceValues); workQueue.pop(); break; default: break; } } working=false; }
需求目标
- 实现任务队列的顺序处理逻辑,彻底解决快速多任务操作时的竞态问题
- 扩展模块化功能:当用户误勾选复选框后取消(设为
FALSE)时,通过唯一标识键值自动删除目标工作表中对应的行
内容的提问来源于stack exchange,提问作者SciChronic
相关产品推荐
相关产品推荐

