Почему не работает внешняя печатная форма из формы элемента справочника и как это исправить?

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

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

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем внутренние механизмы Библиотеки стандартных подсистем (БСП) и рассмотрим практические способы ее решения.

Выясняем причину: почему «молчит» отладчик?

Если при попытке печати из формы элемента справочника программа не реагирует, а точка останова внутри модуля объекта внешней печатной формы игнорируется, это означает одну простую вещь: выполнение прерывается на клиенте еще до вызова серверного метода печати. Управление просто не доходит до вашей обработки.

Давайте проанализируем логику работы подсистемы «Печать» БСП в управляемом приложении. При нажатии на кнопку печати в форме элемента управление передается общему модулю клиентской логики (например, УправлениеПечатьюСлужебныйКлиент или ПодключаемыеКомандыКлиент). Перед тем как отправить объект на печать, система обязана выполнить ряд стандартных проверок:

  1. Проверить, изменен ли объект на форме, и предложить пользователю записать его.
  2. Для документов — проверить, проведен ли документ, поскольку печать непроведенных документов часто ограничивается бизнес-логикой системы (параметр ПроверкаПроведенияПередПечатью).

В некоторых релизах БСП (особенно в конфигурациях линейки ERP 2.5 / Комплексная автоматизация 2.5 на определенных этапах обновлений) разработчики 1С допустили досадную ошибку. Код проверки проведенности обращается напрямую к свойству объекта формы через точку:

Форма.Объект.Проведен

Так как у справочников реквизит Проведен отсутствует в принципе, платформа выбрасывает исключение «Поле объекта не обнаружено (Проведен)». В режиме предприятия эта ошибка может подавляться платформой или выводиться в неявном виде, прерывая дальнейшее выполнение скрипта. Именно поэтому вызов серверной процедуры Печать вашей ВПФ блокируется на корню.

---

Способ 1. Исправление ошибки через расширение конфигурации (Рекомендуемый)

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

Рассмотрим пример создания «заплатки» в расширении для общего модуля УправлениеПечатьюСлужебныйКлиент:


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

Такой подход полностью решает проблему для всех справочников системы разом, не требуя переделки самих внешних печатных форм.

---

Способ 2. Обходной путь во внешней печатной форме (без изменения конфигурации)

Если база находится на строгой поддержке во фреше (облаке) или регламент компании запрещает установку расширений, проблему можно обойти непосредственно внутри самой ВПФ. Для этого нам нужно уйти от стандартного серверного вызова команды печати, который спотыкается на проверках БСП.

Вместо типа команды ВызовСерверногоМетода мы настроим команду на ВызовКлиентскогоМетода (или открытие вспомогательной формы).

Разберем этот сценарий по шагам:

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

Посмотрим на пример реализации регистрации такой команды в модуле объекта ВПФ:


Функция СведенияОВнешнейОбработке() Экспорт
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки);
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма;
    ПараметрыРегистрации.Наименование = "Печать договора контрагента";
    ПараметрыРегистрации.Версия = "1.1";
    ПараметрыРегистрации.БезопасныйРежим = Ложь;
    
    ПараметрыРегистрации.Назначение.Добавить("Справочник.ДоговорыКонтрагентов");
    
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = "Договор (внешняя форма)";
    НоваяКоманда.Идентификатор = "ПечатьДоговораКлиент";
    // Указываем запуск клиентского метода вместо серверного
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода;
    НоваяКоманда.Модификатор = "ПечатьMXL";
    
    Возврат ПараметрыРегистрации;
КонецФункции

В модуле вспомогательной клиентской формы обработки пишем следующий код:


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

---

Шаблон современной и лаконичной регистрации ВПФ

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

Давайте рассмотрим чистый и современный шаблон модуля объекта внешней печатной формы для справочника, который стабильно работает в актуальных версиях БСП:


Функция СведенияОВнешнейОбработке() Экспорт
    // Инициализируем структуру регистрации через API БСП
    ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(СтандартныеПодсистемыСервер.ВерсияБиблиотеки);
    
    ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма;
    ПараметрыРегистрации.Версия = "1.0";
    ПараметрыРегистрации.БезопасныйРежим = Истина;
    
    // Указываем справочник в качестве объекта назначения
    ПараметрыРегистрации.Назначение.Добавить("Справочник.ДоговорыКонтрагентов");
    
    // Создаем команду печати
    НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
    НоваяКоманда.Представление = НСтр("ru = 'Печать договора (внешняя)'");
    НоваяКоманда.Идентификатор = "ВнешняяПечатьДоговора";
    НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода;
    НоваяКоманда.Модификатор = "ПечатьMXL";
    
    Возврат ПараметрыРегистрации;
КонецФункции

Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ВнешняяПечатьДоговора") Тогда
        
        ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
        
        УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
            КоллекцияПечатныхФорм, 
            "ВнешняяПечатьДоговора", 
            НСтр("ru = 'Печать договора'"), 
            ТабличныйДокумент
        );
        
    КонецЕсли;
    
КонецПроцедуры

Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
    
    ТабличныйДокумент = Новый ТабличныйДокумент;
    ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_ДОГОВОРА";
    
    Макет = ПолучитьМакет("Макет");
    ОбластьЗаголовка = Макет.ПолучитьОбласть("Заголовок");
    
    Для Каждого СсылкаНаДоговор Из МассивОбъектов Цикл
        // Заполняем параметры области макета данными справочника
        ОбластьЗаголовка.Параметры.НомерДоговора = СсылкаНаДоговор.Номер;
        ОбластьЗаголовка.Параметры.ДатаДоговора  = СсылкаНаДоговор.Дата;
        
        ТабличныйДокумент.Вывести(ОбластьЗаголовка);
    КонецЦикла;
    
    Возврат ТабличныйДокумент;
    
КонецФункции

---

Практические советы по отладке внешних печатных форм

Для того чтобы оперативно выявлять подобные архитектурные проблемы платформы или БСП, рекомендуем придерживаться следующих правил при отладке внешних обработок:

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

← На главную