运行添加谷歌表单条目的函数后Google Script的getValue()返回false问题
问题根因
- 第一,
showModalDialog不会阻塞后端脚本执行:弹窗弹出后,脚本会立即执行后续的循环读取逻辑,不会等待前端触发表单提交完成,你看到页面单元格变为TRUE的时候,脚本的循环可能已经执行完毕了。 - 第二,Google Apps Script 对电子表格数据有读取缓存:你循环中反复调用
getValue()读取的是脚本初始化时缓存的旧数据,不会主动拉取表格的最新计算结果,哪怕页面上已经更新,缓存也不会自动刷新。
修复方案
不要依赖公式计算结果做脚本判断条件,直接用脚本实现逻辑的稳定性更高,你可以选择任意一种方案修复:
方案1:最小改动,仅修复缓存和等待时长问题
在读取单元格前强制刷新缓存,同时调长等待总时长给表单提交留足时间,修改循环部分代码即可:
var n,check; // 调长循环到20次,每次等待1秒,总等待时长20秒 for(n=0;n<20;n++){ SpreadsheetApp.flush(); // 强制刷新表格缓存,拉取最新数据 check = ws_MAIN.getRange("O31").getValue(); if(check==true){ deleteData(); return; } Utilities.sleep(1000); } // 可选:新增超时提示 SpreadsheetApp.getUi().alert("提交超时,请手动确认数据是否提交成功后重试");
方案2:更稳定,直接在脚本中实现匹配逻辑
跳过读取公式结果,直接读取B4的值和FormResponses表D列做匹配,避免公式计算和缓存的双重问题,完整修改后代码如下:
function registerTest() { var ws_MAIN = SpreadsheetApp.getActiveSheet(); var url = ws_MAIN.getRange("U1").getValue(); if(url=="") return SpreadsheetApp.getUi().alert("ERROR: Incomplete data"); var html = HtmlService.createHtmlOutput('<html><script>' +'window.close = function(){window.setTimeout(function(){google.script.host.close()},9)};' +'var a = document.createElement("a"); a.href="'+url+'"; a.target="_blank";' +'if(document.createEvent){' +' var event=document.createEvent("MouseEvents");' +' if(navigator.userAgent.toLowerCase().indexOf("firefox")>-1){window.document.body.append(a)}' +' event.initEvent("click",true,true); a.dispatchEvent(event);' +'}else{ a.click() }' +'close();' +'</script>' +'<body style="word-break:break-word;font-family:sans-serif;">Unable to register automatically. <a href="'+url+'" target="_blank" onclick="window.close()">Please clic here</a>.</body>' +'<script>google.script.host.setHeight(40);google.script.host.setWidth(410)</script>' +'</html>') .setWidth(90).setHeight(1); SpreadsheetApp.getUi().showModalDialog(html,"Registering..." ); // 预获取需要匹配的ID和表单响应表 var targetId = ws_MAIN.getRange("B4").getValue(); var formSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("FormResponses"); var n,check, colDValues; for(n=0;n<20;n++){ SpreadsheetApp.flush(); // 每次拉取D列最新数据做匹配 colDValues = formSheet.getRange("D:D").getValues().flat(); check = colDValues.indexOf(targetId) > -1; if(check==true){ deleteData(); return; } Utilities.sleep(1000); } SpreadsheetApp.getUi().alert("提交超时,请手动确认数据是否提交成功后重试"); }
内容的提问来源于stack exchange,提问作者HoraceG
相关产品推荐
相关产品推荐

