Как прервать длительное формирование отчета пользователем в 1С

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

При разработке отчетов без использования схемы компоновки данных (СКД), когда вывод в табличный документ осуществляется вручную через выборку, часто возникает задача предоставить пользователю возможность прервать длительный процесс. Однако стандартный метод платформы ОбработкаПрерыванияПользователя() срабатывает не всегда. Разберем основные причины такого поведения и рассмотрим надежные способы реализации прерывания формирования отчетов.

Почему не срабатывает ОбработкаПрерыванияПользователя

Метод ОбработкаПрерыванияПользователя() предназначен для проверки очереди системных сообщений: если пользователь нажал комбинацию клавиш прерывания (стандартно Ctrl + Break или Ctrl + Pause), платформа прерывает выполнение текущего алгоритма и вызывает исключение. Проанализируем, почему этот механизм может не сработать:

  1. Контекст выполнения: Метод доступен только на стороне клиента (толстый клиент, тонкий клиент, веб-клиент). Если вызов помещен в серверный модуль или серверную процедуру без контекста, платформа не сможет отследить действия пользователя.
  2. Аппаратные особенности и RDP: На многих современных клавиатурах и ноутбуках физическая клавиша Break отсутствует или требует нажатия функциональных сочетаний (например, Fn + B или Fn + Ctrl + Pause). Кроме того, при подключении через удаленный рабочий стол (RDP) клиентская операционная система может перехватывать или вовсе не транслировать скан-код прерывания в сессию 1С.
  3. Длительные операции на стороне СУБД: Метод проверяет нажатие клавиш исключительно в момент своего выполнения во встроенном языке 1С. Если 99% времени занимает выполнение запроса внутри метода Запрос.Выполнить(), нажать отмену не получится до тех пор, пока сервер баз данных полностью не вернет результат выборки.
  4. Ограничения веб-клиента: В браузере системные сочетания клавиш часто перехватываются самим веб-обозревателем и не передаются в контекст приложения.

Способ 1. Оптимальный вызов ОбработкаПрерыванияПользователя в цикле

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

Обратите внимание: вызов ОбработкаПрерыванияПользователя() на каждой итерации при сотнях тысяч строк создает существенные накладные расходы на постоянный опрос системных событий. Чтобы не снижать общую скорость вывода, вызовем проверку порциями, например, каждую 100-ю или 1000-ю итерацию. Посмотрим на пример реализации:


СчетчикИтераций = 0;

Пока Выборка.Следующий() Цикл
    СчетчикИтераций = СчетчикИтераций + 1;
    
    // Проверяем прерывание порциями для сохранения высокой производительности
    Если СчетчикИтераций % 1000 = 0 Тогда
        ОбработкаПрерыванияПользователя();
    КонецЕсли;
    
    // Вывод области макета в табличный документ
    ОбластьСтрока.Параметры.Заполнить(Выборка);
    ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;

Способ 2. Выполнение отчета в фоновом задании с кнопкой отмены

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

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

  1. На клиенте по нажатию кнопки «Сформировать» запускается фоновое задание, выполняющее процедуру компоновки или ручного вывода отчета на сервере.
  2. Клиентскому приложению возвращается идентификатор фонового задания, после чего открывается модальное или немодальное окно состояния ожидания с кнопкой «Отмена».
  3. При нажатии пользователем кнопки отмены на клиенте вызывается метод отмены фонового задания:

&НаСервере
Процедура ОтменитьФормированиеОтчетаНаСервере(ИдентификаторЗадания)
    Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
    Если Задание <> Неопределено И Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
        Задание.Отменить();
    КонецЕсли;
КонецПроцедуры

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

Способ 3. Пошаговая клиентская обработка через обработчик ожидания

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

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

← На главную