Google Apps Script匹配表单值更新/新增Google表格行问题
问题根因
你的重复行匹配逻辑完全不生效,是3个明确的代码错误导致的:
- for循环判断条件写反:原代码写的
i > rangeData.length,循环启动时i=1,只要表格有数据rangeData.length必然大于1,判断条件直接不成立,循环一次都不会执行,永远走新增行逻辑 - 表单取值语法错误:doPost接收到的表单参数全部存储在
e.parameter对象下,你循环判断时直接写e.firstName/e.lastName取到的都是undefined,永远不可能和表格里的值匹配 - 数组索引和表格行号映射错误:
getValues()返回的二维数组索引从0开始,rangeData[0]对应表格第1行(表头行),直接把数组下标i赋值给nextRow会导致写入行号错位;另外找到匹配项后没有跳出循环,存在多匹配项时行号会被覆盖为最后一个匹配项的位置
额外前端问题:HTML里嵌套了两层<form>标签,不符合HTML规范,可能导致FormData取值异常。
修复后代码
前端HTML代码
<form id="form"> <input name="firstName" placeholder="firstName" /> <input name="lastName" placeholder="lastName" /> <input name="someOtherField" placeholder="someOtherField" /> <input name="someFourthField" placeholder="someFourthField" /> <div class="btn-success btn" onclick="SaveData()">Save Data</div> </form> <script> function SaveData() { var formData = new FormData(document.getElementById("form")); fetch('https://script.google.com/macros/s/AKfycbwQFSXfeOKBHzf41MF6Nh5XIOjaPvr159-blUxsg5smD3BDH8qB4RUZRRo8q9nCJLb18w/exec', { method: 'post', body: formData, }) } </script>
Apps Script 后端代码
var sheetName = 'Entries' var scriptProp = PropertiesService.getScriptProperties() function intialSetup () { var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet() scriptProp.setProperty('key', activeSpreadsheet.getId()) } function doPost (e) { var lock = LockService.getScriptLock() lock.tryLock(10000) try { var doc = SpreadsheetApp.openById(scriptProp.getProperty('key')) var sheet = doc.getSheetByName(sheetName) var headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0] var nextRow = sheet.getLastRow() + 1 var newRow = headers.map(function(header) { return header === 'timestamp' ? new Date() : e.parameter[header] }) var range = sheet.getDataRange(); var rangeData = range.getValues(); // 提前拿到提交的姓名参数,避免循环里重复取值 var submitFirstName = e.parameter.firstName.trim(); var submitLastName = e.parameter.lastName.trim(); // 修复循环条件:从第2行(数组索引1,对应表头下第一行数据)开始遍历,到数组最后一位结束 for(let i = 1; i < rangeData.length; i++) { // 取值时做去空格处理,避免表格/表单里的前后空格导致匹配失败,数组索引0对应firstName列、1对应lastName列 var rowFirstName = rangeData[i][0].toString().trim(); var rowLastName = rangeData[i][1].toString().trim(); if(rowFirstName === submitFirstName && rowLastName === submitLastName) { // 数组索引i对应表格行号是i+1,修正行号映射 nextRow = i + 1; // 找到匹配项直接跳出循环,避免后续重复行覆盖行号 break; } } sheet.getRange(nextRow, 1, 1, newRow.length).setValues([newRow]) return ContentService .createTextOutput(JSON.stringify({ 'result': 'success', 'row': nextRow })) .setMimeType(ContentService.MimeType.JSON) } catch (e) { return ContentService .createTextOutput(JSON.stringify({ 'result': 'error', 'error': e })) .setMimeType(ContentService.MimeType.JSON) } finally { lock.releaseLock() } }
额外说明
- 匹配逻辑里加了
trim()去前后空格处理,避免用户输入或者表格里不小心带的空格导致明明值一样却匹配失败的问题 - 循环里用
let声明i变量,避免全局变量污染 - 修正了HTML里重复的form标签、重复的placeholder错误
内容的提问来源于stack exchange,提问作者StephanB
相关产品推荐
相关产品推荐

