В практике программирования на платформе 1С:Предприятие 8.3 (особенно при использовании Библиотеки стандартных подсистем — БСП) разработчики часто сталкиваются с ситуацией, когда при нажатии на кнопку печати система выдает лаконичное сообщение: «Печатная форма недоступна». Рассмотрим подробнее, почему это происходит, как проанализировать ситуацию и какие шаги предпринять для исправления кода. Чтобы избежать подобных программных ошибок, можно использовать конструктор печатных форм 1С в пользовательском режиме.
Прежде всего, разберем принцип работы подсистемы печати. Когда пользователь нажимает кнопку «Печать», срабатывает обработчик, который обращается к менеджеру объекта (документа или справочника) и вызывает экспортную функцию Печать. Эта функция должна заполнить коллекцию печатных форм табличными документами.
Ошибка «Печатная форма недоступна» генерируется стандартными модулями БСП в тех случаях, когда:
Неопределено.Проанализируем процедуру ДобавитьКомандыПечати. Именно здесь мы сообщаем системе, какие кнопки должны появиться в меню «Печать». Важно, чтобы Идентификатор команды в этой процедуре в точности совпадал с тем, который мы будем проверять в функции Печать. Посмотрим на пример кода:
Процедура ДобавитьКомандыПечати(КомандыПечати) Экспорт
// Команда для Техкарты
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.Идентификатор = "МакетТехКарта";
КомандаПечати.Представление = НСтр("ru = 'Тех. карта'");
КомандаПечати.Обработчик = "УправлениеПечатьюБПКлиент.ВыполнитьКомандуПечати";
КомандаПечати.Порядок = 10;
// Команда для Заявки
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.Идентификатор = "Макет"; // Обратите внимание на этот ID
КомандаПечати.Представление = НСтр("ru = 'Заявка'");
КомандаПечати.Обработчик = "УправлениеПечатьюБПКлиент.ВыполнитьКомандуПечати";
КомандаПечати.Порядок = 20;
КонецПроцедуры
Если в процедуре регистрации вы указали идентификатор "Макет", а в коде формирования документа будете искать "МакетЗаявки", система просто пропустит блок формирования, и мы получим обсуждаемую ошибку.
Выясним, как менеджер объекта обрабатывает запрос на печать. Проанализируем типичную структуру функции Печать:
Функция Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Проверяем, нужно ли печатать Техкарту
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "МакетТехКарта") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "МакетТехКарта", "Тех. карта",
ОформлениеТехКарты(МассивОбъектов, ОбъектыПечати));
КонецЕсли;
// Проверяем, нужно ли печатать Заявку
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "Макет") Тогда
ТабДокЗаявка = ОформлениеЗаявки(МассивОбъектов, ОбъектыПечати);
// Важный момент: если ОформлениеЗаявки вернет Неопределено,
// форма будет считаться недоступной
Если ТабДокЗаявка <> Неопределено Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "Макет", "Заявка", ТабДокЗаявка);
КонецЕсли;
КонецЕсли;
ОбщегоНазначенияБП.ЗаполнитьДополнительныеПараметрыПечати(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
КонецФункции
Важный совет: Если одна форма печатается (например, Техкарта), а вторая нет (Заявка), значит, проблема локализована именно в функции формирования конкретного документа — в нашем случае ОформлениеЗаявки.
Разберем наиболее частую причину: пустой результат запроса. Если ваш запрос к базе данных не находит записей для переданного массива объектов, цикл вывода областей в табличный документ не запустится. В итоге функция вернет «пустой лист», который БСП не сможет отобразить.
Рассмотрим пример функции с запросом:
Функция ОформлениеЗаявки(МассивОбъектов, ОбъектыПечати) Экспорт
ТабДок = Новый ТабличныйДокумент;
Макет = Документы.ЗаявкаЦифровая_ПР.ПолучитьМакет("Макет");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
Запрос.Текст =
"ВЫБРАТЬ
| СтрокаЗаявки.Наименование КАК Наименование,
| СтрокаЗаявки.Количество КАК Количество,
| СтрокаЗаявки.Владелец КАК Ссылка
|ИЗ
| Документ.СтрокаЗаявки_ПР КАК СтрокаЗаявки
|ГДЕ
| СтрокаЗаявки.Владелец В(&МассивОбъектов)";
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
// Если данных нет, ТабДок останется пустым.
// Для отладки можно вывести сообщение или бросить исключение
// ВызватьИсключение "Запрос для печати не вернул данных!";
Возврат Неопределено;
КонецЕсли;
// ... далее идет заполнение ТабДок ...
Возврат ТабДок;
КонецФункции
Посмотрим, какие ошибки часто встречаются в тексте запроса. Проверьте условия в секции ГДЕ. Например, если вы печатаете документ, а данные ищете в его табличной части (которая представлена отдельным объектом или подчиненным справочником), убедитесь, что поле связи (например, Владелец) действительно содержит ссылки из МассивОбъектов.
Проанализируем ситуацию, когда печать выполняется на сервере в фоновом задании. В этом случае привычный метод Сообщить() не выведет текст на экран пользователя. Сообщения просто «исчезнут».
Чтобы эффективно отладить код в таких условиях, рекомендуем использовать следующие приемы:
ВызватьИсключение "Текст ошибки" прервет выполнение и выведет диалоговое окно с вашим текстом даже при фоновой печати.ЗаписьЖурналаРегистрации, чтобы проверить значения переменных на сервере.Выясним, насколько критичными могут быть опечатки. В практике разработчиков бывают случаи, когда переменная называется СуммаМПЗ (материалы), но в одном месте кода случайно написано СуммаМП3 (цифра три вместо буквы З). Визуально это почти незаметно, но для программы это разные переменные. Если такая переменная используется в условии вывода области, область может просто не вывестись, что приведет к пустому табличному документу.
Также проверьте, что все области макета, которые вы пытаетесь получить через Макет.ПолучитьОбласть("ИмяОбласти"), действительно существуют в макете с такими именами. Если имя области указано неверно, выполнение прервется с ошибкой, которая в интерфейсе может выглядеть как «Печатная форма недоступна».
Подведем итог. Если вы столкнулись с этой проблемой, выполните проверку по чек-листу:
ДобавитьКомандыПечати и Печать.СтрокаМассива.Проведен и выводите пользователю понятное предупреждение через ТекстОшибки.ТабличныйДокумент, а не Неопределено (за исключением случаев, когда печать действительно невозможна).Следуя этим шагам, мы сможем быстро найти «узкое место» в коде и вернуть пользователям возможность полноценной работы с печатными формами системы.