如何在Google Sheets列校验扫码值是否重复并在HTML页提示
二维码扫码Google Web App去重问题
我正在开发一款可扫描二维码的Google Web App,通过Google Sheets存储解码后的文本值。当前代码只能防止连续扫描同一二维码的重复,但如果在两次不同扫码操作之间重复扫同一二维码,Sheet的A列还是会出现重复数据。
需要实现的功能:扫码获取文本后,先检查Google Sheets中是否已存在该文本(不是仅检查上一次结果),存在则在HTML页面显示“已存在”提示;不存在则添加到Sheet中。
当前可运行代码
Google Apps Script(GS)代码
var ss=SpreadsheetApp.getActiveSpreadsheet(); var sheet=ss.getSheets()[0]; function doGet() { var tmpl=HtmlService.createTemplateFromFile('index'); return tmpl.evaluate().setTitle('index'); } function sendback(x){ var y=sheet.getLastRow()+1; sheet.getRange(y, 1).setValue(x); return "ok"; }
HTML代码
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script> <script src="https://unpkg.com/html5-qrcode@2.0.9/dist/html5-qrcode.min.js"></script> <script type="text/javascript"> var resultContainer = document.getElementById('qr-reader-results'); var lastResult, countResults = 0; async function onScanSuccess(decodedText, decodedResult) { if (decodedText !== lastResult) { ++countResults; lastResult = decodedText; console.log(`Scan result ${decodedText}`, decodedResult); google.script.run.sendback(decodedText); await waitme() $('#qr-reader-results').prepend("<p>" + decodedText + "</p>"); } } setTimeout(function(){ var html5QrcodeScanner = new Html5QrcodeScanner( "qr-reader", { fps: 10, qrbox: 250 }); html5QrcodeScanner.render(onScanSuccess); },500); function waitme(){ promise1=new Promise(function(resolve){ setTimeout(function(){ resolve('ok'); },1000) }) return promise1; } window.addEventListener('beforeunload', function (e) { e.preventDefault(); e.returnValue = '3'; }); </script>
尝试过的无效代码
修改后的GS代码
function sendback(x) { var sheet = ss.getSheets()[0]; var data = sheet.getDataRange().getValues(); for (var i = 0; i < data.length; i++) { if (data[i][0] == x) { return "fail"; } } var y = sheet.getLastRow() + 1; sheet.getRange(y, 1).setValue(x); return "ok"; }
修改后的HTML中onScanSuccess函数
async function onScanSuccess(decodedText, decodedResult) { var result = await google.script.run.sendback(decodedText); if (result === "fail") { console.log("Already exists."); } else if (result === "ok") { console.log(`Scan result ${decodedText}`, decodedResult); $('#qr-reader-results').prepend("<p>" + decodedText + "</p>"); } }
解决方案
问题核心:google.script.run是异步调用,不能直接用await,必须通过回调函数处理返回结果。同时要保留防止连续重复扫码的逻辑,避免重复触发检查。
1. 更新Google Apps Script代码
检查逻辑保留,改用更可靠的appendRow添加数据:
var ss=SpreadsheetApp.getActiveSpreadsheet(); var sheet=ss.getSheets()[0]; function doGet() { var tmpl=HtmlService.createTemplateFromFile('index'); return tmpl.evaluate().setTitle('index'); } function sendback(x) { var data = sheet.getDataRange().getValues(); // 遍历A列检查是否已存在目标文本 for (var i = 0; i < data.length; i++) { if (data[i][0] === x) { return "exists"; } } // 不存在则追加到Sheet末尾 sheet.appendRow([x]); return "added"; }
2. 更新HTML中的扫码成功处理函数
使用.withSuccessHandler处理返回结果,保留防连续重复逻辑:
async function onScanSuccess(decodedText, decodedResult) { if (decodedText !== lastResult) { ++countResults; lastResult = decodedText; console.log(`Scan result ${decodedText}`, decodedResult); // 调用GS函数并处理返回值 google.script.run .withSuccessHandler(function(response) { if (response === "exists") { // 显示已存在提示 $('#qr-reader-results').prepend("<p style='color:red;'>已存在:" + decodedText + "</p>"); } else if (response === "added") { // 显示添加成功提示 $('#qr-reader-results').prepend("<p style='color:green;'>已添加:" + decodedText + "</p>"); } }) .withFailureHandler(function(error) { console.error("处理出错:", error); $('#qr-reader-results').prepend("<p style='color:orange;'>出错:" + error.message + "</p>"); }) .sendback(decodedText); await waitme(); } }
关键说明
google.script.run必须通过回调函数获取返回值,不能直接用await,这是之前尝试失败的主要原因。appendRow([x])比getLastRow()+1的方式更可靠,避免并发操作导致的行号错误。- 给不同状态的提示添加颜色区分,提升用户体验。
内容的提问来源于stack exchange,提问作者Chloe Ricasata
相关产品推荐
相关产品推荐

