【问题标题】:Send email when cell is edited using email in parallel cell使用并行单元格中的电子邮件编辑单元格时发送电子邮件
【发布时间】:2023-03-31 05:15:01
【问题描述】:

我已经阅读了很多 onEdit 和 Triggers 脚本,但仍然无法实现我想要实现的目标,我在 excel VBA 中编写了很多代码,而 google sheet 则非常不同。所以事情是基于我的截图,我想要的是一旦单元格包含“已批准”、“拒绝”、“进行中”并且电子邮件地址必须基于编辑单元格的平行度。我渴望完成这项工作。

代码基于互联网,但我无法根据我的数据/表格对其进行调整。

【问题讨论】:

  • 我很擅长 GAS。你能分享你从执行记录中得到的错误吗?
  • 嗨@AleisterTanekJavasMraz 问题是我不知道如何调整代码,所以代码不会运行。我不知道如何以及从哪里开始。如何定义用于编辑的列并获取电子邮件地址的平行单元格
  • 您将需要了解 GAS 中的一些基本功能。您应该使用 onEdit() 简单触发器,以便在电子表格中编辑单元格时运行函数 sendMailOnEditOfColH(e)。触发时,事件对象“e”会携带一些有关电子表格更改的基本信息到脚本中。您还需要查看 .getRange() 函数的参数,以将当前脚本与电子表格的布局同步。当前第 5-6 行从 (.rowStart, 3, 1, 7) 定义的 Range 中获取 Values,即 (Row, Col, NumRows, NumCols)。
  • 我已经阅读了它,并且我还阅读了 onEdit 不运行 MailApp 功能。与 VBA excel 相比,情况大不相同。我只想编辑单元格并通过电子邮件发送包含电子邮件地址的并行单元格。我可以在 excel 中对其进行编码,然后有人可以将其转换为谷歌脚本吗?
  • 我有一个想法,在我的工作表上有一个按钮,按下它会显示一个输入框来输入主键,如票号,它将查找电子邮件并插入“已批准”,然后发送电子邮件。这可能吗?如果是,我会将其编码为 excel vba 并请人转换。

标签: google-apps-script google-sheets


【解决方案1】:

您可以使用以下脚本将自定义函数添加到电子表格 UI 中的下拉菜单。这将允许您绕过不允许使用 MailApp 类的 onEdit() 限制,但代价是让用户手动调用脚本而不是脚本自动运行。

这里用户将从下拉菜单中选择“发送电子邮件”,它将通过输入提示模式提示他/她输入主键。对应key所在的行会被识别,状态自动变为“approved”后会发送一封邮件。此脚本假定电子表格至少包含四列标题行“主键”、“描述”、“电子邮件”和“状态”,顺序不限。

请注意:此代码已成功测试。请通过替换方括号和其中包含定义 sheetURL 和 workSheetName 变量的文本来更新第 20 和 21 行。

function onOpen() {
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Custom Menu')
  .addItem('Send E-Mail', 'sendEmail')
  .addToUi();
}

