Почему перестало срабатывать оповещение формы при печати в 1С:Розница 2.3 и как это исправить?

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

При переходе на новые релизы конфигурации 1С:Розница 2.3 (например, с версии 2.3.8 на 2.3.16 и выше) многие разработчики сталкиваются с неприятной ситуацией: отлаженные механизмы кастомизации печати ценников и этикеток перестают функционировать. Типичный сценарий — использование метода Оповестить для передачи параметров в общую форму печати с целью подмены макета или изменения логики формирования документа. Рассмотрим подробнее, почему это происходит и как адаптировать код под новые реалии платформы и Библиотеки стандартных подсистем (БСП).

Анализируем причину сбоя: конфликт с длительными операциями

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

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

Разбор программного кода вызова печати

Рассмотрим пример кода, который часто используется в обработке ПечатьЭтикетокИЦенников. Обратите внимание на то, как вызывается стандартная команда печати и где располагается ваше оповещение:


&НаКлиенте
Процедура Печать2(Команда)
    // ... предварительные проверки выбора товаров ...
    
    ПараметрыПечати = ПолучитьПараметрыПечати(РежимПечати);
    
    // Стандартный вызов БСП
    УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
        "Обработка.ПечатьЭтикетокИЦенников", 
        РежимПечати, 
        ПараметрКоманды, 
        ЭтаФорма, 
        ПараметрыПечати);
    
    // Попытка передать данные через оповещение
    Оповестить("ПодменаМакета", Объект.Товары, ЭтаФорма);
КонецПроцедуры

В новых релизах процедура ВыполнитьКомандуПечати работает асинхронно. Это означает, что выполнение кода продолжается сразу после вызова команды, не дожидаясь открытия формы печати. Таким образом, метод Оповестить срабатывает в тот момент, когда форма печати документов еще даже не создана в памяти клиента. Естественно, ловить это событие некому.

Решение №1: Использование структуры ПараметрыПечати

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

Разберем по шагам, как это реализовать:

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

Пример модификации структуры параметров:


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

Решение №2: Адаптация обработчика ОбработкаОповещения

Если вы все же решили оставить механизм оповещений, нам необходимо убедиться, что форма-приемник готова их обрабатывать. Рассмотрим, как выглядит ваш обработчик в расширении или кастомизированной форме ПечатьДокументов:


&НаКлиенте
Процедура РПЦОбработкаОповещенияПосле(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ПодменаМакета" Тогда
        Для Каждого пТекШаблон Из НастройкиПечатныхФорм Цикл
            // Логика поиска и подмены макета
            пПодменитьМакетПечати("МАКЕТ_ВЕСКОД", ЭтотОбъект[пТекШаблон.ИмяРеквизита], Параметр);
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры

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

Важные рекомендации по отладке

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

Советы для успешного внедрения изменений:

  1. Проверьте, не блокирует ли системное окно "Подготовка печатных форм" поток пользовательского интерфейса. Если вы используете БлокироватьОкноВладельца, это может препятствовать доставке некоторых типов событий.
  2. Используйте Отладка фоновых заданий, чтобы увидеть, в какой момент происходит обращение к макетам на стороне сервера.
  3. Убедитесь, что в процедуре Печать2 вы правильно инициализируете ПараметрыОткрытия. В новых релизах структура ПараметрыПечатиДляПринтераЭтикеток также может влиять на поведение формы.

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

← На главную