Вместо того, чтобы вставлять формулу по сценарию, я предлагаю поместить формулу непосредственно в электронную таблицу.Это значительно упростит ваш код.
Я взял вашу формулу и добавил несколько элементов:
1 - Включен AF столбца в столбец, который обновляется при отправке электронного письма.
2 - Добавлен столбец «Статус»(может быть, колонка AG ??).Это где формула идет.
3 - преобразовал формулу в ARRAYFORMULA
.Обратите внимание, что каждый диапазон в формуле включает целый столбец (например, I2: I).Это также требовало замены AND
на «*» и OR
на «+».Ниже приведено объяснение.
4 - добавлено ARRAY_CONSTRAIN
, поэтому формула добавляется только при добавлении новой строки данных.Если бы этого не было здесь, то формула отображалась бы в каждой строке столбца в нижней части листа - не очень хороший вид и немного отталкивающий.
=ARRAY_CONSTRAIN(ArrayFormula(if(M2:M="EMAIL SENT","EMAIL SENT",IF(((I2:I="YOUR TRIP DWL")+(I2:I="MEGA PACK DWL (YT + AA + BONUS)"))*(J2:J<=0)*(K2:K<>"")*(L2:L<>""), "Send Email", "Wait"))),COUNTA(I2:I),1)
Вот скриншот моего макета и результатов формулы.
Логика работает следующим образом:
Проверьте столбец M (ваш столбец AF).Оцените, было ли письмо уже отправлено.Если да, то ничего не делай;если нет, то оцените, пришло ли время отправить электронное письмо.
Если электронное письмо еще не было отправлено, оцените состояние определенных полей.
Столбец I (ваш столбец I) - содержит ли он «YOUR TRIP DWL» или «MEGA PACK DWL (YT + AA + BONUS)».Если да, то продолжайте, иначе «Подождите».
Убедитесь, что каждый из следующих столбцов оценен как истинный.
- Столбец J (ваш столбец M) <= 0 (меньше или равен нулю) </li>
- Столбец K (ваш столбец AA) <> "" (не пустой)
- Столбец L (ваш столбец AE) <> "" (не пустой)
- Если все они оценены как true, то «Отправить письмо», в противном случае «Подождите».
Количество строк, в которых отображаются результаты формулы, управляется ARRAY_CONSTRAIN
и параметром COUNTA(I2:I)
.Это подсчитывает количество строк с содержимым в столбце I (ваш столбец I).Выбор этого столбца основывался на предположении, что в столбце L всегда будет значение. Если это не так, выберите другую ячейку / столбец, который всегда будет иметь содержимое.Возможно, вам придется изменить COUNTA
на COUNT
, если вы выберете ячейку / столбец с числовыми значениями.
ARRAYFORMULA
Формула вводится только в одну ячейку (эквивалентЯчейка AG2 в столбце «Статус»).ARRAYFORMULA
оценивает формулу по строкам и автоматически отображает результаты в каждой строке столбца.ARRAY_CONSTRAIN
ограничивает результаты;в нашем случае оно ограничено только теми строками, которые имеют значение.
Что случилось с AND
и OR
в операторе IF
?
Обратите внимание, что IF
оператор не включает буквально функции AND
и OR
.По-видимому, они имеют нулевой эффект на ARRAYFORMULA
.НО кредит Макс Махров в "Google Sheets ARRAYFORMULA с вложенными операторами if ", где он советовал.
Replace AND with * and OR with +
Последствия для вашего кода
Ваш код должен перебрать и оценить столбец «Status».
Если значение равно «Send Email», отправьте электронное письмо и обновите столбец «Status» до «EMAIL SENT».В противном случае ничего не делать.
ОБНОВЛЕНИЕ: изменения кода
Это код, который будет соответствовать предложенной формуле.Кодекс самодокументирован и достаточно прост в использовании.Обширный поток обработки выглядит следующим образом.
1 - разрешить для пользовательских переменных
2 - удаленно открыть электронную таблицу
3 - вычислить количество строк данных
4 - пройти черезданные по строке
5 - если значение ячейки = «Отправить электронную почту», отправьте электронное письмо и обновите значение соседнего столбца с помощью «EMAIL SENT»
function so_52680239() {
// Declare user variables
// SpreadsheetID
var ResultsSheetID = "1Iz-qmOnzZp4EAmGzWJORNpJGkueYzGFUTkpUZ9g3-as";
// SheetName
var SheetName = "Results";
// Column letter for the Status Column
var StatusColumnLetter = "N";
// Start row for the Status Column
var StatusHeaderRow = 1;
// open the Results Spreadsheet
// Supply the ID
var ResultsSheet = SpreadsheetApp.openById(ResultsSheetID);
var Results_ss = ResultsSheet.getSheetByName(SheetName);
// Convert the column letter for Status Column to a number
var StatusColumnNumber = letterToColumn(StatusColumnLetter);
//Logger.log("StatusColumnNumber = "+StatusColumnNumber);
// Create a string variable range for the Status Column
var StatusStartRange = StatusColumnLetter+StatusHeaderRow+":"+StatusColumnLetter;
//Logger.log("StatusStartRange = "+StatusStartRange);
// Get the last row with content in the StatusColumn
var LastRowvals = Results_ss.getRange(StatusStartRange).getValues();
var LastDataRow = LastRowvals.filter(String).length;
//Logger.log('Last row = '+LastDataRow);
// declare the search range
var searchRange = Results_ss.getRange(StatusHeaderRow+1,StatusColumnNumber, LastDataRow-1);
//var searchRangeA1 = searchRange.getA1Notation();
//Logger.log('searchRangeA1 = '+searchRangeA1);
// Get array of values in the search Range
var rangeValues = searchRange.getValues();
// Loop through array and if condition met, send email
// Note, only one column of data so no looping by column
for ( j = 0 ; j < LastDataRow - 1; j++){
if(rangeValues[j][0] === 'Send Email'){
// do stuff
// insert code to send email
//Logger.log("j = "+j+", value = "+rangeValues[j][0]+", so Send Email");
// Update your Column AF (one column to the left of the formula results column) with "EMAIL SENT"
Results_ss.getRange(StatusHeaderRow+1+j,StatusColumnNumber).offset(0, -1).setValue('EMAIL SENT');
}else {
// do Nothing
//Logger.log("j = "+j+", value = "+rangeValues[j][0]+", so do nothing");
};
};
}
//Utility to convert a column letter to a column number
function letterToColumn(letter)
{
var column = 0, length = letter.length;
for (var i = 0; i < length; i++)
{
column += (letter.charCodeAt(i) - 64) * Math.pow(26, length - i - 1);
}
return column;
}
Снимок экрана - ПОСЛЕ выполнения кода,Заметка № 2 обновлена.
Кредит: yagisanatode.com для быстрого и эффективного обновления данных: Скрипт Google Apps - итерация по диапазонам в листах правильным и неправильным путем
Решение только с кодом
Если электронную таблицу для формулы нельзя обновить вручную, сценарий может выполнить ту же задачу.
Предположение: столбец I всегда содержит данные;это используется для вычисления количества строк данных, которые нужно обработать.
Условие: если во время выполнения сценария соответствующая ячейка в AF2 пуста, то формула будет вставлена в эту ячейку.Формула затем оценит данные, и в результате может появиться значение «Отправить почту».Тем не менее, нет никаких условий, чтобы затем отправлять почту во время той же процедуры обновления.
Я оставлю это Вопроснику о том, как они решат иметь дело с этим вопросом.
function so_52680239_02() {
// Declare user variables
// SpreadsheetID
var ResultsSheetID = "1ILmQ5cAwRD0Va0lPKcAhr7OTvwLaX_UtFCJ8EEL4TwM";
// SheetName
var SheetName = "Results01";
// Column letter for the Status Column
var StatusColumnLetter = "M";
// Start row for the Status Column
var StatusHeaderRow = 1;
// Column letter for the TripType (assume that there is always data in this cell)
var TripTypeColumnLetter = "I";
// open the Results Spreadsheet
// Supply the ID
var ResultsSheet = SpreadsheetApp.openById(ResultsSheetID);
var Results_ss = ResultsSheet.getSheetByName(SheetName);
// Convert the column letter for Status Column to a number
var StatusColumnNumber = letterToColumn(StatusColumnLetter);
// Logger.log("StatusColumnNumber = "+StatusColumnNumber); //DEBUG
// Convert the column letter for Trip Type Column to a number
var TripTypeColumnNumber = letterToColumn(TripTypeColumnLetter);
// Logger.log("TripTypeColumnNumber = "+TripTypeColumnNumber);// DEBUG
// Create a string variable range for the Status Column
var StatusStartRange = StatusColumnLetter + StatusHeaderRow + ":" + StatusColumnLetter;
// Logger.log("StatusStartRange = "+StatusStartRange); // DEBUG
// Create a string variable range for the Trip Type Column
var TripTypeRange = TripTypeColumnLetter + StatusHeaderRow + ":" + TripTypeColumnLetter;
// Logger.log("TripTypeRange = "+TripTypeRange); // DEBUG
// Get the last row with content in the Trip Type Column
var TripLastRowvals = Results_ss.getRange(TripTypeRange).getValues();
var TripLastDataRow = TripLastRowvals.filter(String).length;
// Logger.log('Last trip row = '+TripLastDataRow);// DEBUG
// Define the formula
var myformula = '=IF(((AND(OR(I' + row + '="YOUR TRIP DWL",I' + row + '="MEGA PACK DWL (YT + AA + BONUS)"),M' + row + '<=0,AA' + row + '<>"",AE' + row + '<>""))), "Send Email", "Wait")';
// declare the search range in Column AF
var searchRange = Results_ss.getRange(StatusHeaderRow + 1, StatusColumnNumber, TripLastDataRow - 1);
// Logger.log('searchRange = '+searchRange.searchRangeA1); //DEBUG
//Get array of values in the search Range
var rangeValues = searchRange.getValues();
//Logger.log("rangevalues = "+rangeValues)
// establish some variablkes for use in the loop
var emailformula = "";
var emailformularange = "";
// loop for email formula
for (var row = 0; row < TripLastDataRow - 1; row++) {
if (rangeValues[row][0] == "") {
// cell is empty, insert formula
emailformula = '=IF(((I' + (row + 2) + '="YOUR TRIP DWL")+(I' + (row + 2) + '="MEGA PACK DWL (YT + AA + BONUS)"))*(J' + (row + 2) + '<=0)*(K' + (row + 2) + '<>"")*(L' + (row + 2) + '<>""), "Send Email", "Wait")';
emailformularange = '' + StatusColumnLetter + (row + 2) + ''
var rangeList = Results_ss.getRangeList([emailformularange]);
rangeList.setFormula(emailformula);
//Logger.log("row = "+row+", value = "+rangeValues[row][0]+", Action: Cell is empty, so insert formula in "+emailformularange);//DEBUG
} else if (rangeValues[row][0] == "EMAIL SENT") {
//do nothing
//Logger.log("row = "+row+", value = "+rangeValues[row][0]+", Action: Email already sent so do nothing"); // DEBUG
} else if (rangeValues[row][0] == "Wait") {
//do nothing
//Logger.log("row = "+row+", value = "+rangeValues[row][0]+", Action: Wait, so do nothing"); //DEBUG
} else if (rangeValues[row][0] == "Send Email") {
// Send mail
emailformularange = '' + StatusColumnLetter + (row + 2) + ''
Results_ss.getRange(emailformularange).setValue('EMAIL SENT');
// Logger.log("row = "+row+", value = "+rangeValues[row][0]+", Action: Send Mail and update cell "+emailformularange+" to 'EMAIL SENT'"); //DEBUG
}
}
}