Проблема с onEdit после отправки электронной почты в Google sheets

#function #google-apps-script #google-sheets

#функция #google-apps-script #google-sheets

Вопрос:

вот мой код в Google script:

 function Send(){
Browser.msgBox("Send");
   }

function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var startRow = 2;
  var lr = sheet.getLastRow();

  var dataRange = sheet.getRange(startRow, 1, lr-1, 6);

  var data = dataRange.getValues();

  for (var i = 0; i < data.length; i  ) {
    var row = data[i];
    var name = row[0];
    var emailAddress = row[1];
    var date = row[2];
    var city = row[3];
     var status = row[6];
    
    if (emailAddress.match('@')  === null){
   continue;
    };

    var subject = row[4];
    var message = "Hey "   name   ", welcome in the team "   row[5];

    MailApp.sendEmail(emailAddress, subject, message);

    sheet.getRange(i 2,7).setValue("Sent");
      }
}
 

Пока здесь все работает нормально. Я бы хотел, чтобы тогда, когда «Отправлено» появляется в 7-м столбце, вся строка, в которой находится «Отправлено», перемещалась на другую вкладку.

 function onEdit(e) {
  var ss = e.source;
  var s = ss.getActiveSheet();
  var r = e.range;
  var actionCol = 7;
  var nameCol = 7;
  var rowIndex = r.getRowIndex();
  var colIndex = r.getColumnIndex();
  var colNumber = s.getLastColumn()-1;
  if (e.value == "Sent" amp;amp; colIndex == actionCol) {
       var targetSheet = s.getRange(rowIndex, nameCol).getValue();
       if (ss.getSheetByName("Welcome")) { 
           var targetSheet = ss.getSheetByName("Done");
      var targetRange = targetSheet.getRange(targetSheet.getLastRow() 1, 1, 1, colNumber);
       var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
        sourceRange.copyTo(targetRange);
            s.deleteRow(rowIndex);
          }
  }
}
 

** Если я вручную напишу «Отправлено» в 7-м столбце, строка переместится на другой лист. Но когда я запускаю первую функцию и в этом столбце появляется «Отправлено», функция onEdit не работает.
Таким образом, в основном обе функции работают, но не одновременно.

Кто-нибудь знает, как это исправить?**

Ответ №1:

Проблемы:

  • Вы пытаетесь запустить onEdit функцию с помощью скрипта, но триггеры работают не так. В официальной документации указано следующее:

onEdit(e) Триггер запускается автоматически, когда пользователь изменяет значение любой ячейки в электронной таблице.

А именно, onEdit триггеры активируются только действиями пользователя, а не скриптами или формулами.

  • Вам не нужна отдельная функция, чтобы проверить, соответствует ли значение Sent , а затем удалить строку с помощью другой функции. После отправки электронной почты вы можете переместить данные и удалить строку, и все это в рамках одной функции.
  • И последнее, но не менее важное: при итеративном удалении строк мы меняем структуру листа, и поэтому вводимые данные не соответствуют обновленной структуре. Чтобы устранить эту проблему, мы можем сохранить индексы строк, которые мы хотим удалить, в массиве, а затем, используя этот массив, удалить строки в обратном направлении.

Решение:

Предполагая, что ваши коды работают отдельно, это также должно работать:

 function myFunction() {
  var ss = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName("Welcome");
  var targetSheet = ss.getSheetByName("Done");
  var startRow = 2;
  var lr = sheet.getLastRow();
  var dataRange = sheet.getRange(startRow, 1, lr-1, 6);
  var data = dataRange.getValues(); 
  var colNumber = sheet.getLastColumn()-1;
  var delRows = [];
  for (var i = 0; i < data.length; i  ) {
      var row = data[i];
      var name = row[0];
      var emailAddress = row[1];
      var date = row[2];
      var city = row[3];
      var status = row[6];
      if (emailAddress.match('@')  === null){
         continue;
      };
      var subject = row[4];
      var message = "Hey "   name   ", welcome in the team "   row[5];
      MailApp.sendEmail(emailAddress, subject, message);
      var targetRange = targetSheet.getRange(targetSheet.getLastRow() 1, 1, 1, colNumber);
      var sourceRange = sheet.getRange(i startRow, 1, 1, colNumber);
      sourceRange.copyTo(targetRange);
      delRows.push(i startRow); 
      }   
  // delete rows in reverse order    
  delRows.reverse().forEach(ri=>{sheet.deleteRow(ri)});  
}
 

вам больше не нужна onEdit функция, поэтому вы можете удалить ее.

Комментарии:

1. При запуске скрипта появляется сообщение об ошибке: TypeError: не удается прочитать свойство ‘getLastRow’ null myFunction @ Code.gs:6

2. Кроме того, я хотел бы удалить строку, для которой было отправлено электронное письмо, но также сохранить ее на другой вкладке с именем «Готово»

3. @Fabien убедитесь, что у вас есть лист с именем Welcome и лист с именем Done . Это решит оба ваших вопроса. Убедитесь, что имена листов точно соответствуют этим двум словам. Никаких дополнительных пробелов или разных прописных / строчных букв.

4. В названии вкладки действительно была ошибка. Еще раз спасибо за вашу помощь 🙂