При переходе на новые релизы конфигурации 1С:Розница 2.3 (например, с версии 2.3.8 на 2.3.16 и выше) многие разработчики сталкиваются с неприятной ситуацией: отлаженные механизмы кастомизации печати ценников и этикеток перестают функционировать. Типичный сценарий — использование метода Оповестить для передачи параметров в общую форму печати с целью подмены макета или изменения логики формирования документа. Рассмотрим подробнее, почему это происходит и как адаптировать код под новые реалии платформы и Библиотеки стандартных подсистем (БСП).
Выясним причину, по которой привычный вызов ОбработкаОповещения в целевой форме перестает реагировать на события. В последних версиях 1С:Розница процесс подготовки печатных форм был переведен на рельсы асинхронного выполнения. Проанализируем ситуацию: когда пользователь нажимает кнопку печати, система инициирует фоновое задание для формирования табличного документа. В этот момент на экране появляется окно с надписью "Подготовка печатных форм".
Проблема заключается в том, что механизм Оповестить рассылает сообщения всем открытым формам. Однако, если в момент вызова метода Оповестить целевая форма (например, ОбщиеФормы.ПечатьДокументов) еще не успела полностью инициализироваться или находится в состоянии ожидания завершения фонового задания, обработчик события может быть проигнорирован. Как заметили участники обсуждения, если данных мало (например, один весовой товар) и окно подготовки не успевает появиться, оповещение "проскакивает" успешно. Но как только объем данных увеличивается и включается механизм длительных операций, связь разрывается.
Рассмотрим пример кода, который часто используется в обработке ПечатьЭтикетокИЦенников. Обратите внимание на то, как вызывается стандартная команда печати и где располагается ваше оповещение:
&НаКлиенте
Процедура Печать2(Команда)
// ... предварительные проверки выбора товаров ...
ПараметрыПечати = ПолучитьПараметрыПечати(РежимПечати);
// Стандартный вызов БСП
УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
"Обработка.ПечатьЭтикетокИЦенников",
РежимПечати,
ПараметрКоманды,
ЭтаФорма,
ПараметрыПечати);
// Попытка передать данные через оповещение
Оповестить("ПодменаМакета", Объект.Товары, ЭтаФорма);
КонецПроцедуры
В новых релизах процедура ВыполнитьКомандуПечати работает асинхронно. Это означает, что выполнение кода продолжается сразу после вызова команды, не дожидаясь открытия формы печати. Таким образом, метод Оповестить срабатывает в тот момент, когда форма печати документов еще даже не создана в памяти клиента. Естественно, ловить это событие некому.
Самый надежный и архитектурно правильный способ — отказаться от использования Оповестить в пользу передачи данных через структуру параметров самой печати. Метод ВыполнитьКомандуПечати принимает аргумент ПараметрыПечати. Все, что вы поместите в эту структуру, будет доступно в форме печати на протяжении всего жизненного цикла формирования документа.
Разберем по шагам, как это реализовать:
ПараметрыПечати.Пример модификации структуры параметров:
ПараметрыПечати = ПолучитьПараметрыПечати(РежимПечати);
// Добавляем свой флаг или данные напрямую
ПараметрыПечати.Вставить("СпециальныйРежимВесовогоТовара", Истина);
ПараметрыПечати.Вставить("ДанныеДляПодмены", Объект.Товары.Выгрузить());
Если вы все же решили оставить механизм оповещений, нам необходимо убедиться, что форма-приемник готова их обрабатывать. Рассмотрим, как выглядит ваш обработчик в расширении или кастомизированной форме ПечатьДокументов:
&НаКлиенте
Процедура РПЦОбработкаОповещенияПосле(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ПодменаМакета" Тогда
Для Каждого пТекШаблон Из НастройкиПечатныхФорм Цикл
// Логика поиска и подмены макета
пПодменитьМакетПечати("МАКЕТ_ВЕСКОД", ЭтотОбъект[пТекШаблон.ИмяРеквизита], Параметр);
КонецЦикла;
КонецЕсли;
КонецПроцедуры
Чтобы этот код сработал в условиях асинхронности, необходимо инициировать Оповестить не в процедуре нажатия кнопки, а в самой форме печати при ее создании или после завершения формирования документа. Однако это усложняет логику. Проанализируем ситуацию: гораздо эффективнее вызывать процедуру пПодменитьМакетПечати непосредственно из обработчика ПриОткрытии или в момент компоновки табличного документа, используя переданные ПараметрыПечати.
Проанализируем еще один важный нюанс. В конфигурации 1С:Розница 2.3 часто используется кэширование макетов. Если ваша логика подмены срабатывает после того, как БСП уже начала рендеринг документа в фоновом задании, визуальных изменений вы не увидите.
Советы для успешного внедрения изменений:
БлокироватьОкноВладельца, это может препятствовать доставке некоторых типов событий.Отладка фоновых заданий, чтобы увидеть, в какой момент происходит обращение к макетам на стороне сервера.Печать2 вы правильно инициализируете ПараметрыОткрытия. В новых релизах структура ПараметрыПечатиДляПринтераЭтикеток также может влиять на поведение формы.Подводя итог, можно сказать, что нестабильность Оповестить в новых версиях 1С — это прямое следствие борьбы за производительность интерфейса через асинхронность. Переход на передачу параметров через структуры БСП сделает ваше решение устойчивым к последующим обновлениям конфигурации.