Есть ли вероятность того, что значения будут рассматриваться как текст в электронной таблице? Обратите внимание, что строка "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.
...