Часто перед разработчиком встает задача автоматизировать процесс, который не требует участия пользователя: обновление цен, загрузка данных из внешних источников или рассылка уведомлений. Если по каким-то причинам вы не хотите или не можете изменять основную конфигурацию (например, когда нельзя добавить новое РегламентноеЗадание в расширение), на помощь приходит механизм дополнительных отчетов и обработок Библиотеки стандартных подсистем (БСП). Рассмотрим подробно, как превратить обычную внешнюю обработку в полноценный фоновый процесс.
Первое и самое важное правило, которое часто упускают начинающие разработчики: весь управляющий код для фонового задания должен находиться исключительно в Модуле объекта внешней обработки. Проанализируем ситуацию: когда система запускает обработку по расписанию, она делает это на стороне сервера в фоновом сеансе. В этом сеансе не инициализируются формы, поэтому код в модуле формы просто не будет вызван. Разберем структуру модуля объекта подробнее.
Для того чтобы подсистема «Дополнительные отчеты и обработки» опознала нашу разработку и позволила настроить для нее расписание, нам необходимо реализовать экспортную функцию СведенияОВнешнейОбработке. Проанализируем пример кода, который позволит системе зарегистрировать нашу команду как серверный метод:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
ПараметрыРегистрации.Вставить("Вид", "ДополнительнаяОбработка");
ПараметрыРегистрации.Вставить("Наименование", "Моя фоновая обработка");
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("Информация", "Выполнение задачи по расписанию");
// Создаем таблицу команд
ТаблицаКоманд = ПолучитьТаблицуКоманд();
// Добавляем команду
// Использование "ВызовСерверногоМетода" — критически важно для работы в фоне
ДобавитьКоманду(ТаблицаКоманд,
"Запустить выполнение",
"ОсновнаяКоманда",
"ВызовСерверногоМетода",
Истина);
ПараметрыРегистрации.Вставить("Команды", ТаблицаКоманд);
Возврат ПараметрыРегистрации;
КонецФункции
Функция ПолучитьТаблицуКоманд()
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("ПоказыватьОповещение", Новый ОписаниеТипов("Булево"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Возврат Команды;
КонецФункции
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Обратим внимание на параметр Использование. Значение ВызовСерверногоМетода сообщает системе, что при запуске команды должен быть вызван программный метод в модуле объекта, а не открыта форма обработки.
После того как система зарегистрирует обработку, при наступлении времени по расписанию она обратится к процедуре ВыполнитьКоманду. Важно соблюдать правильную сигнатуру (набор параметров) этой процедуры, иначе возникнет ошибка "Недостаточно фактических параметров".
Рассмотрим правильную реализацию:
// Процедура вызывается платформой при выполнении команды
// ИдентификаторКоманды - строка, которую мы указали при регистрации
// ПараметрыВыполненияКоманды - структура с контекстом выполнения
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполненияКоманды = Неопределено) Экспорт
Если ИдентификаторКоманды = "ОсновнаяКоманда" Тогда
ВыполнитьОсновнуюЛогику();
КонецЕсли;
КонецПроцедуры
Процедура ВыполнитьОсновнуюЛогику()
// Здесь размещается ваш основной код
// ВАЖНО: В фоновом задании метод Сообщить() не выведет текст пользователю!
// Для логирования используем Журнал Регистрации
ТекстСообщения = "Фоновая обработка успешно запущена в " + ТекущаяДата();
ЗаписьЖурналаРегистрации("МояОбработка.Выполнение",
УровеньЖурналаРегистрации.Информация,
,
,
ТекстСообщения);
// Пример полезного действия
// ... ваш код ...
КонецПроцедуры
Выясним причину частого вопроса: "Почему я добавил Сообщить(), а ничего не происходит?". Когда код выполняется в фоновом режиме, у него нет графического интерфейса. Все, что вы выводите через Сообщить, уходит "в пустоту". Для мониторинга работы используйте объект ЗаписьЖурналаРегистрации. Это единственный штатный способ убедиться, что ваше задание отработало успешно, или проанализировать ошибку в блоке Попытка...Исключение.
После подготовки файла обработки выполним следующие шаги в программе:
В функции СведенияОВнешнейОбработке мы указали БезопасныйРежим = Ложь. Разберем, что это значит. Если ваша обработка должна записывать файлы на диск, работать с COM-объектами или использовать привилегированный режим, безопасный режим должен быть выключен. При включенном безопасном режиме (Истина) возможности кода сильно ограничены для защиты системы.
При использовании небезопасного режима система при регистрации может выдать предупреждение. Администратор должен подтвердить разрешение, нажав кнопку "Разрешить выполнение".
Мы проанализировали процесс создания регламентированной внешней обработки. Основные шаги включают в себя создание экспортных методов в модуле объекта, правильную обработку параметров в ВыполнитьКоманду и обязательное логирование через журнал регистрации. Этот подход позволяет гибко настраивать автоматические задачи без снятия конфигурации с поддержки и без внесения изменений в расширения.