You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

投标管理Google Sheet自动邮件优化:解决逐单元格重复触发问题

投标记录表邮件通知代码优化方案

核心优化目标

仅在新增整行投标记录、到期日列修改、状态列修改这三种场景下触发邮件,彻底解决单单元格编辑重复发信的问题。

修改后的完整代码

//@OnlyCurrentDoc
function processEdit(e) {
  const sheet = e.source.getActiveSheet();
  const range = e.range;
  const editedRow = range.getRow();
  const editedCol = range.getColumn();
  
  // 获取tendersopen命名范围的边界
  const tenderRange = sheet.getRangeByName("tendersopen");
  if (!tenderRange) return;
  const startRow = tenderRange.getRow();
  const endRow = tenderRange.getLastRow();
  const startCol = tenderRange.getColumn();
  const endCol = tenderRange.getLastColumn();
  
  // 只处理tendersopen范围内的编辑操作
  if (editedRow < startRow || editedRow > endRow || editedCol < startCol || editedCol > endCol) return;
  
  // 从表头找到到期日、状态列的位置
  const headerRow = tenderRange.getValues()[0];
  const dueDateColIndex = headerRow.indexOf("到期日"); // 替换成你表格里的实际表头文字
  const statusColIndex = headerRow.indexOf("状态"); // 替换成你表格里的实际表头文字
  if (dueDateColIndex === -1 || statusColIndex === -1) return;
  
  // 转换为实际列号(表格列从1开始)
  const dueDateCol = startCol + dueDateColIndex;
  const statusCol = startCol + statusColIndex;
  
  // 判断是否是新增整行:编辑行是tendersopen最后一行,且该行首列有内容(确保是完整新增)
  const isNewRow = editedRow === endRow && sheet.getRange(editedRow, startCol).getValue() !== "";
  
  // 判断是否编辑了到期日或状态列
  const isTargetCol = editedCol === dueDateCol || editedCol === statusCol;
  
  // 符合任一条件才发送邮件
  if (isNewRow || isTargetCol) {
    // 获取当前编辑行的完整数据
    const rowData = sheet.getRange(editedRow, startCol, 1, endCol - startCol + 1).getValues()[0];
    
    // 渲染邮件模板
    const template = HtmlService.createTemplateFromFile("Template");
    template.headerRow = headerRow;
    template.editedRowData = rowData;
    template.editedRowNum = editedRow;
    
    const html = template.evaluate().getContent();
    
    MailApp.sendEmail({
      to: "email@gmail.com",
      subject: "投标记录表已更新",
      htmlBody: html
    });
  }
}

关键修改点说明

  1. 范围过滤:先检查编辑单元格是否在tendersopen范围内,不在直接终止,避免无关操作触发
  2. 动态列定位:通过表头文字匹配到期日、状态列,不用硬编码列号,表格结构调整后不用改代码
  3. 精准场景判断:
    • 新增行:仅当编辑的是tendersopen的最后一行,且首列有内容时才判定为新增(避免中途编辑空行触发)
    • 目标列编辑:只在修改到期日或状态列时触发邮件
  4. 数据精简:给模板传递当前编辑行的完整数据,而非整个范围的所有行,减少冗余

注意事项

  • 务必把代码里的"到期日"、"状态"替换成你表格中实际的表头文字,否则列匹配会失败
  • 如果新增行的判断逻辑需要调整(比如首列不是必填项),修改sheet.getRange(editedRow, startCol)中的startCol为对应必填列的列号即可
  • 修改后重新部署On Edit触发器,确保新代码生效

内容的提问来源于stack exchange,提问作者Michelle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 22:53:07