如何让Google脚本仅在指定表单关联的工作表提交时执行?
解决Google Apps Script仅触发指定表单提交的问题
我来帮你排查这个问题,你遇到的情况是修改表单提交触发函数后,脚本无法正常创建文档和触发云打印,大概率是几个常见的配置或逻辑问题,咱们一步步来解决:
可能的问题根源
你的修改思路是对的——通过判断提交对应的工作表名称来过滤触发逻辑,但失效的原因通常集中在触发器配置、名称匹配、字段索引、缺失配置项这几个点上。
分步解决方案
1. 验证触发器配置是否正确
Google表单关联到表格后,表单提交的触发器需要绑定到电子表格而非表单本身,否则e.range等参数可能无法正确获取:
- 打开你的Google表格,点击「扩展程序」→「Apps Script」
- 点击左侧「触发器」图标,检查现有触发器:
- 确认「事件源」是电子表格,「事件类型」是表单提交
- 确保触发器绑定的函数是修改后的
onFormSubmit - 如果没有符合要求的触发器,点击「添加触发器」按上述配置重新创建
2. 核对工作表名称的准确性
代码中判断的"Job Submission"必须和表格中实际的工作表名称完全一致(包括大小写、空格),比如不能写成"job submission"或"JobSubmission"。
可以在函数中添加日志来排查:
function onFormSubmit(e) { var rng = e.range; var sheet = rng.getSheet(); var name = sheet.getName(); Logger.log("当前提交的工作表:" + name); // 新增日志 if(name !== "Job Submission") { Logger.log("非目标工作表,终止执行"); return; } // 后续代码... }
提交测试表单后,点击Apps Script编辑器的「查看」→「日志」,确认名称是否匹配。
3. 确认表单字段顺序与values索引匹配
createNewDoc函数中使用values[1]、values[2]等索引获取表单字段,这些索引对应表单的提交顺序(values[0]是系统自动添加的提交时间):
- 打开「Job Submission」对应的Google表单,检查字段顺序
- 确保
values[1]对应「job_name」、values[7]对应「order_form」等,若表单字段有新增/删除,需要同步调整索引
4. 补全代码中缺失的关键配置项
你的代码中有几个必填项是空的,这会直接导致功能失败:
var docTemplate = "";:替换为你的Google Docs模板ID(从模板文档URL中提取,格式类似123abcXYZ...)var printerId = ""和printGoogleDocument中的"printerid" : "":替换为你的Google云打印机IDMailApp.sendEmail(email_address, ...)中的email_address:设置为接收工单邮件的邮箱(可以固定填写,也可以从表单字段中获取,比如values[8]如果是邮箱字段就用这个索引)DriveApp.getFolderById("").addFile(file):替换为要存放工单文档的目标文件夹ID
5. 重新授权脚本
修改函数后,脚本可能需要重新获取权限才能访问Drive、MailApp等服务:
- 打开Apps Script编辑器,点击「运行」→「运行函数」→选择
onFormSubmit - 按照提示完成授权流程(必须使用拥有表格和表单权限的账号)
6. 通过日志定位具体错误
如果还是无法正常运行,在关键函数中添加日志来定位问题:
- 在
createNewDoc开头添加:Logger.log("表单提交数据:" + values); - 在
printGoogleDocument开头添加:Logger.log("准备打印的文档ID:" + copyId);
提交测试表单后查看日志,就能清楚看到哪一步出现了错误(比如复制模板失败、发送邮件失败等)
修改后的完整示例代码
以下是补全配置项和日志后的代码,你可以直接替换使用:
// 工单配置项 - 请务必补全以下信息 var docTemplate = "你的Google Docs模板ID"; var docName = "Work Order"; var printerId = "你的Google云打印机ID"; var targetFolderId = "存放工单的文件夹ID"; var emailRecipient = "接收邮件的邮箱@example.com"; function addDates() { var date = new Date(); var holiday = ["09/04/2017","10/09/2017","11/23/2017","12/24/2017","12/25/2017","01/01/2018"]; var days = 5; date.setDate(date.getDate()); var counter = 0; if(days > 0 ){ while (counter < days) { date.setDate(date.getDate() + 1 ); var check = date.getDay(); var holidayCheck = holiday.indexOf(Utilities.formatDate(date, "EDT", "MM/dd/yyyy")); if (check != 0 && check != 6 && holidayCheck == -1) { counter++; } } } Logger.log("计算出的到期日期:" + date) return date; } function createNewDoc(values) { Logger.log("开始创建文档,表单数据:" + values); // 根据你的表单字段顺序调整索引 var job_name = values[1]; var order_count = values[2]; var print_services = values[3]; var priority = values[5]; var notes = values[6]; var order_form = values[7]; var formattedDate = Utilities.formatDate(new Date(), "EDT", "MM/dd/yyyy"); var expirationDate = Utilities.formatDate(addDates(), "EDT", "MM/dd/yyyy"); // 复制模板文档 try { var copyId = DriveApp.getFileById(docTemplate) .makeCopy(docName+' for '+job_name) .getId(); Logger.log("模板复制成功,新文档ID:" + copyId); } catch (error) { Logger.log("复制模板失败:" + error.message); throw error; } // 替换模板占位符 var copyDoc = DocumentApp.openById(copyId); var copyBody = copyDoc.getActiveSection(); copyBody.replaceText('keyJobName', job_name); copyBody.replaceText('keyOrderCount', order_count); copyBody.replaceText('keyOrderForm', order_form); copyBody.replaceText('keyPrintServices', print_services); copyBody.replaceText('keyPriority', priority); copyBody.replaceText('keyNotes', notes); copyBody.replaceText('keyDate', formattedDate); copyBody.replaceText('keyDue', expirationDate); copyDoc.saveAndClose(); Logger.log("模板占位符替换完成"); // 发送邮件 var pdf = DriveApp.getFileById(copyId).getAs("application/pdf"); var subject = "New Job Submission - " + job_name; var body = "Here is the work order for " + job_name + ". Job is due " + expirationDate + "."; try { MailApp.sendEmail(emailRecipient, subject, body, {htmlBody: body, attachments: pdf}); Logger.log("邮件发送成功"); } catch (error) { Logger.log("邮件发送失败:" + error.message); } // 移动文档到目标文件夹 try { var file = DriveApp.getFileById(copyId); DriveApp.getFolderById(targetFolderId).addFile(file); file.getParents().next().removeFile(file); Logger.log("文档已移动到目标文件夹"); } catch (error) { Logger.log("移动文档失败:" + error.message); } return [copyId, docName + ' for ' + job_name]; } function printGoogleDocument(copyId, docName) { Logger.log("开始打印文档:" + docName); var ticket = { version: "1.0", print: { color: { type: "STANDARD_COLOR" }, duplex: { type: "NO_DUPLEX" }, } }; var payload = { "printerid" : printerId, "content" : copyId, "title" : docName, "contentType" : "google.kix", "ticket" : JSON.stringify(ticket), }; try { var response = UrlFetchApp.fetch('https://www.google.com/cloudprint/submit', { method: "POST", payload: payload, headers: { Authorization: 'Bearer ' + GoogleCloudPrint.getCloudPrintService().getAccessToken() }, "muteHttpExceptions": true }); response = JSON.parse(response); if (response.success) { Logger.log("打印成功:%s", response.message); } else { Logger.log("打印失败:错误代码 %s,信息 %s", response.errorCode, response.message); } return response; } catch (error) { Logger.log("打印请求出错:" + error.message); throw error; } } function onFormSubmit(e) { var rng = e.range; var sheet = rng.getSheet(); var name = sheet.getName(); Logger.log("收到表单提交,工作表:" + name); if(name !== "Job Submission") { Logger.log("非目标工作表,终止执行"); return; } try { var returnedDocValues = createNewDoc(e.values); printGoogleDocument(returnedDocValues[0], returnedDocValues[1]); } catch (error) { Logger.log("执行流程出错:" + error.message); } }
内容的提问来源于stack exchange,提问作者Brandon
相关产品推荐
相关产品推荐

