Отправка стандартных уведомлений с помощью скрипта Google Apps - PullRequest
0 голосов
/ 02 сентября 2018

Я пытаюсь настроить простой скрипт приложений Google для отправки электронных писем, когда ресурсы различных компонентов достигают определенного порогового значения. После прочтения и поиска я собрал скрипт, который, кажется, работает, но начинает отправлять ошибочные электронные письма, когда я увеличиваю диапазон, извлекаемый из моей таблицы.

Вот мой код и более подробная информация ниже.

var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Inventory Report");
var howFar = 5 //sheet.getMaxRows(); // how many rows of data
var onHand = sheet.getRange(2,14,howFar,1).getValues();
var minimum = sheet.getRange(2,16,howFar,1).getValues();
var itemNum = sheet.getRange(2,1,howFar,1).getValues();
var itemName = sheet.getRange(2,2,howFar,1).getValues();

var sendTo = "test@gmail.com";
var overStock = 1.5;  // warning factor over minimum

function stockAlert() {
  for (var i = 0; i < onHand.length; i++) { 
    if (onHand[i] < minimum[i] * overStock && onHand[i] > minimum[i]) {
        MailApp.sendEmail( sendTo , "Testing Stock Reorder Notifications", itemNum[i] + " " + itemName[i] +" - Stock is low! Current stock is " + onHand[i] + ". Minimum is " + minimum[i] + ".");
    }
    else if (minimum[i] > 0 && onHand[i] < minimum[i]) {
        MailApp.sendEmail( sendTo , "Testing Stock Cirtical Notifications", itemNum[i] + " " + itemName[i] +" - Stock is Critical and will be depleted! Current stock is " + onHand[i] + ". Minimum is " + minimum[i] + ".");
    } 
  }
}

В моем листе минимальные значения: 200, 400, 200, 300, 600
. В моем листе значения для onHand 270, 270, 920, 920, 1830

Это означает, что я должен видеть одно электронное письмо с низким запасом для первого набора значений, одно критическое электронное письмо с запасом для второго набора значений и никаких электронных писем для последних 3 наборов значений.

Если var howfar = 3, скрипт отправляет два соответствующих электронных письма. Если var howfar = 5, я получу третье письмо с критическим запасом для пятого набора значений, которое не следует отправлять. Интересно, что тело письма показывает, что оно ссылается на правильный набор значений, но else if должно быть ложным.

Тело неправильного письма гласит:

itemNum itemName - Запас критически важен и будет исчерпан! Текущий запас 1830. Минимум 600.

Учитывая мой обширный опыт не кодирования, я надеюсь и предполагаю, что это будет простое исправление, но любая помощь очень ценится!

1 Ответ

0 голосов
/ 02 сентября 2018

Есть ли вероятность того, что значения будут рассматриваться как текст в электронной таблице? Обратите внимание, что строка "1830" действительно < строка "600". Если они представляют собой текст в электронной таблице (а не числа), то, когда скрипт Apps считывает значения, они будут сохранены как String s.

edit: действительно, это источник вашей проблемы - вы сравниваете 2D массивы на уровне Array:

Logger.log(minimum[i]); // "[600.0]"
Logger.log(typeof minimum[i]); // object

Logger.log(minimum[i][0]); // 600.0
Logger.log(typeof minimum[i][0]); // number

Самое простое решение - просто получить доступ к нужному элементу двумерного массива. Поскольку вы получили только один столбец, в каждом внутреннем массиве есть только 1 элемент (с индексом 0). Таким образом, <array>[i][0] вместо <array>[i].

Расширение этого, которое будет работать в ситуациях, когда значения листа могут быть текстовыми, заключается в явном приведении к числу перед сравнением с использованием функции JS parseInt(val, radix). Предполагая, что minimum и другие являются двумерными массивами в том виде, в каком они указаны в коде вашего вопроса:

for (var i = 0; i < onHand.length; i++) {
  var min = parseInt(minimum[i][0], 10),
      avail = parseInt(onHand[i][0], 10);
  if (avail < min) {
    // send critical stock email
  }
  else if (avail < min * overStock) {
    // send reorder email
  }
  else {
    // on hand amount is > needed
  }
}

Для пустой строки, например parseInt("", 10), или другие нечисловые входные данные, возвращаемым значением является число NaN, которое не является ни >, ни <, чем действительные числа, поэтому неправильные входные данные не должны приводить к отправке электронного письма.


Другая проблема заключается в том, что ваш скрипт заполняет глобальные переменные вызовами интерфейса, что приводит к более медленному выполнению любого скрипта. Лучше всего обернуть соответствующую настройку в функцию:

function getStockAmounts() {
  // Return an object of the inventory values.
  const stock = SpreadsheetApp.getActive().getSheetByName("some name");
  const numHeaders = 1,
        numVals = stock.getLastRow() - numHeaders;
  return [
    {p: 'minimum', col: 16},
    {p: 'onHand', col: 14},
    {p: 'itemName', col: 2},
    {p: 'itemNum', col: 1}
  ].reduce(function (obj, key) {
    obj[key.p] = stock.getRange(numHeaders + 1, key.col, numVals, 1)
      .getValues()
      // Return a 1-D array, rather than a 2-D array, since all these are single-column variables.
      .map(function (row) { return row[0]; });
    return obj;
  }, {'numVals': numVals});
}

и затем вызовите это из вашего скрипта:

function foo() {
  const stocks = getStockAmounts();
  for (var i = 0; i < stocks.numVals; i++) {
    var min = stocks.minimum[i]; // 1D arrays, so only 1 index is needed.
    ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...