Применение формулы ко всем ячейкам в столбце, если оно не равно x - PullRequest
0 голосов
/ 06 октября 2018

Я пытаюсь применить формулу к столбцу, но только если ячейка не содержит определенного значения (EMAIL SENT), у меня есть скрипт, который отправляет электронные письма, когда в строке «AF» в строке «отправка электронной почты» изаменяет его на «EMAIL SENT», чтобы избежать повторных отправок, мне нужно пропустить ячейки с «EMAIL SENT» в них.

Вот сценарий, который у меня есть, но он переписывает поверх ячеек и сбрасывает ячейки обратно«отправить письмо».Заранее спасибо.
Сценарий для начинающих.
ps или чтобы эта формула начиналась с первой пустой ячейки в столбце AF.

  var sss4 = SpreadsheetApp.openById('<ID>');
  var ss4 = sss4.getSheetByName('Results');
  ss4.getRange("AF2").setFormula('=IF(((AND(OR(I2="YOUR TRIP DWL",I2="MEGA PACK DWL (YT + AA + BONUS)"),M2<=0,AA2<>"",AE2<>""))), "Send Email", "Wait")');
  var lr4 = ss4. getLastRow();
  var filldownrange4 = ss4.getRange(2, 32, lr4-1);
  ss4. getRange("AF2").copyTo(filldownrange4);

1 Ответ

0 голосов
/ 07 октября 2018

Вместо того, чтобы вставлять формулу по сценарию, я предлагаю поместить формулу непосредственно в электронную таблицу.Это значительно упростит ваш код.

Я взял вашу формулу и добавил несколько элементов:

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)

Вот скриншот моего макета и результатов формулы.so_52680239_screenshot


Логика работает следующим образом:

  1. Проверьте столбец M (ваш столбец AF).Оцените, было ли письмо уже отправлено.Если да, то ничего не делай;если нет, то оцените, пришло ли время отправить электронное письмо.

  2. Если электронное письмо еще не было отправлено, оцените состояние определенных полей.

    • Столбец I (ваш столбец I) - содержит ли он «YOUR TRIP DWL» или «MEGA PACK DWL (YT + AA + BONUS)».Если да, то продолжайте, иначе «Подождите».

    • Убедитесь, что каждый из следующих столбцов оценен как истинный.

      • Столбец J (ваш столбец M) <= 0 (меньше или равен нулю) </li>
      • Столбец K (ваш столбец AA) <> "" (не пустой)
      • Столбец L (ваш столбец AE) <> "" (не пустой)
      • Если все они оценены как true, то «Отправить письмо», в противном случае «Подождите».
  3. Количество строк, в которых отображаются результаты формулы, управляется 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 обновлена.so_52687371_after


Кредит: 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

        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...