function sendEmail(){

  // Display a dialog box with a title, message, input field, and "OK" and "Cancel" buttons. The
  // user can also close the dialog by clicking the close button in its title bar.
  var ui = SpreadsheetApp.getUi();
  var response = ui.prompt('Pop-Up Prompt', 'Please enter primary key:', ui.ButtonSet.OK_CANCEL);

  // Process the user's response.
  if (response.getSelectedButton() == ui.Button.OK) {
    Logger.log('The user entered the following primary key:', response.getResponseText());

    // Map the header rows in order that column position is not hard-coded.
    var sheetURL = '[ENTER YOUR SHEET URL HERE]';
    var workSheetName = '[ENTER YOUR WORKSHEET NAME HERE]';
    var sheet = SpreadsheetApp.openByUrl(sheetURL).getSheetByName(workSheetName);
    var lastColumn = sheet.getLastColumn();
    var headerRange = sheet.getRange(1, 1, 1, lastColumn);
    var headers = headerRange.getValues();

    for (var i=1; i<headers[0].length+1; i++) {
      switch (headers[0][i-1]){
        case "Primary Key":
          var primaryKeyIndex = i;
          break;
        case "Description":
          var descriptionIndex = i;
          break;
        case "Email":
          var emailIndex = i;
          break;
        case "Status":
          var statusIndex = i;
          break;
      }
    }
    // Header rows mapped.

    // Search for row corresponding to primary key.
    var primaryKey = response.getResponseText();
    var keyRow = findInColumn(columnToLetter(primaryKeyIndex), primaryKey);
    if (keyRow == -1){
      ui.alert('Primary Key "'+ primaryKey + '" not found.');
    } else {
      ui.alert('Primary Key "'+ primaryKey + '" found at row: ' +keyRow+ '.');
      sheet.getRange(keyRow, statusIndex).setValue("Approved");

      //Prepare Email
      var subject = "test";
      var email = sheet.getRange(keyRow, emailIndex).getValue();
      var body = "Hi, \n\n Your entry with primary key " + primaryKey + " is now approved.";
      MailApp.sendEmail(email, subject, body);

    }

  } else if (response.getSelectedButton() == ui.Button.CANCEL) {
    Logger.log('The user clicked cancel.');
  } else {
    Logger.log('The user clicked the close button in the dialog\'s title bar.');
  }
}

// Helper function to find corresponding row to data in column.
function findInColumn(column, data) {

  var sheet  = SpreadsheetApp.getActiveSpreadsheet();
  var column = sheet.getRange(column + ":" + column);  // like A:A

  var values = column.getValues(); 
  var row = 0;

  while ( String(values[row]) && String(values[row][0]) !== String(data) ) {
    row++;
  }

  if (String(values[row][0]) === String(data))
    return row+1;
  else 
    return -1;

}


// Helper function to convert Column Number to Column Letter
function columnToLetter(column){
  var temp, letter = '';
  while (column > 0)
  {
    temp = (column - 1) % 26;
    letter = String.fromCharCode(temp + 65) + letter;
    column = (column - temp - 1) / 26;
  }
  return letter;
}

【讨论】:

  • 我不敢相信这是可能的。非常感谢你的帮助。如果您不介意还有一个问题,如果我添加另一个也将合并到电子邮件主题的列怎么办。
  • 您好,请帮我调整您的代码以适合我的模板。添加未找到范围错误的列
【解决方案2】:

我建议您不要使用 onEdit 触发器来发送电子邮件。我认为它已被许多用户过度使用。如果是,则必须使用installable triggers。这是一个example email solution,昨天进来的看起来很干净。

【讨论】:

    【解决方案3】:

    您可以使用下面的大部分代码。修改电子邮件部分以满足您的需要。 此代码检查工作表名称是否为“表单响应”,并将列标题编辑为“状态”,如上图所示。

    function onEdit() {
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var aSheet = ss.getActiveSheet();
      // check sheet name
      if (aSheet.getName() != 'Form Responses') return;
    
      var range = ss.getActiveRange();
      var row = range.getRow();
      var col = range.getColumn();
    //  Logger.log(col);
    
      var headers = aSheet.getRange(1,1,1,aSheet.getLastColumn()).getValues()[0];
    //  Logger.log(headers[col-1]);
    
      // check column header
      if (headers[col-1] != 'Status') return;
    
      var value = range.getValue();
      var values = ["approved", "denied", "in progress"]; // values to check for
    
      // check values
      if (values.indexOf(value.toString().toLowerCase()) == -1) return;
    
    //  Logger.log(row);
      var rowValues = aSheet.getRange(row, 1, 1, aSheet.getLastColumn()).getValues()[0];
      Logger.log(rowValues);
    
      // change as necessary
      var recipient = rowValues[1]; // email is in 2nd column
      var body = 'Email body'; // create body
      var subject = 'Test'; // set subject
    
      // send email
      MailApp.sendEmail(recipient, subject, body);
    }
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多