Как запустить процедуру из внешней обработки в фоновом задании с помощью БСП?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке внешних обработок для 1С, особенно тех, что выполняют ресурсоемкие задачи, такие как массовое удаление или изменение объектов, возникает необходимость перенести выполнение в фоновый режим. Это позволяет не блокировать интерфейс пользователя и продолжать работу в программе. Однако попытка использовать стандартный метод ФоновыеЗадания.Выполнить() для вызова процедуры из самой внешней обработки напрямую приводит к ошибкам. Давайте разберемся, почему так происходит и как правильно организовать фоновое выполнение с помощью механизмов Библиотеки стандартных подсистем (БСП).

Анализ проблемы: почему прямой вызов не работает

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


// Этот код НЕ будет работать для внешней обработки!
МассивОбъектов = ПолучитьМассивСсылокДляУдаления();
ПараметрыЗадания = Новый Массив;
ПараметрыЗадания.Добавить(МассивОбъектов);

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

При выполнении такого кода мы столкнемся с ошибкой, связанной с неверно переданными параметрами. Разберем основные причины, почему этот подход не работает:

  1. Контекст выполнения. Фоновое задание выполняется на сервере в совершенно новом, изолированном сеансе. В этом сеансе нет никакого "контекста" нашей открытой формы или объекта внешней обработки. Система просто не знает, где искать процедуру с именем УдалитьОбъекты, так как форма и ее модуль существуют только в клиентском сеансе пользователя.
  2. Требования к первому параметру. Метод ФоновыеЗадания.Выполнить ожидает в качестве первого параметра строковое представление метода в формате "ИмяОбщегоМодуля.ИмяПроцедуры". Процедура должна находиться в общем серверном модуле и быть экспортной. Вызвать процедуру из модуля формы или объекта обработки таким способом невозможно.
  3. Правильная передача параметров. Второй параметр метода Выполнить — это массив, каждый элемент которого будет передан в качестве отдельного параметра в вызываемую процедуру. Если ваша процедура ожидает один параметр (например, массив ссылок), то вам нужно создать массив, содержащий один этот элемент — ваш массив ссылок.

Итак, мы выяснили, что прямой вызов процедуры из внешней обработки через ФоновыеЗадания.Выполнить невозможен из-за архитектурных ограничений платформы. К счастью, в конфигурациях, использующих Библиотеку стандартных подсистем (БСП), есть специальный, предназначенный именно для таких задач механизм.

Решение: используем подсистему "Длительные операции" БСП

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

Шаг 1. Подготовка внешней обработки

Чтобы БСП могла корректно работать с нашей обработкой, она должна соответствовать определенным стандартам и быть зарегистрирована в системе.

1. Регистрация в системе. Ваша внешняя обработка должна быть подключена к информационной базе через стандартный механизм БСП: Администрирование -> Печатные формы, отчеты и обработки -> Дополнительные отчеты и обработки. Это стандартный способ интеграции внешних разработок в типовые конфигурации.

2. Размещение процедуры в модуле объекта. Процедура, которую вы хотите выполнить в фоновом режиме, должна находиться в модуле объекта вашей внешней обработки (не в модуле формы!). Она обязательно должна быть объявлена как экспортная (Экспорт).

Посмотрим на пример такой процедуры. Допустим, она принимает на вход массив ссылок для удаления.


&НаСервере
Процедура УдалитьОбъектыВФоне(МассивСсылок) Экспорт

    // Здесь размещается вся "тяжелая" логика
    // Например, итерация по массиву и удаление каждого объекта
    Для Каждого Ссылка Из МассивСсылок Цикл
        
        Попытка
            Объект = Ссылка.ПолучитьОбъект();
            Объект.Удалить();
        Исключение
            // Логирование ошибок удаления
            ЗаписьЖурналаРегистрации("УдалениеОбъектов", 
                                     УровеньЖурналаРегистрации.Ошибка,
                                     ,
                                     ,
                                     "Не удалось удалить объект: " + Ссылка);
        КонецПопытки;

    КонецЦикла;

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

Шаг 2. Вызов длительной операции из модуля формы

Теперь, когда у нас есть подготовленная процедура в модуле объекта, нам нужно правильно вызвать ее из модуля формы (например, по нажатию на кнопку). Для этого используется метод ДлительныеОперации.ВыполнитьВФоне.

Давайте разберем код вызова на примере.


&НаКлиенте
Процедура ВыполнитьУдалениеВФоне(Команда)

    // 1. Получаем массив ссылок для удаления
    МассивСсылокДляУдаления = ПолучитьМассивСсылок();
    Если МассивСсылокДляУдаления.Количество() = 0 Тогда
        Сообщить("Не выбраны объекты для удаления!");
        Возврат;
    КонецЕсли;

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

    // 5. Задаем текст, который будет виден пользователю во время выполнения
    ПараметрыВыполнения.Вставить("ТекстСообщения", "Выполняется удаление объектов...");
    
    // 6. Запускаем выполнение в фоновом задании
    ДлительныеОперацииКлиент.ВыполнитьВФоне(ПараметрыВыполнения);
    
КонецПроцедуры

Проанализируем ключевые моменты этого кода:

При желании можно настроить обработчик оповещения, который выполнится после завершения фонового задания, чтобы, например, обновить данные на форме или сообщить пользователю о результате. Для этого нужно передать в метод ВыполнитьВФоне второй параметр — описание оповещения.

Итог

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

← На главную