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