Как правильно вызвать Web-сервис при проведении документа в 1С:Предприятие 8

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

При разработке систем интеграции между «1С:ERP Управление предприятием» и «1С:Документооборот» часто возникает задача оперативной передачи данных. Типичный сценарий: в момент проведения документа «Приобретение товаров и услуг» (ПТУ) в ERP необходимо отправить данные в «Документооборот», чтобы обновить дополнительные реквизиты в связанных заявках на закупку. Однако прямая реализация такой задачи «в лоб» через вызов Web-сервиса непосредственно в модуле объекта может привести к катастрофическим последствиям для производительности системы. В этой статье мы проанализируем, почему нельзя обращаться к внешним ресурсам внутри транзакции и разберем архитектурно верные способы решения этой задачи.

Проблема транзакционных блокировок и «греховных мыслей» разработчика

Рассмотрим ситуацию, когда код обращения к Web-сервису размещается непосредственно в процедуре ОбработкаПроведения. Проблема заключается в том, что в этот момент система 1С находится внутри транзакции базы данных. Проанализируем риски такого подхода:

  1. Длительность транзакции: Пока 1С ожидает ответа от внешнего сервиса (который может тормозить из-за нагрузки на сеть или долгой обработки запроса), транзакция в ERP остается открытой. В это время таблицы, задействованные в проведении ПТУ, заблокированы для других пользователей. Если сервис отвечает 20–30 секунд, работа всего отдела закупок может парализоваться.
  2. Риск «фантомных» данных: Представим ситуацию: Web-сервис успешно принял массив данных и обновил информацию в «1С:Документооборот». Но сразу после возврата управления в ERP происходит ошибка проведения (например, нехватка остатков по другому регистру или исключение в коде). Транзакция в ERP откатывается, документ остается непроведенным, а данные в Документообороте уже изменены. Возникает рассинхронизация баз.
  3. Нестабильность связи: Если сервер Документооборота временно недоступен, пользователь не сможет провести документ в ERP. Система выдаст ошибку, и бизнес-процесс закупки остановится.

Именно поэтому опытные разработчики называют идею прямого вызова сервиса при проведении «греховной». Разберем, как сделать это правильно.

Решение №1: Использование Регистра Сведений и регламентного задания (Асинхронная модель)

Это самый надежный и рекомендуемый метод. Суть его заключается в разделении момента фиксации данных и момента их отправки. Разберем этот процесс по шагам.

Шаг 1. Создадим вспомогательный РегистрСведений, например, ОчередьИнтеграцииСДО. В нем должны быть измерения Объект (ДокументСсылка.ПриобретениеТоваровУслуг) и ресурсы для хранения данных (или строка JSON с массивом номеров).

Шаг 2. В процедуре ОбработкаПроведения мы не вызываем сервис, а просто записываем в этот регистр информацию о том, что документ требует выгрузки. Запись в регистр внутри транзакции происходит мгновенно и надежно.

Шаг 3. Создаем РегламентноеЗадание, которое с определенной периодичностью (например, раз в минуту) считывает записи из этого регистра, формирует массив и отправляет его в Web-сервис Документооборота.

Проанализируем пример кода для записи в очередь:


Процедура ОбработкаПроведения(Отказ, РежимПроведения)
    // Основная логика проведения документа
    // ...
    
    // Фиксация намерения отправить данные
    МенеджерЗаписи = РегистрыСведений.ОчередьИнтеграцииСДО.СоздатьМенеджерЗаписи();
    МенеджерЗаписи.Объект = ЭтотОбъект.Ссылка;
    МенеджерЗаписи.СостояниеОтправки = Перечисления.СостоянияИнтеграции.ВТрафике;
    МенеджерЗаписи.ДатаРегистрации = ТекущаяДатаСеанса();
    МенеджерЗаписи.Записать();
КонецПроцедуры

В этом случае, если транзакция ERP откатится, запись в регистре также исчезнет, и «лишних» данных в Документооборот не уйдет.

Решение №2: Вызов фонового задания (Мгновенная асинхронность)

Если руководство требует, чтобы данные уходили «здесь и сейчас», и задержка в минуту недопустима, мы можем запустить фоновое задание сразу после завершения транзакции. Рассмотрим подробнее, как это реализовать.

Для этого лучше использовать обработчик события ПослеЗаписи в модуле формы или механизм подписок на события. Важно, чтобы вызов происходил вне транзакции проведения. Выясним причину: фоновое задание работает в отдельном сеансе и должно иметь возможность прочитать уже зафиксированные в базе данные документа.


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

Этот метод позволяет пользователю продолжить работу не дожидаясь ответа от Web-сервиса, в то время как сервер 1С в фоновом режиме будет пытаться связаться с внешней системой.

Решение №3: Использование Библиотеки стандартных подсистем (БСП)

В современных конфигурациях, таких как 1С:ERP, уже встроена подсистема «Очередь заданий». Вместо написания собственного велосипеда с Регистрами Сведений, мы можем использовать готовые механизмы БСП. Это обеспечит нам дополнительные возможности:

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

Технические нюансы: HTTP-сервисы и формат JSON

Хотя в обсуждении упоминается Web-сервис (обычно подразумевается SOAP), мы рекомендуем рассмотреть использование HTTP-сервисов. Выясним, почему это эффективнее:

1. Легкость данных: Использование формата JSON вместо тяжеловесного XML (SOAP) значительно сокращает объем передаваемого трафика. Для мобильных сетей или слабых каналов связи это критично.

2. Простота сериализации: В 1С массив номеров ПТУ превращается в JSON одной строкой:


ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.УстановитьСтроку();
ЗаписатьJSON(ЗаписьJSON, МассивНомеровПТУ);
СтрокаJSON = ЗаписьJSON.Закрыть();

3. Удобство отладки: HTTP-запросы проще тестировать через сторонние утилиты (например, Postman), что ускоряет процесс разработки и поиска ошибок в интеграции.

Подведем итоги

Реализация прямого обращения к Web-сервису внутри ОбработкаПроведения — это технический долг, который обязательно приведет к жалобам пользователей на «зависания» системы. Правильный путь — это асинхронность. Используйте Регистры Сведений для хранения очереди сообщений и регламентные задания для их отправки. Это гарантирует целостность данных в обеих базах и стабильную работу пользователей в 1С:ERP.

← На главную