В процессе сопровождения и доработки типовых конфигураций "1С:Предприятие 8" программисты часто сталкиваются с задачей расширения стандартного функционала. Типичный пример: необходимо запустить определенный программный код (например, выгрузить отчет, отправить уведомление в мессенджер или обновить данные в другой системе) строго после завершения регламентного задания обмена, такого как ОбменССайтом или ОбменССчатом.
При этом существует жесткое архитектурное ограничение — нельзя вносить изменения в типовые объекты конфигурации, чтобы не усложнять последующие обновления системы. В этой статье мы подробно разберем несколько надежных и изящных способов решения этой задачи с использованием современных механизмов платформы "1С:Предприятие".
---
Проанализируем архитектуру большинства типовых обменов. По завершении своей работы регламентное задание практически всегда фиксирует свой статус в базе данных. Это может быть специализированный регистр сведений (например, УспешныеОбменыССайтом, СостоянияОбменовДанными) или системный регистр истории обменов БСП (Библиотеки Стандартных Подсистем).
Если мы можем определить, в какой регистр записывается успешный статус, мы можем использовать стандартный механизм платформы — Подписку на события.
Разберем реализацию этого способа по шагам:
_МойСлужебныйСобытияСервер). В свойствах модуля обязательно установим флаги Сервер и Внешнее соединение._ОтследитьЗавершениеОбмена).РегистрСведенийНаборЗаписей.УспешныеОбменыССайтом (или тот регистр, который отвечает за статус завершения вашего обмена).ПриЗаписи._МойСлужебныйСобытияСервер.ПриЗаписиСтатусаОбмена.Теперь напишем код обработчика. Важно учитывать, что при записи набора записей регистра платформа может сначала производить очистку старых записей (передавая пустой набор), а затем записывать новые. Нам нужно реагировать только на фактическую запись новых данных.
Процедура ПриЗаписиСтатусаОбмена(Источник, Отказ, Замещение) Экспорт
// Исключаем обработку пустых наборов при очистке регистра
Если Источник.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Проанализируем записанные строки
Для Каждого СтрокаЗаписи Из Источник Цикл
// Проверяем, что состояние обмена соответствует успешному окончанию
Если СтрокаЗаписи.СостояниеОбмена = Перечисления.СостоянияОбмена.Успешно Тогда
// Запускаем нашу кастомную логику постобработки
ВыполнитьПочтовоеОповещение(СтрокаЗаписи.УзелИнформационнойБазы);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Преимущества метода: полная независимость от кода самого регламентного задания. Метод работает на уровне СУБД при фиксации транзакции записи данных.
Ограничения: необходимо точно знать, в какой именно объект метаданных пишется статус и гарантирует ли эта запись окончание всего процесса обмена.
---
Если используемая версия платформы "1С:Предприятие" поддерживает механизм расширений (рекомендуется 8.3.10 и выше), то этот метод является наиболее современным, чистым и предпочтительным.
Суть метода заключается в перехвате выполнения процедуры общего модуля, которую вызывает регламентное задание, с помощью аннотации &После (&After).
Разберем алгоритм настройки расширения:
ОбменССайтомСлужебный.ВыполнитьОбменДанными.&После.Рассмотрим пример кода в модуле расширения:
&После("ВыполнитьОбменДанными")
Процедура Расш1_ВыполнитьОбменДанными(ПараметрыОбмена)
// Этот код гарантированно выполнится в том же фоновом сеансе
// сразу после успешного завершения основной процедуры обмена.
Попытка
// Вызываем логику нашей кастомной обработки из собственного модуля
МойМодульПостобработки.ВыполнитьДействияПослеОбмена();
ЗаписьЖурналаРегистрации("МониторингОбмена.Постобработка",
УровеньЖурналаРегистрации.Информация,
,
,
"Постобработка обмена успешно завершена.");
Исключение
// Обязательно обрабатываем ошибки, чтобы авария в нашей логике
// не привела к ложному флагу сбоя самого обмена, если это критично
ЗаписьЖурналаРегистрации("МониторингОбмена.Постобработка",
УровеньЖурналаРегистрации.Ошибка,
,
,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры
Преимущества метода: код выполняется строго в контексте фонового задания обмена, у вас есть доступ ко всем локальным переменным и параметрам, переданным в оригинальный метод. Основная конфигурация остается на 100% типовой.
---
Если применение расширений по каким-то причинам ограничено политикой безопасности компании, но создавать новые объекты в основной конфигурации разрешено, мы можем применить паттерн "Обертка".
Идея заключается в переносе расписания со стандартного регламентного задания на наше собственное, которое будет последовательно запускать сначала типовой обмен, а затем нашу логику.
Разберем по шагам, как это реализовать:
ОбменССчатом (снимем флаг использования).МойОбменСПостобработкой и настроим для него точно такое же расписание, какое было у оригинального задания._МойСлужебныйСобытияСервер.ВыполнитьОбменИПостобработку).Напишем код для нашего метода-обертки:
Процедура ВыполнитьОбменИПостобработку() Экспорт
// Шаг 1. Программный запуск оригинального метода обмена
Попытка
// Вызываем экспортируемую процедуру оригинального общего модуля
ОбменССайтомСлужебный.ВыполнитьОбменДанными();
Исключение
// Фиксируем ошибку оригинального обмена
ЗаписьЖурналаРегистрации("МойОбмен.Ошибка",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Ошибка при выполнении основного обмена: " + ОписаниеОшибки());
// Прерываем выполнение, так как обмен завершился аварийно
ВызватьИсключение "Основной обмен завершился с ошибкой. Постобработка отменена.";
КонецПопытки;
// Шаг 2. Выполнение нашей кастомной логики
Попытка
МойМодульПостобработки.ВыполнитьДействияПослеОбмена();
Исключение
ЗаписьЖурналаРегистрации("МойОбмен.ОшибкаПостобработки",
УровеньЖурналаРегистрации.Ошибка,
,
,
"Ошибка при выполнении постобработки: " + ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Преимущества метода: абсолютная предсказуемость и простота отладки. Логика гарантированно не запустится, если основной обмен завершился аварийно с генерацией исключения.
---
Этот способ незаменим, когда запуск обмена происходит асинхронно, интерактивно пользователем из формы или нам необходимо отследить завершение процесса на стороне клиента (в интерфейсе).
Платформа "1С:Предприятие" предоставляет мощный программный интерфейс для работы с активными процессами через менеджер ФоновыеЗадания.
Рассмотрим пример реализации на клиенте с использованием обработчика ожидания:
&НаКлиенте
Перем ИдентификаторФоновогоЗадания;
&НаКлиенте
Процедура ЗапуститьМониторингОбмена(IDЗадания)
ИдентификаторФоновогоЗадания = IDЗадания;
// Подключаем ежесекундную проверку состояния фонового процесса
ПодключитьОбработчикОжидания("ПроверитьСтатусВыполненияОбмена", 2, Ложь);
КонецПроцедуры
&НаКлиенте
Процедура ПроверитьСтатусВыполненияОбмена()
СостояниеЗадания = ПолучитьСостояниеЗаданияНаСервере(ИдентификаторФоновогоЗадания);
Если СостояниеЗадания = "Активно" Тогда
// Задание еще выполняется, продолжаем ожидать
Возврат;
Иначе
// Процесс завершился, отключаем таймер
ОтключитьОбработчикОжидания("ПроверитьСтатусВыполненияОбмена");
Если СостояниеЗадания = "Завершено" Тогда
ПоказатьПредупреждение(, "Обмен успешно завершен! Данные обновлены.");
// Выполняем действия на клиенте после обмена
Иначе
ПоказатьПредупреждение(, "В процессе обмена произошла ошибка!");
EndIf;
КонецЕсли;
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПолучитьСостояниеЗаданияНаСервере(Идентификатор)
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(Идентификатор);
Если Задание = Неопределено Тогда
Возврат "НеНайдено";
КонецЕсли;
Возврат Строка(Задание.Состояние);
КонецФункции
Преимущества метода: идеально подходит для интерактивных сценариев работы в управляемых формах, когда пользователю важно видеть актуальный статус выполнения длительной операции.
---
Мы подробно разобрали различные архитектурные подходы к отслеживанию окончания работы регламентных заданий в "1С:Предприятии". Выбор конкретного метода зависит от технических условий проекта:
&После). Это наиболее современный и удобный стандарт разработки.