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

Интеграция таблиц с 1С

Связать 1С:Предприятие 8.3 с таблицей Coverse можно двумя способами. Они не исключают друг друга.

СпособКто начинает обменКогда подходитЧто нужно со стороны 1С
1С отправляет в таблицу1Снужно сразу видеть проведённые документы, оплаты, изменения остатковпрограммист 1С добавляет около 30 строк кода; база может стоять в локальной сети
Таблица забирает из 1Сскрипт по расписаниюнужны справочники, документы за период, данные для отчётавключить стандартный интерфейс OData; база должна быть доступна из интернета

Если 1С должна писать в таблицу большие объёмы данных без скрипта, можно обращаться к API Coverse Таблиц напрямую: начните с руководства Первая интеграция.

1С отправляет в таблицу​

1С отправляет JSON с данными документа на адрес вебхука скрипта, скрипт записывает строку. Запрос идёт из 1С наружу, поэтому способ работает и для базы в локальной сети: нужен только выход в интернет.

1. Скрипт в таблице​

Создайте скрипт и вставьте код. Он записывает документ на лист «Документы 1С», а повторную отправку того же документа обновляет, а не дублирует.

const SHEET = "Документы 1С";

function onWebhook(event) {
if (!event) return;
if (!event.json) {
console.warn("Тело запроса не JSON:", event.body);
return;
}

const doc = event.json;
if (!doc.id) {
console.warn("В документе нет id:", JSON.stringify(doc));
return;
}

const values = [
asText(doc.id),
asText(doc.number),
Utilities.toDate(doc.date) || "",
asText(doc.client),
Number(doc.total) || 0,
new Date(),
];

const sheet = Coverse.table.getSheetByName(SHEET) || Coverse.table.insertSheet(SHEET);
if (sheet.getLastRow() === 0) {
sheet.appendRow(["ID", "Номер", "Дата", "Контрагент", "Сумма", "Получено"]);
}

const rows = sheet.getRange(1, 1, sheet.getLastRow(), 1).getValues();
const index = rows.findIndex((row) => String(row[0]) === values[0]);
if (index === -1) {
sheet.appendRow(values);
} else {
sheet.getRange(index + 1, 1, 1, values.length).setValues([values]);
}
}

function asText(value) {
const text = String(value === undefined || value === null ? "" : value);
return text.charAt(0) === "=" ? "'" + text : text;
}
  • id — уникальный идентификатор документа в 1С. По нему скрипт находит уже записанную строку.
  • Дату 1С передаёт без часового пояса, например 2026-10-19T12:30:00. Utilities.toDate понимает её в часовом поясе владельца скрипта и возвращает null, если дата не распознана, поэтому одна неверная дата не остановит скрипт.
  • asText не даёт тексту, который начинается с =, стать формулой.

2. Адрес вебхука​

  1. На вкладке «Триггеры» добавьте триггер «По вебхуку» с функцией onWebhook.
  2. Скопируйте адрес вида https://app.coverse.team/api/hooks/scripts/whs_….
  3. Если 1С выходит в интернет с постоянного адреса, укажите его в поле «Разрешённые IP-адреса» триггера.

Подробнее: Вебхуки.

3. Код в 1С​

Программист 1С добавляет процедуру отправки в общий модуль, который выполняется на сервере: из тонкого клиента HTTP-запросы недоступны. Сервер и путь берутся из адреса вебхука: сервер — app.coverse.team, путь — всё, что после него, начиная с /api/hooks/…. Адрес лучше хранить в константе или настройке, а не в коде.

Процедура ОтправитьВCoverse(Данные, ПутьВебхука) Экспорт

Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
Настройки = Новый НастройкиСериализацииJSON;
Настройки.ФорматСериализацииДаты = ФорматДатыJSON.ISO;
Настройки.ВариантЗаписиДаты = ВариантЗаписиДатыJSON.ЛокальнаяДата;
ЗаписатьJSON(Запись, Данные, Настройки);
Текст = Запись.Закрыть();

Соединение = Новый HTTPСоединение("app.coverse.team", 443, , , , 30, Новый ЗащищенноеСоединениеOpenSSL());

Заголовки = Новый Соответствие;
Заголовки.Вставить("Content-Type", "application/json; charset=utf-8");

Запрос = Новый HTTPЗапрос(ПутьВебхука, Заголовки);
Запрос.УстановитьТелоИзСтроки(Текст, КодировкаТекста.UTF8, ИспользованиеByteOrderMark.НеИспользовать);

Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Если Ответ.КодСостояния <> 200 Тогда
ВызватьИсключение "Coverse ответил " + Строка(Ответ.КодСостояния) + ": " + Ответ.ПолучитьТелоКакСтроку();
КонецЕсли;

КонецПроцедуры

Пример вызова для документа реализации. Названия реквизитов зависят от конфигурации, подставьте свои:

Данные = Новый Структура;
Данные.Вставить("id", Строка(Документ.Ссылка.УникальныйИдентификатор()));
Данные.Вставить("number", Документ.Номер);
Данные.Вставить("date", Документ.Дата);
Данные.Вставить("client", Строка(Документ.Контрагент));
Данные.Вставить("total", Документ.СуммаДокумента);

ОтправитьВCoverse(Данные, ПутьВебхука);

Тело отправляется в UTF-8 без метки BOM: с меткой Coverse не распознает JSON. Для HTTPS-соединения нужна платформа 8.3 с поддержкой TLS 1.2.

Что отвечает Coverse​

КодЧто значитЧто делать в 1С
200, тело OKзапрос принят и поставлен в очередь скриптаничего
401подпись неверная, если в триггере включена проверка подписипроверьте настройки подписи
403адрес 1С не в списке разрешённых, триггер выключен или скрипты недоступны на тарифе владельцатекст причины в поле error ответа
404неверный путь вебхукаскопируйте адрес из карточки триггера заново
413тело больше 100 КБотправляйте документы по одному, без лишних реквизитов
429больше 60 запросов в минуту, очередь скрипта переполнена или закончилась норма минутповторите позже, заголовок Retry-After подскажет, через сколько секунд

Ответ 200 означает, что запрос принят, но скрипт выполняется уже после ответа. Если скрипт упадёт с ошибкой, 1С об этом не узнает: результат видно только в журнале скрипта.

Где вызывать отправку​

Не отправляйте запрос прямо внутри проведения документа: если сеть или Coverse недоступны, проведение замедлится или завершится ошибкой. Надёжнее при проведении только отмечать документ к отправке, а отправлять регламентным заданием раз в несколько минут:

  • отправляйте не больше 60 документов в минуту на один адрес;
  • при ответе 429 или ошибке сети повторяйте попытку позже, остальные коды требуют исправления настроек;
  • повторная отправка безопасна: скрипт обновит строку по id.

Таблица забирает из 1С через OData​

У 1С:Предприятия 8.3 есть стандартный интерфейс OData: справочники, документы и регистры доступны по HTTP в формате JSON. Скрипт по расписанию запрашивает нужные данные и записывает их на лист.

1. Включите OData​

Облачная 1С (1cfresh.com). Интерфейс OData в приложениях 1С:Фреш уже включён. Пользователь с полными правами открывает Администрирование → Синхронизация данных → Настройки стандартного интерфейса OData (в некоторых приложениях раздел называется «Администрирование и НСИ» или «Настройки»):

  1. На вкладке «Состав» отметьте объекты, которые нужны скрипту, например документ заказа клиента и справочник номенклатуры.
  2. На вкладке «Авторизация» создайте отдельного пользователя для обмена и запишите логин и пароль.

Адрес интерфейса выглядит так: https://1cfresh.com/a/<приложение>/<номер области>/odata/standard.odata/. Подробнее — в статье 1С:Фреш.

