Как перевести команду внешней обработки в фоновый режим, чтобы избежать блокировки интерфейса в 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.

← На главную