Разработка надежного, быстрого и простого в поддержке обмена данными между независимыми базами 1С разных организаций — это классическая задача интеграции. Часто возникает сценарий, когда напрямую связывать базы данных нельзя из соображений безопасности, поэтому в качестве буфера используется промежуточный веб-сервер. В этой статье мы подробно разберем, как спроектировать и реализовать такую систему обмена с точки зрения платформы 1С, избегая избыточного программирования и сохраняя возможность обновления типовых конфигураций.
Прежде чем приступать к написанию кода, давайте проанализируем возможные варианты интеграции, которые предоставляет современная платформа 1С. Нам необходимо решить несколько ключевых задач:
Для решения этих задач мы рассмотрим четыре основных технологических подхода: от полностью готовых бесплатных сервисов до разработки собственных REST-интерфейсов на базе HTTP-сервисов 1С.
---
Это наиболее гибкий, современный и производительный способ интеграции, который идеально подходит, если промежуточный веб-сервер разрабатывается сторонним программистом. Вместо устаревшего и тяжеловесного протокола SOAP (веб-сервисы 1С) мы будем использовать легковесный HTTP-сервис.
Рассмотрим подробнее, как устроен этот механизм в 1С. В дереве конфигурации существует специализированный объект — HTTP-сервисы. Мы можем настроить шаблоны URL и связать их с методами (GET, POST, PUT, DELETE), обработчики которых пишутся на встроенном языке 1С.
Давайте разберем по шагам, как написать обработчик в 1С для приема заказа покупателя с веб-сервера. Веб-сервер отправляет нам POST-запрос с JSON-пакетом, содержащим ID товаров и количество. Наша задача — распарсить этот JSON и создать документ ЗаказПокупателя (или ЗаказКлиента).
Ниже представлен пример кода серверного модуля HTTP-сервиса, обрабатывающего входящий заказ:
Функция СоздатьЗаказПокупателя(Запрос)
// Получаем тело запроса в виде строки JSON
СтрокаJSON = Запрос.ПолучитьТелоКакСтроку("UTF-8");
// Читаем JSON во временную структуру 1С
Чтение = Новый ЧтениеJSON;
Чтение.УстановитьСтроку(СтрокаJSON);
ДанныеЗаказа = ПрочитатьJSON(Чтение);
Чтение.Закрыть();
// Начинаем транзакцию для безопасности записи данных
НачатьТранзакцию();
Попытка
// Создаем новый документ Заказ клиента
НовыйЗаказ = Документы.ЗаказКлиента.СоздатьДокумент();
НовыйЗаказ.Дата = ТекущаяДата();
НовыйЗаказ.Соглашение = Справочники.СоглашенияСКлиентами.НайтиПоРеквизиту("УникальныйИдентификаторБуфера", ДанныеЗаказа.ИдентификаторСоглашения);
НовыйЗаказ.Партнер = ДанныеЗаказа.ИдентификаторПартнера;
НовыйЗаказ.Контрагент = ДанныеЗаказа.ИдентификаторКонтрагента;
НовыйЗаказ.Организация = Справочники.Организации.НайтиПоРеквизиту("ИНН", ДанныеЗаказа.ИННПолучателя);
// Заполняем табличную часть товары
Для Каждого СтрокаТовара Из ДанныеЗаказа.Товары Цикл
НоваяСтрока = НовыйЗаказ.Товары.Добавить();
// Ищем номенклатуру по уникальному ID буферной базы
НоваяСтрока.Номенклатура = Справочники.Номенклатура.НайтиПоРеквизиту("ID_Буфера", СтрокаТовара.ID_Товара);
НоваяСтрока.Количество = СтрокаТовара.Количество;
НоваяСтрока.Цена = СтрокаТовара.Цена;
// Рассчитываем сумму
НоваяСтрока.Сумма = НоваяСтрока.Количество * НоваяСтрока.Цена;
КонецЦикла;
// Записываем и проводим документ
НовыйЗаказ.Записать(РежимЗаписиДокумента.Проведение);
ЗафиксироватьТранзакцию();
// Формируем успешный ответ
Ответ = Новый HTTPСервисОтвет(201); // Created
Ответ.УстановитьТелоИзСтроки("{""status"":""success"",""document_number"":""" + НовыйЗаказ.Номер + """}");
Возврат Ответ;
Исключение
ОтменитьТранзакцию();
// В случае ошибки возвращаем статус 500 и описание ошибки
Ответ = Новый HTTPСервисОтвет(500);
Ответ.УстановитьТелоИзСтроки("{""status"":""error"",""message"":""" + ОписаниеОшибки() + """}");
Возврат Ответ;
КонецПопытки;
КонецФункции
Для отправки данных о номенклатуре и остатках на веб-сервер используется обратный процесс. В 1С настраивается регламентное задание, которое с определенной периодичностью опрашивает измененные товары, сериализует их в JSON при помощи встроенных объектов ЗаписьJSON и отправляет POST-запрос на ваш веб-сервер при помощи объекта HTTPСоединение.
---
Мало кто знает, но если перед нами стоит задача максимально быстро настроить интеграцию и вообще не писать код внутри 1С, мы можем задействовать встроенный механизм платформы — стандартный интерфейс OData.
Выясним преимущества этого подхода. Начиная с версии 8.3.5, платформа 1С умеет автоматически генерировать готовый REST API для абсолютно всех объектов конфигурации (справочников, документов, регистров). Для этого достаточно при публикации информационной базы на веб-сервере (IIS или Apache) установить одну галочку: "Публиковать стандартный интерфейс OData".
После этого внешняя система сможет отправлять стандартные HTTP-запросы напрямую к базе 1С. Например:
GET /odata/standard.odata/Catalog_НоменклатураGET /odata/standard.odata/Catalog_Номенклатура(guid'идентификатор')POST /odata/standard.odata/Document_ЗаказКлиентаВажное преимущество OData: протокол по умолчанию поддерживает формат JSON. Внешний веб-сервер сможет легко считывать остатки, цены и создавать документы, используя стандартные CRUD-запросы. Чтобы ограничить доступ веб-сервера только к нужным таблицам, в 1С настраиваются права роли для специального пользователя, под которым авторизуется внешнее веб-приложение.
---
Один из главных вопросов автора темы: как позволить пользователям на стороне поставщика самостоятельно отмечать товары, предназначенные для выгрузки в буферную базу, и при этом избежать изменения типовой конфигурации 1С?
Рассмотрим подробнее современную технологию платформы — Расширения конфигурации (файлы .cfe). Расширение позволяет добавлять новые реквизиты, формы и логику работы, не снимая основную конфигурацию с поддержки. Это гарантирует, что базы клиентов будут без проблем обновляться в автоматическом режиме.
Алгоритм реализации этой задачи выглядит следующим образом:
Номенклатура и создаем в нем новый реквизит типа Булево — ВыгружатьВБуфер.ВыгружатьВБуфер равен Истина.Пример простого запроса в 1С для выборки таких товаров:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Код КАК Код,
| Номенклатура.Наименование КАК Наименование,
| ЕСТЬNULL(ТоварыНаСкладахОстатки.ВНаличииОстаток, 0) КАК Остаток
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
| ПО ТоварыНаСкладахОстатки.Номенклатура = Номенклатура.Ссылка
|ГДЕ
| Номенклатура.ВыгружатьВБуфер = ИСТИНА";
РезультатЗапроса = Запрос.Выполнить();
---
Если бюджет проекта равен нулю, а сроки сильно поджимают, то разработка собственного веб-сервера и программирование HTTP-обменов в 1С могут оказаться экономически нецелесообразными. Платформа 1С предлагает встроенное штатное решение для B2B-взаимодействия — сервис «1С:Бизнес-сеть».
Давайте проанализируем, почему этот сервис решает все задачи автора без написания кода:
---
Если вы все же решили писать собственную интеграцию через буферный веб-сервер, вам придется решить проблему идентификации товаров. У поставщика товар называется "Кабель силовой медный ВВГнг 3х2.5", а у покупателя — "Провод ВВГ 3х2,5 (ГОСТ)". Без GTIN сопоставить их автоматически крайне сложно.
Для решения этой задачи в типовых конфигурациях 1С используется встроенный регистр сведений «Номенклатура контрагентов» (в некоторых конфигурациях — «Номенклатура поставщиков»). Рассмотрим схему работы этого механизма:
[Контрагент-Поставщик + Внешний Идентификатор].Ниже представлен пример кода, реализующий поиск сопоставленной номенклатуры в 1С:
Функция НайтиВнутреннююНоменклатуру(ВнешнийИдентификатор, ПартнерПоставщик)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| НоменклатураКонтрагентов.Номенклатура КАК Номенклатура
|ИЗ
| РегистрСведений.НоменклатураКонтрагентов КАК НоменклатураКонтрагентов
|ГДЕ
| НоменклатураКонтрагентов.Идентификатор = &ВнешнийИдентификатор
| И НоменклатураКонтрагентов.Владелец = &ПартнерПоставщик";
Запрос.УстановитьПараметр("ВнешнийИдентификатор", ВнешнийИдентификатор);
Запрос.УстановитьПараметр("ПартнерПоставщик", ПартнерПоставщик);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
Возврат Выборка.Номенклатура;
КонецЕсли;
Возврат Справочники.Номенклатура.ПустаяСсылка();
КонецФункции
---
Подводя итоги нашего технического анализа, мы можем составить четкий план действий по внедрению интеграции: