Автоматизация обмена данными между базами в локальной сети — одна из классических задач программиста 1С. Часто возникает необходимость, чтобы при создании контрагента в «Управлении торговлей» он мгновенно появлялся в «Бухгалтерии предприятия» вместе с основным договором. Рассмотрим подробно, как это реализовать, используя современные механизмы платформы 1С:Предприятие 8.3.
Прежде чем приступать к написанию кода, проанализируем общую схему взаимодействия. У нас есть две базы: Источник (где создается контрагент) и Приемник (где он должен быть создан автоматически). Для решения этой задачи мы можем использовать несколько инструментов:
Разберем вариант с созданием 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);
Попытка
Ответ = Соединение.ОтправитьДляОбработки(Запрос);
Исключение
// Здесь важно логировать ошибку, но не прерывать запись в основной базе
ЗаписатьЛогОшибки("Сервер приемник недоступен");
КонецПопытки;
КонецПроцедуры
Если мы не хотим программировать в базе-приемнике, можно использовать протокол OData. Рассмотрим этот вариант. Платформа 1С позволяет обращаться к объектам базы через стандартные URL. Для этого базу нужно опубликовать на веб-сервере (Apache или IIS) с установленной галочкой "Публиковать стандартный интерфейс OData".
Проанализируем нюансы работы с OData при создании пары «Контрагент + Договор»:
GET запрос к Catalog_Контрагенты с фильтром по ИНН, чтобы проверить существование объекта.POST запрос для создания контрагента.Владелец при отправке второго POST запроса в Catalog_ДоговорыКонтрагентов.Использование OData упрощает разработку на стороне приемника, но усложняет логику на стороне источника, так как приходится делать несколько последовательных вызовов.
Рассмотрим критически важный момент: что произойдет, если в момент записи контрагента в базе А база Б будет выключена или пропадет интернет? Если вызывать HTTP-сервис напрямую из подписки ПриЗаписи, пользователь увидит ошибку или долгое "зависание" программы.
Выясним причину, по которой стоит использовать промежуточный Регистр сведений:
ОчередьОбмена, куда помещаем ссылку на созданного контрагента.РегламентноеЗадание, которое работает в фоне раз в 1-5 минут.Такой подход гарантирует доставку данных даже при временных сбоях связи и не замедляет работу пользователей в основной базе.
Проанализируем проблему синхронизации при изменении данных. Если пользователь в первой базе изменит название контрагента, система должна обновить его в базе-приемнике, а не создавать новый дубль. Поиск по ИНН — хороший метод, но ИНН тоже может быть изменен (например, при исправлении ошибки ввода).
Рекомендация: при создании нового контрагента в базе-приемнике через HTTP-сервис используйте метод УстановитьСсылкуНового(). Передавайте UUID (Уникальный идентификатор) из базы-источника в базу-приемник. Таким образом, контрагенты в обеих базах будут иметь одинаковые внутренние идентификаторы 1С, что позволит однозначно находить их при любых последующих изменениях реквизитов.
// В базе приемнике при создании
СсылкаИзИсточника = Новый УникальныйИдентификатор(ДанныеКонтрагента.GUID);
НовыйКонтрагент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйКонтрагент.УстановитьСсылкуНового(Справочники.Контрагенты.ПолучитьСсылку(СсылкаИзИсточника));
// Заполнение реквизитов...
НовыйКонтрагент.Записать();
При публикации базы на веб-сервере (например, Apache) важно помнить о безопасности. Разберем основные правила:
Таким образом, мы рассмотрели комплексный подход к автоматизации создания объектов между базами 1С. Использование HTTP-сервисов в сочетании с фоновым обменом через регистр сведений является наиболее надежным и масштабируемым решением для современной платформы 1С:Предприятие.