Перейти к основному содержимому

Основы JavaScript для скриптов

Скрипты Coverse пишутся на JavaScript. Чтобы написать скрипт, знать язык не обязательно: его может написать ИИ в редакторе. Но если понимать несколько основ, скрипт легко прочитать, поправить название столбца или условие и найти ошибку. Здесь собран этот минимум на примерах из таблиц.

Функция​

Скрипт состоит из функций. Функция — именованный кусок кода, который выполняется целиком при запуске.

function main() {
console.log("Привет");
}
  • main — имя функции. Кнопка «Запустить» по умолчанию запускает main, другую функцию можно выбрать в меню рядом с кнопкой.
  • Код функции пишется между { и }.
  • console.log выводит текст в журнал запуска. Это главный способ посмотреть, что происходит в скрипте.

Функция для триггера получает событие в скобках: function onEdit(event) { … }. Что в нём лежит, описано в статье Триггеры.

Переменные​

Переменная — имя для значения, чтобы использовать его дальше.

const sheet = Coverse.table.getSheet("Заказы");
let total = 0;
total = total + 150;
  • const — значение не меняется. Используйте по умолчанию.
  • let — значение будет меняться, например счётчик или сумма.
  • Регистр важен: total и Total — разные переменные.

Значения​

ТипПримерЧто это
Текст"Оплачен"строка в кавычках
Число1250.5дробная часть через точку, без пробелов
Логическоеtrue, falseда или нет; так читается флажок в ячейке
Пустоnullзначения нет, например getSheetByName не нашёл лист
Датаnew Date()текущий момент

Число и текст — разные вещи: 1250 и "1250" не равны. Подробнее в разделе Частые ошибки.

Строки таблицы — это массивы​

getValues() возвращает таблицу как массив строк, а каждая строка — массив ячеек.

const rows = Coverse.table.getSheet("Заказы").getDataRange().getValues();

Если на листе так:

ABCD
1НомерКлиентСуммаСтатус
2101Иванов1500Оплачен
3102Петрова800Новый

то rows выглядит так:

[
["Номер", "Клиент", "Сумма", "Статус"],
[101, "Иванов", 1500, "Оплачен"],
[102, "Петрова", 800, "Новый"],
]

Важно: в массиве счёт идёт с нуля, а в таблице строки и столбцы считаются с единицы.

В кодеЧто этоВ таблице
rows[0]первая строка, заголовкистрока 1
rows[1]вторая строкастрока 2
rows[1][2]вторая строка, третья ячейкаC2, значение 1500
rows.lengthсколько строк3

Поэтому номер строки в таблице — это индекс в массиве плюс один: строка rows[i] лежит в строке i + 1 листа.

Найти столбец по заголовку​

Чтобы скрипт не ломался, когда столбцы переставят, ищите столбец по названию:

const head = rows[0];
const sumCol = head.indexOf("Сумма");
if (sumCol === -1) throw new Error("Нет столбца «Сумма»");

indexOf возвращает номер элемента в массиве или -1, если его нет.

Цикл: пройти по всем строкам​

for (let i = 1; i < rows.length; i++) {
console.log(rows[i][sumCol]);
}
  • let i = 1 — начинаем со второй строки, потому что первая — заголовки.
  • i < rows.length — идём, пока строки не кончились.
  • i++ — после каждого шага прибавляем единицу.

Ещё два удобных способа:

for (const row of rows.slice(1)) {
console.log(row[0]);
}

const ids = rows.slice(1).map((row) => row[0]);
const paid = rows.slice(1).filter((row) => row[3] === "Оплачен");
  • slice(1) — все строки, кроме первой.
  • map — сделать из каждой строки новое значение, здесь список номеров.
  • filter — оставить только подходящие строки.

Условие​

if (row[3] === "Оплачен") {
paidTotal = paidTotal + row[2];
} else if (row[3] === "Отменён") {
cancelled++;
} else {
waiting++;
}
ЗаписьЗначит
===равно
!==не равно
>, <, >=, <=больше, меньше
&&и
||или
!не

Пишите ===, а не =: один знак = записывает значение в переменную, а не сравнивает.

Объекты​

Объект хранит значения по названиям. В скриптах он встречается в параметрах команд и в ответах сервисов.

