#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. В названии вкладки действительно была ошибка. Еще раз спасибо за вашу помощь 🙂