Как перевести команду внешней обработки в фоновый режим, чтобы избежать блокировки интерфейса в 1С:Предприятие?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

При работе с конфигурациями 1С:Предприятие, особенно в режиме управляемых форм, мы часто сталкиваемся с ситуациями, когда выполнение длительных операций, таких как обработка больших объемов данных или создание множества документов, приводит к полной блокировке пользовательского интерфейса. Это значительно ухудшает удобство работы и может создавать ощущение "зависания" программы. Чтобы решить эту проблему, организация конвейера обработки задач поможет избежать долгих проведений, перенеся выполнение этих операций в фоновый режим и позволяя пользователю продолжить работу, пока система выполняет трудоемкую задачу.

Рассмотрим конкретный сценарий: у нас есть внешняя обработка, которая загружает данные из файла Excel в


ДеревоЗначений
на форме. Затем по нажатию кнопки запускается цикл, создающий по каждой строке дерева новый документ, например, "Реализация товаров и услуг". Именно эта операция создания документов становится проблемой, блокируя интерфейс.

Основной принцип работы с фоновыми заданиями

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

  1. Выполнение на сервере: Фоновые задания всегда выполняются на сервере 1С:Предприятия.
  2. Отсутствие привязки к форме: Фоновое задание не имеет прямого доступа к элементам формы, поэтому вся логика, работающая с данными формы, должна быть перенесена в модуль объекта обработки или в общий модуль.
  3. Экспортная процедура: Метод, который будет выполняться в фоновом режиме, должен быть экспортной процедурой модуля объекта обработки или общего модуля. Это позволяет системе 1С вызывать его извне.
  4. Передача данных: Все необходимые для работы фонового задания данные, которые были сформированы на форме или клиентской стороне, должны быть явно переданы в фоновое задание, часто через временное хранилище.

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

Решение 1: Использование `ДополнительныеОтчетыИОбработкиКлиент.ВыполнитьКомандуВФоне`

Этот способ является наиболее удобным, если ваша внешняя обработка уже загружена в справочник "Дополнительные отчеты и обработки". Для эффективного администрирования таких объектов может быть полезна групповая выгрузка и загрузка дополнительных обработок. Этот механизм позволяет запускать предопределенные команды обработки в фоновом режиме.

Шаг 1: Вынесение логики в экспортную процедуру модуля объекта обработки

Прежде всего, нам необходимо перенести основную логику создания документов из процедуры формы в экспортную процедуру, расположенную в модуле объекта нашей внешней обработки. Исходный код на форме выглядел следующим образом:


// В модуле формы внешней обработки
&НаКлиенте
Процедура СоздатьРТУ(Команда)
    СоздатьДокументыНаСервере;
КонецПроцедуры

&НаСервере
Процедура СоздатьДокументыНаСервере()
    ДЗ = РеквизитФормыВЗначение("ДЗф"); // ДЗф - дерево значений из формы
    Для каждого стр_ОРГ из ДЗ.Строки Цикл
        Организация = стр_орг.Организация;
        // ...
        СоздатьРТУНаСервере(Организация); // Пример вызова, который создает документ
        // ...
    КонецЦикла;
КонецПроцедуры

Мы должны выделить логику, которая непосредственно создает документы, в отдельную экспортную процедуру в модуле объекта обработки. Предположим, что наше дерево значений


ДЗф
необходимо для работы. Мы будем передавать его как параметр.

Создадим новую экспортную процедуру в модуле объекта нашей внешней обработки:


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

    // Опционально: можно вернуть какой-либо результат через ПараметрыФоновогоЗадания
    Если ПараметрыФоновогоЗадания <> Неопределено Тогда
        ПараметрыФоновогоЗадания.Результат = "Создание документов завершено успешно.";
        ПараметрыФоновогоЗадания.Сообщения = "Создано " + ДеревоЗначенийДляОбработки.Строки.Количество() + " документов реализации.";
    КонецЕсли;

КонецПроцедуры

В процессе выполнения полезно реализовать индикатор прогресса для отображения состояния задачи, чтобы пользователь понимал, какая часть данных уже обработана. Обратите внимание, что мы добавили параметр


ПараметрыФоновогоЗадания
. Он может быть использован для передачи информации о прогрессе или результате обратно вызывающей стороне.

Шаг 2: Создание команды в обработке