const order = { id: 101, client: "Иванов", total: 1500 };
console.log(order.client);

Http.fetch("https://example.com/api", { method: "POST", body: order });

Ответ внешнего сервиса обычно тоже объект: response.json().items.

Текст​

const name = "Иванов";
const line = "Клиент: " + name + ", сумма " + 1500;
const sameLine = `Клиент: ${name}, сумма ${1500}`;

name.trim();
name.toLowerCase();
name.includes("ван");
"101;102;103".split(";");
  • + склеивает текст.
  • В обратных кавычках ` значения подставляются через ${…}.
  • trim() убирает пробелы по краям, toLowerCase() переводит в нижний регистр, includes проверяет, есть ли кусок текста, split режет текст на части.

Числа​

const sum = Number(row[2]) || 0;
Math.round(sum * 100) / 100;
Utilities.formatNumber(sum, { currency: "RUB" });
  • Number(value) превращает текст в число. Если это не число, получится NaN, а || 0 заменит его на ноль.
  • Округление до копеек — через Math.round.
  • Чтобы показать число красиво, используйте Utilities.formatNumber, а в ячейку записывайте само число и задавайте формат через setNumberFormat.

Даты​

Дата из ячейки приходит объектом Date. Для работы с датами используйте команды Utilities: они считают в часовом поясе владельца скрипта.

Допустим, в столбце E записан срок:

const today = Utilities.today();
const weekAgo = Utilities.addDays(today, -7);
const due = Utilities.toDate(row[4]);

if (due !== null && due < today) {
console.log("Просрочено:", Utilities.formatDate(due, "dd.MM.yyyy"));
}

Стандартные getDate(), getHours() и new Date(год, месяц, день) работают в часовом поясе сервера, поэтому дата может сдвинуться на день. Подробнее в статье Даты, числа и утилиты.

Остановить скрипт с ошибкой​

if (!sheet) throw new Error("Нет листа «Заказы»");

throw останавливает скрипт, запуск в журнале получает статус «Ошибка» с вашим текстом. Это лучше, чем молча записать неверные данные.

Чтобы ошибка одной строки не останавливала весь скрипт, оберните опасное место в try:

try {
const response = Http.fetch(url);
console.log(response.status);
} catch (error) {
console.warn("Сервис не ответил:", error.message);
}

Частые ошибки​

Сообщение или симптомПричинаЧто сделать
Cannot read properties of undefinedобращение к строке или ячейке, которой нет: индекс больше длины массива или столбец не найденпроверьте indexOf на -1 и границы цикла i < rows.length
Cannot read properties of nullкоманда вернула null: getSheetByName не нашёл лист, Utilities.toDate не распознал датупроверьте значение перед использованием: if (!sheet) …
… is not definedопечатка в имени переменной или команды, регистр не совпалсверьте написание, например Coverse, а не coverse
… is not a functionу объекта нет такой командынайдите правильное название в Справочнике команд
Unexpected tokenлишняя или пропущенная скобка, кавычка, запятаяпосмотрите номер строки в журнале и проверьте парные скобки и кавычки рядом с ней
сравнение не срабатываетчисло сравнивается с текстом: "1500" === 1500 даёт falseприведите к одному виду: Number(value) === 1500 или String(value) === "1500"
сумма склеилась в текст: "1500800"одно из слагаемых — текстNumber(a) + Number(b)
текст не находитсялишние пробелы или другой регистрString(value).trim().toLowerCase() === "оплачен"
в журнале дата вида "2026-10-05T21:00:00.000Z"console.log показывает дату в UTCвыводите через Utilities.formatDate(date, "dd.MM.yyyy")

Пустая ячейка приходит пустой строкой "". Проверка «ячейка заполнена» выглядит так: if (row[2] !== "").

Как читать журнал​

  • Ставьте console.log в нужных местах: console.log("Строка листа", i + 1, row) покажет номер строки в таблице и её содержимое. Массивы и объекты выводятся в виде JSON.
  • При ошибке журнал показывает текст и номер строки кода, где она случилась.
  • Чтобы проверить функцию триггера, не дожидаясь события, используйте «Запустить с событием». См. Первый скрипт.

Что дальше​