При разработке отчетов без использования схемы компоновки данных (СКД), когда вывод в табличный документ осуществляется вручную через выборку, часто возникает задача предоставить пользователю возможность прервать длительный процесс. Однако стандартный метод платформы ОбработкаПрерыванияПользователя() срабатывает не всегда. Разберем основные причины такого поведения и рассмотрим надежные способы реализации прерывания формирования отчетов.
Метод ОбработкаПрерыванияПользователя() предназначен для проверки очереди системных сообщений: если пользователь нажал комбинацию клавиш прерывания (стандартно Ctrl + Break или Ctrl + Pause), платформа прерывает выполнение текущего алгоритма и вызывает исключение. Проанализируем, почему этот механизм может не сработать:
Запрос.Выполнить(), нажать отмену не получится до тех пор, пока сервер баз данных полностью не вернет результат выборки.Если вывод данных выполняется на клиенте в толстом или тонком клиенте, вызов проверки прерывания обязательно должен находиться внутри цикла обхода выборки или строк дерева/таблицы значений.
Обратите внимание: вызов ОбработкаПрерыванияПользователя() на каждой итерации при сотнях тысяч строк создает существенные накладные расходы на постоянный опрос системных событий. Чтобы не снижать общую скорость вывода, вызовем проверку порциями, например, каждую 100-ю или 1000-ю итерацию. Посмотрим на пример реализации:
СчетчикИтераций = 0;
Пока Выборка.Следующий() Цикл
СчетчикИтераций = СчетчикИтераций + 1;
// Проверяем прерывание порциями для сохранения высокой производительности
Если СчетчикИтераций % 1000 = 0 Тогда
ОбработкаПрерыванияПользователя();
КонецЕсли;
// Вывод области макета в табличный документ
ОбластьСтрока.Параметры.Заполнить(Выборка);
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
В современных конфигурациях на управляемых формах стандартным подходом является формирование отчетов в фоновом режиме через механизм длительных операций. Это позволяет избежать зависания клиентского интерфейса и дает возможность в любой момент остановить операцию по нажатию кнопки на форме.
Разберем по шагам логику реализации фонового формирования с возможностью отмены:
&НаСервере
Процедура ОтменитьФормированиеОтчетаНаСервере(ИдентификаторЗадания)
Задание = ФоновыеЗадания.НайтиПоУникальномуИдентификатору(ИдентификаторЗадания);
Если Задание <> Неопределено И Задание.Состояние = СостояниеФоновогоЗадания.Активно Тогда
Задание.Отменить();
КонецЕсли;
КонецПроцедуры
Такой подход гарантирует, что пользователь сможет в один клик мыши остановить процесс независимо от типа клавиатуры, используемого RDP-клиента или браузера.
Если алгоритм формирования принципиально реализован на стороне клиента без использования фоновых заданий, можно разбить длительный процесс на порции и выполнять их последовательно через обработчик ожидания.
Для этого в цикле обрабатывается заданное количество записей (например, по 500 строк), после чего управление временно возвращается платформе с помощью метода ПодключитьОбработчикОжидания() с минимальным интервалом (0.1 секунды). В паузах между выполнением порций интерфейс 1С остается полностью отзывчивым, благодаря чему на форме остается активной стандартная кнопка «Прервать», устанавливающая флаг отмены для остановки дальнейших вызовов обработчика.