0

Я относительно новичок в программировании и недавно работал над скриптом для отправки электронных писем из электронной таблицы google при изменении ячейки в определенном столбце. Получатель назначается исходя из адреса электронной почты в другом столбце в той же строке, что и изменение. У меня с трудом получается, что мой код перестанет работать после первого письма. Как бы то ни было, сценарий работает бесконечно (по крайней мере, до тех пор, пока у меня не будет писем за день).Google Script Email loop

Вот код:

function sendNotification() { 

     var sheet = SpreadsheetApp.getActiveSheet(); 
    //Get Active cell 
    var mycell = sheet.getActiveSelection(); 
    var cellcol = mycell.getColumn(); 
    var cellrow = mycell.getRow(); 
    var address = sheet.getRange("C" + cellrow).getValue(); 
    var streetAddress = sheet.getRange("F" + cellrow).getValue(); 
    var startRow = 2; 
    var numRows = 2000; 
    // Fetch the range of cells A2:O2000 
    var dataRange = sheet.getRange(startRow, 1, numRows, 15) 
    // Fetch values for each row in the Range. 
    var data = dataRange.getValues(); 
    for (i in data) { 
    var row = data[i]; 
    var emailAddress = address; // First column 
    var message = streetAddress +" Has been Submitted for permitting!";    // Second column 
    var subject = "The above Address has been Submitted For Permitting! We  will Follow up with you when it has been approved."; 
    //Check to see if column is H to trigger 
     if (cellcol == 8 && sheet.getName() == "Sheet1" && mycell !== "") 
     { 
    //Send the Email 
     MailApp.sendEmail(emailAddress, message, subject); 
     } 
    //End sendNotification 
    } 
    } 

Что я могу сделать, чтобы решить эту проблему? Будет ли цикл наилучшим вариантом? Как бы это реализовать?

Как насчет этого подхода?

var EMAIL_SENT = "EMAIL_SENT";

function onEdit(e) { 
    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = ss.getActiveSheet(); 
    var mycell = e.range; 
    var cellcol = mycell.getColumn(); 
    var cellrow = mycell.getRow(); 
    var emailAddress = sheet.getRange("C" + cellrow).getValue(); 
    var streetAddress = sheet.getRange("F" + cellrow).getValue(); 
    var subject = "The above Address has been Submitted For Permitting! We  will follow up with you when it has been approved." 
    // Fetch values for each row in the Range 
    var message = streetAddress +" Has been Submitted for permitting!"; 
    var emailSent = sheet.getRange("O" + cellrow).getValue();  
    if (cellcol == 8 && sheet.getName() == "Sheet1" && emailSent !=  EMAIL_SENT) { // Prevents sending duplicates 
     MailApp.sendEmail(emailAddress, subject, message); 
     sheet.getRange(cellrow, 15).setValue(EMAIL_SENT); 
     // Make sure the cell is updated right away in case the script is  interrupted 
     SpreadsheetApp.flush(); 
    } 
    } 
+0

Ваша петля работает 2000 раз, так как вы извлекаете 2000 строк. Регулятор IF на строке ** ** должен проверить, что значение для текущей строки и столбца 8 (H) не пустое. 'Row [8]! =" "'. Вместо этого вы проверяете 'mycell! =" "', Который ссылается на ячейку вне цикла. Также 'cellcol == 8' не представляется необходимым. – Fredster

+0

Дело в том, что я хочу отправить сообщение только в том случае, если отредактированная ячейка находится в столбце 8. Я думаю, что я все это делал неправильно. Это выглядит лучше? – AFliss

ответ

0

При использовании onEdit() функция будет срабатывать каждый раз при редактировании ячейки. Это то, что вы хотите? То, что я предполагаю, что вы ищете скрипт, который:

  1. читает каждую строку активного листа
  2. Если восьмой столбец не пустой, посылает по электронной почте на адрес в первой колонке
  3. весь сценарий запуска по запросам пользователей (не тогда, когда пользователь редактирует ячейку)

В этом случае первый подход лучше, sendNotification(). Также необходим цикл для чтения всех строк. И оператор IF должен быть чем-то вроде if (row[8] != ""), а затем отправить электронное письмо.

В этом случае row, который был определен как row = data[i] в вашем первом скрипте, будет иметь значения всех ячеек в строке, считываемой в цикле. Таким образом, row[8] будет иметь значение 8-го (столбец H), который вы хотите проверить на пустоту, таким образом, if(row[8] != "").

Кроме того, если я правильно понял, адрес электронной почты должен быть emailAddress = row[1] внутри цикла, потому что адрес электронной почты отличается от каждой строки.

0

Ваш второй подход var EMAIL_SENT = "EMAIL_SENT"; почти похож на простое расширение кода, который устанавливает ячейки в столбце «EMAIL_SENT» для каждой строки после sendEmail называется приведено в Section 2: Improvements. Внутри учебника каждая ячейка помечена в каждой строке каждый раз, когда отправляется электронное письмо. При этом вы должны пометить отредактированные ячейки как unsent, после чего вы сможете повторно запустить сценарий позже, избегать отправки дубликатов электронной почты и отправлять только отредактированные ячейки.

Чтобы сделать ваш код более эффективным и помочь улучшить производительность ваших скриптов, есть также список best practices.