Как настроить автоматическое создание контрагентов и их договоров в другой базе 1С через HTTP-сервисы

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Автоматизация обмена данными между базами в локальной сети — одна из классических задач программиста 1С. Часто возникает необходимость, чтобы при создании контрагента в «Управлении торговлей» он мгновенно появлялся в «Бухгалтерии предприятия» вместе с основным договором. Рассмотрим подробно, как это реализовать, используя современные механизмы платформы 1С:Предприятие 8.3.

Архитектурный подход к решению задачи

Прежде чем приступать к написанию кода, проанализируем общую схему взаимодействия. У нас есть две базы: Источник (где создается контрагент) и Приемник (где он должен быть создан автоматически). Для решения этой задачи мы можем использовать несколько инструментов:

  1. HTTP-сервисы: разработка собственного программного интерфейса (API) в базе-приемнике.
  2. OData (REST API): использование стандартного интерфейса 1С, который не требует программирования в базе-приемнике.
  3. Подписки на события: механизм в базе-источнике, который будет инициировать отправку данных.
  4. Регистры сведений (очередь сообщений): промежуточный слой для обеспечения отказоустойчивости.

Вариант 1: Использование собственного HTTP-сервиса

Разберем вариант с созданием HTTP-сервиса в базе-приемнике. Это наиболее гибкий метод, позволяющий реализовать сложную логику проверки дублей и заполнения реквизитов.

Шаг 1. Создание сервиса в базе-приемнике

В дереве метаданных базы-приемника необходимо создать новый объект HTTPСервисы. Назовем его IntegrationService. Внутри него создадим ресурс /counterparty с методом POST. Рассмотрим пример кода для обработки входящего запроса:


Функция counterpartyPOST(Запрос)
    // Читаем данные из тела запроса (JSON)
    Чтение = Новый ЧтениеJSON;
    Чтение.УстановитьСтроку(Запрос.ПолучитьТелоКакСтроку());
    ДанныеКонтрагента = ПрочитатьJSON(Чтение);
    Чтение.Закрыть();
    
    // Ищем контрагента по ИНН, чтобы избежать дублей
    КонтрагентСсылка = Справочники.Контрагенты.НайтиПоРеквизиту("ИНН", ДанныеКонтрагента.ИНН);
    
    Если КонтрагентСсылка.Пустая() Тогда
        НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
    Иначе
        НовыйКонтрагент = КонтрагентСсылка.ПолучитьОбъект();
    КонецЕсли;
    
    НовыйКонтрагент.Наименование = ДанныеКонтрагента.Наименование;
    НовыйКонтрагент.ИНН = ДанныеКонтрагента.ИНН;
    НовыйКонтрагент.КПП = ДанныеКонтрагента.КПП;
    НовыйКонтрагент.Записать();
    
    // Создаем договор, если он передан
    Если ДанныеКонтрагента.Свойство("Договор") Тогда
        ДоговорОбъект = Справочники.ДоговорыКонтрагентов.СоздатьЭлемент();
        ДоговорОбъект.Владелец = НовыйКонтрагент.Ссылка;
        ДоговорОбъект.Наименование = ДанныеКонтрагента.Договор.Наименование;
        ДоговорОбъект.Записать();
    КонецЕсли;
    
    Возврат Новый HTTPСервисОтвет(201); // Created
КонецФункции

Шаг 2. Отправка запроса из базы-источника

Проанализируем, как отправить данные. Нам понадобится ПодпискаНаСобытие для справочника Контрагенты на событие ПриЗаписи. В обработчике события мы будем формировать JSON и отправлять его через HTTPСоединение.


Процедура ПриЗаписиКонтрагента(Источник, Отказ) Экспорт
    Если Источник.ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;
    
    Соединение = Новый HTTPСоединение("server-name/base-receiver", , "User", "Password");
    Запрос = Новый HTTPЗапрос("/hs/IntegrationService/counterparty");
    
    Данные = Новый Структура;
    Данные.Вставить("Наименование", Источник.Наименование);
    Данные.Вставить("ИНН", Источник.ИНН);
    Данные.Вставить("КПП", Источник.КПП);
    
    ЗаписьJSON = Новый ЗаписьJSON;
    ЗаписьJSON.УстановитьСтроку();
    ЗаписатьJSON(ЗаписьJSON, Данные);
    СтрJSON = ЗаписьJSON.Закрыть();
    
    Запрос.УстановитьТелоИзСтроки(СтрJSON);
    Попытка
        Ответ = Соединение.ОтправитьДляОбработки(Запрос);
    Исключение
        // Здесь важно логировать ошибку, но не прерывать запись в основной базе
        ЗаписатьЛогОшибки("Сервер приемник недоступен");
    КонецПопытки;
КонецПроцедуры

Вариант 2: Использование стандартного интерфейса OData

Если мы не хотим программировать в базе-приемнике, можно использовать протокол OData. Рассмотрим этот вариант. Платформа 1С позволяет обращаться к объектам базы через стандартные URL. Для этого базу нужно опубликовать на веб-сервере (Apache или IIS) с установленной галочкой "Публиковать стандартный интерфейс OData".

Проанализируем нюансы работы с OData при создании пары «Контрагент + Договор»:

  1. Сначала необходимо отправить GET запрос к Catalog_Контрагенты с фильтром по ИНН, чтобы проверить существование объекта.
  2. Если объект не найден, отправляем POST запрос для создания контрагента.
  3. После успешного создания контрагента платформа вернет GUID созданного объекта. Его необходимо использовать как значение поля Владелец при отправке второго POST запроса в Catalog_ДоговорыКонтрагентов.

Использование OData упрощает разработку на стороне приемника, но усложняет логику на стороне источника, так как приходится делать несколько последовательных вызовов.

Обеспечение надежности: Очередь событий (Outbox Pattern)

Рассмотрим критически важный момент: что произойдет, если в момент записи контрагента в базе А база Б будет выключена или пропадет интернет? Если вызывать HTTP-сервис напрямую из подписки ПриЗаписи, пользователь увидит ошибку или долгое "зависание" программы.

Выясним причину, по которой стоит использовать промежуточный Регистр сведений:

Такой подход гарантирует доставку данных даже при временных сбоях связи и не замедляет работу пользователей в основной базе.

Работа с уникальными идентификаторами (GUID)

Проанализируем проблему синхронизации при изменении данных. Если пользователь в первой базе изменит название контрагента, система должна обновить его в базе-приемнике, а не создавать новый дубль. Поиск по ИНН — хороший метод, но ИНН тоже может быть изменен (например, при исправлении ошибки ввода).

Рекомендация: при создании нового контрагента в базе-приемнике через HTTP-сервис используйте метод УстановитьСсылкуНового(). Передавайте UUID (Уникальный идентификатор) из базы-источника в базу-приемник. Таким образом, контрагенты в обеих базах будут иметь одинаковые внутренние идентификаторы 1С, что позволит однозначно находить их при любых последующих изменениях реквизитов.


// В базе приемнике при создании
СсылкаИзИсточника = Новый УникальныйИдентификатор(ДанныеКонтрагента.GUID);
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку(СсылкаИзИсточника));
// Заполнение реквизитов...
НовыйКонтрагент.Записать();

Безопасность и отладка

При публикации базы на веб-сервере (например, Apache) важно помнить о безопасности. Разберем основные правила:

Таким образом, мы рассмотрели комплексный подход к автоматизации создания объектов между базами 1С. Использование HTTP-сервисов в сочетании с фоновым обменом через регистр сведений является наиболее надежным и масштабируемым решением для современной платформы 1С:Предприятие.

← На главную