Своя база.

  1. В конфигураторе откройте Администрирование → Публикация на веб-сервере и отметьте «Публиковать стандартный интерфейс OData».
  2. Задайте состав объектов, доступных через OData. В типовых конфигурациях это делается в режиме 1С:Предприятие обработкой «Настройка стандартного интерфейса OData», в остальных — программно, процедурой УстановитьСоставСтандартногоИнтерфейсаOData.
  3. Создайте пользователя для обмена с ролью «Удаленный доступ OData» или с полными правами. Лучше отдельного, с логином латиницей.
  4. Опубликованная база должна открываться из интернета по HTTPS с действительным сертификатом. Скрипты не обращаются к адресам локальной сети, а из портов доступны 80, 443 и с 1024 по 65535.

Адрес интерфейса: https://<ваш сервер>/<имя публикации>/odata/standard.odata/.

2. Узнайте имена объектов​

Объекты в OData называются по виду и имени в конфигурации: Catalog_Номенклатура, Document_ЗаказКлиента, InformationRegister_КурсыВалют. Имена зависят от конфигурации. Список доступных объектов вернёт адрес интерфейса с параметром ?$format=json, а реквизиты объекта видны в ответе на пробный запрос. Стандартные поля: Ref_Key (ссылка), Code и Description у справочников, Number, Date и Posted у документов, DeletionMark (пометка удаления).

3. Сохраните доступ в секреты​

На вкладке «Секреты» скрипта добавьте:

  • ODATA_URL — адрес интерфейса, заканчивается на /odata/standard.odata/;
  • ODATA_USER — логин пользователя обмена;
  • ODATA_PASSWORD — пароль.

4. Код скрипта​

Скрипт каждый раз загружает заказы за последние 7 дней и переписывает ими лист «Заказы из 1С». Так в таблице всегда актуальная картина, включая исправленные и распроведённые документы, и не нужно следить за повторами.

const ENTITY = "Document_ЗаказКлиента";
const DAYS = 7;
const SHEET = "Заказы из 1С";
const PAGE = 500;
const MAX_PAGES = 20;

function main() {
const base = Secrets.get("ODATA_URL");
const user = Secrets.get("ODATA_USER");
const password = Secrets.get("ODATA_PASSWORD");
if (!base || !user || !password) throw new Error("Добавьте секреты ODATA_URL, ODATA_USER и ODATA_PASSWORD");

const url = base.replace(/\/?$/, "/") + encodeURIComponent(ENTITY);
const auth = "Basic " + Utilities.base64Encode(user + ":" + password);
const from = Utilities.formatDate(Utilities.addDays(Utilities.today(), -DAYS), "yyyy-MM-dd'T'HH:mm:ss");

const items = [];
for (let page = 0; page < MAX_PAGES; page++) {
const query = [
"$format=json",
"$filter=" + encodeURIComponent("Date ge datetime'" + from + "' and DeletionMark eq false"),
"$select=" + encodeURIComponent("Ref_Key,Number,Date,Posted,СуммаДокумента"),
"$orderby=" + encodeURIComponent("Date,Ref_Key"),
"$top=" + PAGE,
"$skip=" + page * PAGE,
].join("&");

const response = Http.get(url + "?" + query, {
headers: { Authorization: auth, Accept: "application/json" },
});
if (!response.ok) throw new Error("1С ответила с кодом " + response.status + ": " + response.text().slice(0, 500));

const chunk = response.json().value || [];
items.push(...chunk);
if (chunk.length < PAGE) break;
if (page === MAX_PAGES - 1) throw new Error("Документов больше " + PAGE * MAX_PAGES + ", уменьшите DAYS");
}

const rows = items.map((item) => [
item.Ref_Key,
asText(item.Number),
Utilities.toDate(item.Date) || "",
item.Posted === true,
Number(item.СуммаДокумента) || 0,
]);

const sheet = Coverse.table.getSheetByName(SHEET) || Coverse.table.insertSheet(SHEET);
sheet.getRange("A1:E").clear();
sheet.getRange(1, 1, 1, 5).setValues([["Ссылка", "Номер", "Дата", "Проведён", "Сумма"]]);
if (rows.length > 0) {
sheet.getRange(2, 1, rows.length, 5).setValues(rows);
}
console.log("Загружено документов:", rows.length);
}

function asText(value) {
const text = String(value === undefined || value === null ? "" : value);
return text.charAt(0) === "=" ? "'" + text : text;
}

Что подставить своё:

  • ENTITY — имя объекта из шага 2.
  • Реквизиты в $select и в rows: СуммаДокумента — пример, в вашей конфигурации сумма может называться иначе.
  • DAYS — за сколько дней загружать.

Что важно в коде:

  • Документы загружаются страницами по 500 через $top и $skip, до 20 страниц. Если документов больше, скрипт остановится с ошибкой, а не запишет неполные данные.
  • Параметры запроса собираются вручную, а значения кодируются через encodeURIComponent, потому что в фильтре есть пробелы, кавычки и кириллица.
  • Дата в фильтре записывается как datetime'2026-10-12T00:00:00', это синтаксис OData.
  • Ответ — объект с массивом value, по элементу на документ.
  • Скрипт очищает столбцы A:E листа «Заказы из 1С» и записывает их заново. Документы старше DAYS дней с листа уходят. Свои формулы и заметки держите на другом листе или в столбцах правее E.

5. Проверьте и включите расписание​

  1. Нажмите «Запустить»: в журнале появится «Загружено документов: N», на листе — таблица заказов.
  2. На вкладке «Триггеры» добавьте триггер «По расписанию», например каждый час.

Если что-то не работает​

СимптомПричинаЧто сделать
Http.fetch: запросы на внутренние адреса запрещены.адрес 1С во внутренней сетиопубликуйте базу с адресом, доступным из интернета, или используйте способ «1С отправляет в таблицу»
Http.fetch: порт … запрещён.веб-сервер 1С на порту ниже 1024, кроме 80 и 443перенесите публикацию на порт 443 или выше 1024
Http.fetch: сертификат сервера не прошёл проверку.у публикации самоподписанный сертификатустановите сертификат, выданный центром сертификации
Http.fetch: сервер не ответил вовремя.1С не ответила за 15 секундуменьшите PAGE, DAYS или число реквизитов в $select
Http.fetch: ответ больше 2097152 байт.ответ 1С больше 2 МБуменьшите PAGE или число реквизитов
1С ответила с кодом 401неверный логин или пароль, или у пользователя нет прав на объектпроверьте секреты, роль пользователя и состав объектов OData
1С ответила с кодом 404 или 400неверное имя объекта или реквизитасверьте имена со списком, который возвращает адрес интерфейса
в 1С ошибка «Coverse ответил 403» или 404адрес 1С не разрешён в триггере или неверный путь вебхукасм. таблицу Что отвечает Coverse
в журнале «Тело запроса не JSON»1С отправила тело с меткой BOM или не в JSONотправляйте тело через УстановитьТелоИзСтроки с ИспользованиеByteOrderMark.НеИспользовать
дата пустая1С передала дату в другом форматепередавайте дату как в примере: ФорматДатыJSON.ISO, ВариантЗаписиДатыJSON.ЛокальнаяДата

Частые вопросы​

Можно ли связать таблицу с 1С без своего сервера?​

Да. 1С может сама отправлять документы на вебхук скрипта, а скрипт может по расписанию забирать данные из 1С через стандартный интерфейс OData.

Работает ли интеграция с 1С в локальной сети?​

Да, если 1С отправляет данные в таблицу: запрос идёт из 1С наружу. Забирать данные из 1С скриптом можно, только если база опубликована с адресом, доступным из интернета.

Подходит ли облачная 1С:Фреш?​

Да. В 1С:Фреш стандартный интерфейс OData уже включён, нужно выбрать объекты и создать пользователя для обмена в настройках OData.

Что дальше​