Теперь мы создадим команду в самой внешней обработке. В модуле формы, для обработчика команды, мы будем использовать специальный метод для запуска зарегистрированных команд.


// В модуле формы внешней обработки
&НаКлиенте
Процедура СоздатьРТУ(Команда)
    // Преобразуем дерево значений формы в значение для передачи на сервер
    ДЗ = РеквизитФормыВЗначение("ДЗф");

    // Помещаем данные во временное хранилище на сервере
    АдресДЗфВХранилище = ПоместитьДЗфВоВременноеХранилищеНаСервере(ДЗ);

    // Подготавливаем параметры для команды
    ПараметрыКоманды = Новый Структура("АдресДЗф", АдресДЗфВХранилище);

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

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

КонецПроцедуры

Решение 2: Использование `ДлительныеОперации.ВыполнитьВФоне`

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

Шаг 1: Подготовка экспортной процедуры в модуле объекта обработки

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

Шаг 2: Формирование параметров и запуск фонового задания из формы

Используя справочник по методам БСП, можно быстро найти и внедрить правильный код вызова серверных функций. Мы перепишем процедуру вызова на форме, чтобы она использовала


ДлительныеОперации.ВыполнитьВФоне
.


// В модуле формы внешней обработки
&НаКлиенте
Процедура СоздатьРТУ(Команда)
    ДЗ = РеквизитФормыВЗначение("ДЗф");
    АдресДЗфВХранилище = ПоместитьДЗфВоВременноеХранилищеНаСервере(ДЗ);

    // 3. Формируем параметры для вызова фонового задания
    ИмяФункцииИлиПроцедуры = "ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки";

    УИДДляРезультата = УникальныйИдентификатор;
    АдресВХранилищеРезультата = ПоместитьВоВременноеХранилище(Неопределено, УИДДляРезультата);

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

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

    ПараметрыЗадания.Вставить("ПараметрыВыполнения", ПараметрыПроцедурыМодуляОбъекта);

    // 4. Запускаем фоновое задание
    ДлительнаяОперация = ДлительныеОперации.ВыполнитьВФоне(
        ИмяФункцииИлиПроцедуры,
        ПараметрыЗадания,
        ПараметрыВыполнения
    );

    ПоказатьОповещениеПользователю(НСтр("ru = 'Запущено создание реализаций в фоновом режиме.'"));

КонецПроцедуры

Разберем ключевые моменты этого кода:

  1. Временное хранилище: Мы сначала передаем
    
    ДеревоЗначений
    
    с формы на сервер, чтобы избежать проблем с сериализацией большого объекта.
  2. Стандартные функции:
    
    ДлительныеОперации.ВыполнитьПроцедуруМодуляОбъектаОбработки
    
    — это стандартная функция БСП для запуска методов объектов.
  3. Оповещение о завершении: Использование
    
    ОписаниеОповещения
    
    позволяет корректно проинформировать пользователя об окончании процесса без блокировки его работы.

Передача данных в фоновое задание: подробнее

Одним из самых частых вопросов является передача данных из контекста формы. Лучший подход — использование временного хранилища. Мы помещаем данные на стороне формы, передаем только строковый адрес, а внутри фонового задания восстанавливаем значение. Это критически важно для производительности и стабильности системы.

Отладка фоновых заданий

Отладка кода в фоновом задании требует особого подхода, так как он выполняется в отдельном сеансе. Основные методы включают установку точек останова с последующим ручным подключением к сеансу через окно "Активные соединения", а также активное использование Журнала регистрации и специализированных инструментов, таких как "Консоль заданий" — для этого отлично подойдёт удобная консоль фоновых заданий для 1С.

Заключение

Перевод длительных операций в фоновый режим является стандартной и очень важной практикой при разработке на платформе 1С:Предприятие 8.3. Это не только улучшает пользовательский опыт, но и позволяет эффективно использовать ресурсы сервера. Мы рассмотрели два основных способа реализации: через команды дополнительных обработок и универсальный механизм длительных операций. Помните о необходимости выносить логику в экспортные процедуры и корректно передавать данные. Эти подходы позволят вам создавать более отзывчивые и производительные решения — а оперативно узнавать о сбоях в их работе поможет система мониторинга фоновых заданий с уведомлениями в Telegram.

← На главную