Разработка внешних обработок в экосистеме 1С:Предприятие 8.3 часто начинается с создания изолированного инструмента. На этом этапе всё работает идеально: индикатор прогресса (progressbar) плавно движется, фоновое задание выполняется, пользователь видит результат. Однако при попытке интегрировать эту обработку в типовую конфигурацию через расширение (например, вызывая её по кнопке в документе или справочнике) разработчики часто сталкиваются с тем, что визуальная часть индикатора «замирает», хотя сам алгоритм продолжает успешно работать в фоне. Проанализируем эту ситуацию и разберем по шагам, как восстановить работоспособность индикатора.
Прежде чем искать ошибку в коде, необходимо убедиться, что мы вообще видим то, что происходит на сервере. Когда обработка запускается автономно, контекст выполнения более прозрачен. Но при вызове из расширения фоновое задание может запускаться в отдельном сеансе, который не перехватывается отладчиком по умолчанию. Рассмотрим, как правильно настроить среду для отладки внешних обработок и поиска проблемы.
Для корректного анализа выполнения кода в фоновом задании выполним следующие действия:
Если точка останова не срабатывает, это первый сигнал того, что код выполняется в контексте, который сервер 1С считает «чужим» или небезопасным. Проанализируем, почему это происходит при использовании расширений.
Выясним причину, по которой индикатор перестает обновляться. В типовых конфигурациях (БП 3.0, УТ 11, ЗУП 3.1) для отображения прогресса используется подсистема БСП «Длительные операции». Когда вы открываете форму обработки через стандартный механизм «Дополнительные отчеты и обработки», система сама подготавливает окружение. Но если вы вызываете форму программно из расширения через ОткрытьФорму(), цепочка передачи параметров может разорваться.
Рассмотрим пример типичной ошибки программного вызова:
// В коде расширения
ПараметрыФормы = Новый Структура;
ОткрытьФорму("ВнешняяОбработка.МояОбработка.Форма.Форма", ПараметрыФормы);
В этом случае форма открывается без привязки к владельцу и без необходимых ключей параметров, которые ожидает БСП для инициализации механизма отслеживания прогресса. Посмотрим на пример того, как должен выглядеть правильный вызов длительной операции, чтобы индикатор имел связь с клиентской частью:
// На сервере инициализируем выполнение
РезультатЗапуска = ДлительныеОперации.ЗапуститьВыполнениеВФоне(
УникальныйИдентификатор,
"МояОбработка.ВыполнитьДействие",
ПараметрыВыполнения,
"Текст описания задачи"
);
// Передаем данные на клиент для запуска индикатора
СтруктураПараметров = Новый Структура;
СтруктураПараметров.Вставить("ИдентификаторЗадания", РезультатЗапуска.ИдентификаторЗадания);
СтруктураПараметров.Вставить("АдресХранилища", РезультатЗапуска.АдресХранилища);
Разберем ситуацию, когда фоновое задание работает, но индикатор на форме стоит на месте. Визуальное обновление progressbar на управляемой форме в 1С всегда завязано на метод ПодключитьОбработчикОжидания(). Это основы того, как работают фоновые задания на базовом уровне: метод заставляет клиентское приложение периодически «опрашивать» сервер о состоянии выполнения задачи.
Проанализируем алгоритм работы индикатора:
Идентификатор.ПодключитьОбработчикОжидания("ПроверитьСостояниеЗадания", 1).ПроверитьСостояниеЗадания клиент обращается к серверу, получает процент выполнения и обновляет реквизит формы, связанный с индикатором.Если вы открываете форму обработки из расширения, часто забывают вызвать инициализирующую процедуру ПриОткрытии или OnOpen программно, либо в коде расширения перехватываются события, которые блокируют запуск таймера. Убедитесь, что в коде формы присутствует вызов:
&НаКлиенте
Процедура ПриОткрытии(Отказ)
// Если задание уже запущено или должно быть запущено
ПодключитьОбработчикОжидания("Подключаемый_ПроверитьВыполнениеЗадания", 2, Ложь);
КонецПроцедуры
При использовании расширений платформа 1С часто принудительно включает Безопасный режим для программно создаваемых объектов. В этом режиме работа с фоновыми заданиями и временным хранилищем существенно ограничена. Если ваша обработка пытается передать данные о прогрессе через ПоместитьВоВременноеХранилище, а форма пытается их прочитать, находясь в разных контекстах безопасности, индикатор не получит данных.
Чтобы решить эту проблему, полезно провести анализ расширения на наличие ошибок, связанных с вызовом процедур в разных контекстах. Также можно попробовать явно отключить безопасный режим при создании объекта обработки, если это допустимо политикой безопасности компании:
// Пример создания объекта без безопасного режима (только для доверенных операций)
ОбъектОбработки = ВнешниеОбработки.Создать(ИмяФайла, Ложь);
Однако правильнее будет использовать методы БСП ДлительныеОперации.СообщитьПрогресс(), так как они спроектированы для работы в условиях различных уровней доступа.
Выясним, не происходит ли выполнение «долгой операции» в том же потоке, что и отрисовка формы. Если ваш код в расширении просто вызывает серверный метод обработки, который крутится в цикле Для ... Цикл, то пока этот цикл не завершится, интерфейс 1С будет «заморожен». Индикатор не сдвинется, так как у клиентского приложения нет процессорного времени на перерисовку графических элементов.
Решение здесь только одно: асинхронное выполнение длительных операций через фоновое задание. Используйте стандартную форму ожидания БСП:
ПараметрыОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтаФорма);
ПараметрыОжидания.ТекстСообщения = "Пожалуйста, подождите...";
ПараметрыОжидания.ВыводитьПрогрессВыполнения = Истина;
ДлительныеОперацииКлиент.ОжидатьЗавершение(РезультатЗапуска, ПараметрыОжидания);
Подводя итог, отметим, что «неработающий индикатор» — это всегда симптом разрыва связи между серверным процессом и клиентским таймером обновления. При работе через расширение важно:
ДлительныеОперации), а не самописные циклы с паузами.УникальныйИдентификатор формы в фоновое задание, чтобы сервер знал, кому «отвечать».Следуя этим шагам, мы обеспечим стабильную работу индикатора прогресса и корректный пользовательский опыт при работе с вашими расширениями в 1С.