Как реализовать индикацию прогресса во внешней обработке на управляемых формах 1С 8.3

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

Переход с обычных форм на управляемые часто вызывает трудности у разработчиков, особенно когда речь заходит об интерактивных элементах, таких как полоса прогресса. В обычных формах мы могли напрямую обращаться к элементам формы из любого места кода. В управляемом приложении ситуация иная: выполнение кода жестко разделено на клиент и сервер. Серверный код (особенно в модуле объекта) «не видит» форму, а клиент не может напрямую получить состояние серверного процесса без дополнительных механизмов.

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

Способ 1. Использование метода Состояние на клиенте

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

Разберем пример кода:


&НаКлиенте
Процедура ЗапуститьОбработку(Команда)
    
    // Предположим, у нас есть список объектов для обработки
    ВсегоОбъектов = Объект.СписокДокументов.Количество();
    ТекущийИндекс = 0;
    
    Для Каждого Стр Из Объект.СписокДокументов Цикл
        ТекущийИндекс = ТекущийИндекс + 1;
        
        // Формируем процент выполнения
        Процент = (ТекущийИндекс / ВсегоОбъектов) * 100;
        
        // Выводим информацию в системную полосу состояния
        Состояние("Обработка документов...", Процент, "Обрабатывается: " + Стр.Ссылка);
        
        // Вызываем серверную процедуру для обработки конкретного объекта
        ОбработатьОбъектНаСервере(Стр.Ссылка);
    КонецЦикла;
    
КонецПроцедуры

Важные нюансы: этот метод эффективен только в том случае, если серверная процедура ОбработатьОбъектНаСервере выполняется достаточно быстро. Если же внутри серверного вызова происходит длительный процесс (например, проведение тысяч документов), интерфейс «зависнет», и полоса прогресса не будет обновляться до завершения всего серверного вызова. Именно поэтому для длительных серверных расчетов нам нужны фоновые задания.

Способ 2. Подсистема «Длительные операции» (БСП)

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

Проанализируем алгоритм работы:

  1. Клиент запускает фоновое задание через БСП.
  2. Серверный код в модуле объекта выполняет работу и периодически вызывает ДлительныеОперации.СообщитьПрогресс.
  3. Клиентская форма «слушает» состояние задания и обновляет индикатор.

Реализация в модуле объекта:


Процедура ВыполнитьДлительнуюОперацию(Параметры, АдресРезультата) Экспорт
    
    Выборка = Параметры.Выборка;
    Всего = Выборка.Количество();
    Счетчик = 0;
    
    Пока Выборка.Следующий() Цикл
        // Основная логика обработки
        ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();
        // ... (код обработки)
        
        Счетчик = Счетчик + 1;
        Процент = Цело(Счетчик / Всего * 100);
        
        // Передаем данные о прогрессе в систему
        ТекстСообщения = "Обработано документов: " + Счетчик + " из " + Всего;
        ДлительныеОперации.СообщитьПрогресс(Процент, ТекстСообщения);
    КонецЦикла;
    
КонецПроцедуры

Реализация в модуле формы:


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

&НаКлиенте
Процедура ОбработкаПрогресса(Прогресс, ДополнительныеПараметры) Экспорт
    Если Прогресс = Неопределено Тогда
        Возврат;
    КонецЕсли;
    // Здесь можно вручную обновить свои реквизиты на форме, 
    // если не используется стандартное окно БСП
    Элементы.ИндикаторПрогресса.Значение = Прогресс.Процент;
    Элементы.НадписьСостояние.Заголовок = Прогресс.Текст;
КонецПроцедуры

Способ 3. Использование Временного хранилища (без БСП)

Если использование БСП невозможно или ограничено, мы можем реализовать механизм обмена данными самостоятельно через ВременноеХранилище и ПодключитьОбработчикОжидания.

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

Посмотрим на шаги реализации:

  1. При старте формируем уникальный УникальныйИдентификатор (UID).
  2. Запускаем фоновое задание, передавая ему этот UID.
  3. На форме включаем обработчик ожидания (например, каждые 2 секунды).
  4. В фоновом задании на сервере записываем структуру с процентом во временное хранилище по адресу UID.
  5. В обработчике ожидания на клиенте читаем данные из хранилища и обновляем форму.

Пример записи прогресса на сервере:


ПрогрессСтруктура = Новый Структура("Процент, Текст", 45, "Загрузка данных...");
ПоместитьВоВременноеХранилище(ПрогрессСтруктура, АдресХранилища);

Пример чтения на клиенте (в обработчике ожидания):


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

&НаКлиенте
Процедура ОбработчикОжидания()
    ДанныеПрогресса = ПолучитьПрогрессНаСервере();
    Если ДанныеПрогресса <> Неопределено Тогда
        ПроцентВыполнения = ДанныеПрогресса.Процент;
        СостояниеВыполнения = ДанныеПрогресса.Текст;
    КонецЕсли;
КонецПроцедуры

Особенности работы во внешних обработках

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

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

Выводы и рекомендации

Мы рассмотрели три принципиально разных подхода к индикации процесса. Для быстрого решения «на коленке» достаточно метода Состояние() на клиенте в цикле. Для профессиональной разработки в современных конфигурациях (БП 3.0, УТ 11, ERP) настоятельно рекомендуем использовать ДлительныеОперации.СообщитьПрогресс, так как это обеспечивает единообразный интерфейс и надежную работу в многопользовательской среде.

При использовании Платформы 8.3.26 и выше, обратите внимание на новый механизм УведомленияКлиента, который позволяет серверу отправлять данные на клиент асинхронно без использования обработчиков ожидания, что значительно снижает нагрузку на сеть и сервер.

← На главную