В современной разработке на платформе 1С:Предприятие 8.3 использование механизма дополнительных отчетов и обработок (ДО) из состава Библиотеки стандартных подсистем (БСП) является стандартом де-факто. Однако часто возникает задача вызвать команду такой обработки не интерактивно (нажатием кнопки в интерфейсе), а программно: из другой обработки, по расписанию или при возникновении определенного события. В этой статье мы подробно разберем, как реализовать программный запуск дополнительных обработок для различных сценариев.
Прежде чем переходить к коду, проанализируем ситуацию. Дополнительные обработки регистрируются в справочнике ДополнительныеОтчетыИОбработки. Каждая обработка может содержать одну или несколько команд. Команды могут выполняться на сервере (без формы), открывать форму обработки или выполнять клиентский метод. Мы рассмотрим два наиболее востребованных сценария: запуск серверного метода в фоновом задании и открытие формы обработки.
Этот метод идеально подходит для ресурсоемких операций, таких как синхронизация данных, загрузка больших файлов или массовое перестроение индексов. Рассмотрим, как подготовить структуру команды и передать её на исполнение механизму длительных операций.
Для начала подготовим структуру команды. Нам необходимо заполнить параметры, которые ожидает БСП. Разберем этот процесс по шагам на стороне сервера:
&НаСервереБезКонтекста
Процедура ЗаполнитьСтруктуруВыполняемойКоманды(ВыполняемаяКоманда, НаименованиеОбработки)
// Ищем ссылку на обработку в справочнике по наименованию
ДопОбработкаСсылка = Справочники.ДополнительныеОтчетыИОбработки.НайтиПоНаименованию(НаименованиеОбработки);
Если ЗначениеЗаполнено(ДопОбработкаСсылка) Тогда
ВыполняемаяКоманда = Новый Структура;
// Заполняем обязательные поля из первой найденной команды (индекс 0)
ВыполняемаяКоманда.Вставить("Ссылка", ДопОбработкаСсылка);
ВыполняемаяКоманда.Вставить("Представление", ДопОбработкаСсылка.Команды[0].Представление);
ВыполняемаяКоманда.Вставить("Идентификатор", ДопОбработкаСсылка.Команды[0].Идентификатор);
ВыполняемаяКоманда.Вставить("ВариантЗапуска", ДопОбработкаСсылка.Команды[0].ВариантЗапуска);
ВыполняемаяКоманда.Вставить("ПоказыватьОповещение", ДопОбработкаСсылка.Команды[0].ПоказыватьОповещение);
ВыполняемаяКоманда.Вставить("Модификатор", ДопОбработкаСсылка.Команды[0].Модификатор);
ВыполняемаяКоманда.Вставить("ОбъектыНазначения", Неопределено);
ВыполняемаяКоманда.Вставить("Вид", ДопОбработкаСсылка.Вид);
ВыполняемаяКоманда.Вставить("ЭтоОтчет", Ложь);
Иначе
ВыполняемаяКоманда = Неопределено;
КонецЕсли;
КонецПроцедуры
Теперь рассмотрим, как инициировать выполнение этой команды в фоновом режиме. Использование ДлительныеОперации позволяет не блокировать интерфейс пользователя во время работы скрипта.
&НаКлиенте
Процедура ВыполнитьСинхронизацию(Команда)
вКоманда = Новый Структура;
ЗаполнитьСтруктуруВыполняемойКоманды(вКоманда, "Моя дополнительная обработка");
Если ЗначениеЗаполнено(вКоманда) Тогда
// Запускаем фоновое задание
ДлительнаяОперация = НачатьВыполнениеСервернойКомандыВФоне(вКоманда, УникальныйИдентификатор);
// Настраиваем параметры ожидания
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
ПараметрыОжидания.ТекстСообщения = "Выполняется команда обработки...";
ПараметрыОжидания.ВыводитьОкноОжидания = Истина;
ОповещениеОЗавершении = Новый ОписаниеОповещения("ПослеЗавершенияВыполнения", ЭтотОбъект, вКоманда);
ДлительныеОперацииКлиент.ОжидатьЗавершение(ДлительнаяОперация, ОповещениеОЗавершении, ПараметрыОжидания);
КонецЕсли;
КонецПроцедуры
Важно помнить, что серверный метод должен вызывать типовую процедуру БСП ДополнительныеОтчетыИОбработки.ВыполнитьКоманду. Именно она отвечает за распаковку внешней обработки во временное хранилище и вызов метода ВыполнитьКоманду из модуля обработки.
Если нам нужно не просто выполнить код, а предоставить пользователю интерфейс обработки, следует использовать метод ВыполнитьОткрытиеФормыОбработки. Проанализируем пример кода, который позволяет это сделать:
&НаКлиенте
Процедура ОткрытьФормуДопОбработки(Команда)
ВыполняемаяКоманда = Новый Структура;
// Предварительно заполняем структуру, как в предыдущем примере
ЗаполнитьСтруктуруВыполняемойКоманды(ВыполняемаяКоманда, "Название обработки с формой");
Если ВыполняемаяКоманда <> Неопределено Тогда
// Используем встроенный метод БСП для открытия формы
ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьОткрытиеФормыОбработки(ВыполняемаяКоманда, ЭтаФорма, Неопределено);
КонецЕсли;
КонецПроцедуры
Часто возникает вопрос: как работают регламентные задания и фоновые процессы в файловом варианте работы 1С? Выясним причину возможных сложностей. В файловой базе нет отдельного процесса сервера приложений, который бы управлял очередью заданий.
Рассмотрим важные правила для файловых баз:
/AllowExecuteScheduledJobs -Force. Это заставит данный сеанс работать в режиме менеджера заданий.Чтобы программный запуск прошел успешно, модуль самой внешней обработки должен быть написан в соответствии со стандартами БСП. В модуле объекта обязательно должна присутствовать экспортная процедура ВыполнитьКоманду.
Проанализируем пример такой процедуры внутри внешней обработки:
Процедура ВыполнитьКоманду(ИдентификаторКоманды, ПараметрыВыполнения) Экспорт
Если ИдентификаторКоманды = "МояКоманда1" Тогда
// Реализация логики
ЗаписатьВЛог("Команда выполнена успешно");
// Если нужно вернуть результат в вызывающий код:
Если ПараметрыВыполнения.Свойство("АдресРезультата") Тогда
СтруктураРезультата = Новый Структура("Статус, Сообщение", "ОК", "Данные обработаны");
ПоместитьВоВременноеХранилище(СтруктураРезультата, ПараметрыВыполнения.АдресРезультата);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Обратите внимание на Безопасный режим: Если ваша обработка должна работать с файловой системой или внешними API через HTTP, убедитесь, что в карточке регистрации обработки в системе снята галочка "Безопасный режим". При программном вызове ограничения безопасного режима применяются максимально строго, и код может завершиться ошибкой доступа.
В последних версиях БСП рекомендуется не заполнять структуру ВыполняемаяКоманда вручную. Вместо этого лучше использовать функцию ДополнительныеОтчетыИОбработки.КомандыДополнительнойОбработки(Ссылка). Это возвращает таблицу всех доступных команд обработки. Мы можем просто найти нужную строку по идентификатору и преобразовать её в структуру. Это гарантирует, что мы не забудем передать ни один важный параметр, требуемый текущей версией библиотеки.
Разберем, как это упрощает код:
&НаСервере
Функция ПолучитьПараметрыКоманды(СсылкаНаДопОбр, Идентификатор)
ТаблицаКоманд = ДополнительныеОтчетыИОбработки.КомандыДополнительнойОбработки(СсылкаНаДопОбр);
ПараметрыСтрока = ТаблицаКоманд.Найти(Идентификатор, "Идентификатор");
Результат = Новый Структура;
Для каждого Колонка Из ТаблицаКоманд.Колонки Цикл
Результат.Вставить(Колонка.Имя, ПараметрыСтрока[Колонка.Имя]);
КонецЦикла;
Результат.Вставить("Ссылка", СсылкаНаДопОбр);
Возврат Результат;
КонецФункции
Используя предложенные методы, вы сможете гибко интегрировать внешние обработки в общую логику вашей конфигурации, обеспечивая стабильную работу как в файловом, так и в клиент-серверном вариантах работы системы.