Sending an email automatically when the edited cell value says “Done” and the email subject is the first cell in the edited row

萝らか妹 提交于 2020-01-23 04:13:10

问题


I'm trying to write a script where an automatic email is sent to a specific person upon edit of a cell and the cell equals "Done". However, I want the subject to be the first cell of the edited row. Cell that will contain "Done" is always going to be in the AA Column, and I want the subject to be the A column of the same row. Ex: AA3 was edited so subject is A3. I have spent hours sifting through tutorials and came up with this:

function checkValue() {
  var sp = PropertiesService.getScriptProperties();
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Accts");
  var valueToCheck = sheet.getRange("AA2:AA1000").getValue();
  if (valueToCheck = 'Done') {
    MailApp.sendEmail("a***a@gmail.com", activeCell.offset(-26,0).getValue(), Email.html);
  }
}

Am I doing this entirely wrong or is there hope?

EDIT: Now that it's resolved. I thought I'd share what my script ended up looking like. I added a UI and an option to execute using a menu option. Hope this helps someone else.

function onEdit(e) 
{
  var editRange = { // AA2:AA1000
    top : 2,
    bottom : 1000,
    left : 27,
    right : 27
  };

  // Exit if we're out of range
  var thisRow = e.range.getRow();
  if (thisRow < editRange.top || thisRow > editRange.bottom) return;

  var thisCol = e.range.getColumn();
  if (thisCol < editRange.left || thisCol > editRange.right) return;

  var thisthang = e.value;
  var doit = 'TRUE'

  // We're in range; timestamp the edit
  if(thisthang == doit)
  {
    doFinish();
  }
  else{return};
} 

function onOpen()
{
  var ui = SpreadsheetApp.getUi();
  ui.createMenu('Finished')
      .addItem('Finish', 'doFinish')
      .addToUi();
}

function doFinish()
{
   var cell = SpreadsheetApp.getActiveSheet().getActiveCell();
   var row = cell.getRow();

   var Campaign = getCampaignFromRow(row, 1); 

   var ui = SpreadsheetApp.getUi();
   var response = ui.alert('Finish '+Campaign.name+'?', ui.ButtonSet.YES_NO);

   if(response == ui.Button.YES)
   {
     handleFinish(row, Campaign);
   }
   if(response == ui.Button.NO)
   {
     SpreadsheetApp.getActiveSheet().getRange(row, 27).setValue('FALSE');
   }
}

function getCampaignFromRow(row)
{
  var values = SpreadsheetApp.getActiveSheet().getRange(row, 1).getValues();
  var rec = values[0];

  var Campaign = 
      {
        Campaign_Name: rec[0]
      };

   Campaign.name = Campaign.Campaign_Name;

   return Campaign;
}

function handleFinish(row, Campaign)
{
  var templ = HtmlService
      .createTemplateFromFile('Campaign-email');

  templ.Campaign = Campaign;

  var message = templ.evaluate().getContent();

  MailApp.sendEmail({
    to: "a***a@gmail.com",
    subject: "A Campaign has been finished!",
    htmlBody: message
  });

  SpreadsheetApp.getActiveSheet().getRange(row, 27).setValue('TRUE');

}

回答1:


You are trying to trigger an email when the spreadsheet is edited on the "Accts" sheet, in Column "AA" and the value = "Done".

The best solution is to use an onEdit trigger and also make use of Event Objects. In the case, "a simple trigger cannot send an email" ref, so you will need to create an Installable Trigger.

The main differences to your script are:
- var valueToCheck = sheet.getRange("AA2:AA1000").getValue();
- a couple of things here.
- 1) you are trying to get all the values in the column, but you use the getValue (the method for a single cell) instead of getValues.
- 2) you could have defined the ActiveCell and just returned that value
- 3) though you tried to get the values for the entire column, your if statement is designed as though there is a single value rather than an array of values.
- 4) This demonstrates the benefit of the using the Event Objects. You can succinctly get the values of the edited cell and sheet.
- in your if comparison, you use "="; this is only used to assign a value. When comparing values you must use "==" or "===".
- To get the value of the "subject", the script uses the row number derived from the Event Objects; compared to the offset in your script - they are both acceptable. I used the getRange to demonstrate the alternative.
- your email body was defined as "Email.html", but this isn't declared. The answer uses a very simple body but could just as easily use another solution.


function so5967209001(e) {

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getActiveSheet()

  // establish the values to be checked
  var checkSheetname = "Accts"
  var checkValue = "Done"
  var checkColumn = 27; // column AA

  // this will return the event objects
  //Logger.log(JSON.stringify(e)); // DEBUG

  // variables to use for checking
  var editedrange = e.range;
  var editedrow = editedrange.getRow();
  var editedcolumn = editedrange.getColumn();
  var editedsheet = editedrange.getSheet().getSheetName();
  var editedvalue = e.value;
  //Logger.log("DEBUG: row = "+editedrow+", column = "+editedcolumn+", sheet = "+editedsheet+", value"+editedvalue)

  // test the sheet, the column and the value
  if (editedsheet ==checkSheetname && editedcolumn==checkColumn && editedvalue == checkValue){

    //Logger.log("DEBUG: this is a match");

    var subject = sheet.getRange(editedrow,1).getValue(); // Column A of the edited row
    //Logger.log("DEBUG: email subject = "+subject);

    // build your own body
    var body = "this is the body of the email"

    // send the email
    MailApp.sendEmail("ejb@tedbell.com.au", subject, body);
    //Logger.log("DEBUG: mail sent")

  }else{
    //Logger.log("DEBUG: this isn't a match");

  }
}


来源:https://stackoverflow.com/questions/59672090/sending-an-email-automatically-when-the-edited-cell-value-says-done-and-the-em

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!