При разработке внешних печатных форм для конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как Управление торговлей 11, ERP 2 или Бухгалтерия предприятия 3.0, программисты часто сталкиваются с исключением: {ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль(236)}: В обработчике печати не был сформирован табличный документ для: [ИмяМакета]. Эта ошибка означает, что механизм печати вызвал процедуру формирования документа, но на выходе не получил заполненный объект ТабличныйДокумент. Разберем подробно причины этой проблемы и способы её решения.
Это самая распространенная ошибка, которую мы видим в представленном коде. Проанализируем ситуацию: в функции СведенияОВнешнейОбработке команда регистрируется с одним идентификатором, а в процедуре Печать проверяется совершенно другой. Система ищет в коллекции печатных форм именно тот идентификатор, который был нажат пользователем в меню «Печать».
Рассмотрим пример из кода автора. В функции регистрации указано:
НоваяКоманда.Идентификатор = "ПФНовый";
А в процедуре Печать мы видим проверку только для других макетов:
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ОтчетКомиссионера") Тогда
// Код формирования...
КонецЕсли;
Выясним причину ошибки: так как условие УправлениеПечатью.НужноПечататьМакет для идентификатора "ПФНовый" отсутствует, блок формирования документа просто пропускается. В результате в КоллекцияПечатныхФорм не записывается результат работы, и БСП выдает ошибку. Чтобы исправить это, необходимо добавить соответствующее условие:
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПФНовый") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ПФНовый", // Идентификатор должен совпадать!
"Новая печатная форма",
СформироватьНашТабличныйДокумент(СтруктураТипов, ОбъектыПечати, ПараметрыПечати)
);
КонецЕсли;
Вторая по частоте причина — логика формирования самого документа. Если функция СформироватьПечатнуюФорму... отрабатывает, но внутри запроса не найдено данных (например, документ пустой или не проведен), цикл вывода областей макета не запустится. Посмотрим, как это выглядит в коде:
Пока ДанныеПечати.Следующий() Цикл
// Если сюда не зашли, ТабличныйДокумент останется пустым
ТабличныйДокумент.Вывести(ОбластьМакета);
КонецЦикла;
Возврат ТабличныйДокумент;
Проанализируем ситуацию: если запрос вернул 0 строк, функция вернет абсолютно пустой объект ТабличныйДокумент. Механизм БСП интерпретирует это как ошибку формирования. Чтобы избежать этого, рекомендуется добавить проверку выборки и выводить пользователю предупреждение через ОбщегоНазначенияКлиентСервер.СообщитьПользователю, либо выводить хотя бы пустую «шапку» документа.
В современном коде 1С часто используется параметр ЭтоМногоязычнаяПечатнаяФорма = Истина. Рассмотрим фрагмент кода:
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"РасходнаяНакладная",
НСтр("ru='Расходная накладная'"),
СформироватьПечатнуюФормуРасходнаяНакладная(...),
, , ,
Истина // Параметр многоязычности
);
Если вы устанавливаете этот флаг, убедитесь, что в процедуру формирования корректно передаются ПараметрыВывода. Если внутри функции формирования используется КодЯзыкаПечать = ПараметрыВывода.КодЯзыкаДляМногоязычныхПечатныхФорм;, а этот параметр не заполнен, система может дать сбой при получении макета функцией УправлениеПечатью.МакетПечатнойФормы.
Многие начинающие разработчики считают, что внешнюю печатную форму (ВПФ) невозможно отладить, так как она загружается во временное хранилище. Однако это не так. Разберем основные способы:
Печать этой обработки. Теперь вы можете ставить точки останова и проверять значения переменных СтруктураТипов или КоллекцияПечатныхФорм..epf и объект ссылки прямо в режиме «1С:Предприятие» и запустить выполнение с возможностью отладки (если конфигуратор открыт).ОбщийМодуль.ДополнительныеОтчетыИОбработки, вы сможете подняться по стеку вызовов и увидеть, на каком этапе коллекция печатных форм осталась незаполненной.Чтобы ваша печатная форма работала стабильно, придерживайтесь следующей структуры в функции формирования:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
УстановитьПривилегированныйРежим(Истина);
ТабДок = Новый ТабличныйДокумент;
ТабДок.АвтоМасштаб = Истина;
// Получаем макет один раз вне цикла
Макет = ПолучитьМакет("МойМакет");
// Выполняем запрос к данным
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ... ГДЕ Ссылка В (&МассивОбъектов)";
Запрос.УстановитьПараметр("МассивОбъектов", МассивОбъектов);
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат ТабДок; // Или вывести текст "Нет данных для печати"
КонецЕсли;
// Начинаем вывод
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Заполнение параметров и вывод областей
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьШапка);
// Важно для БСП: фиксируем область печати для каждого объекта
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабДок, 1, ОбъектыПечати, Выборка.Ссылка);
КонецЦикла;
Возврат ТабДок;
КонецФункции
Важный момент: если вы используете УстановитьПривилегированныйРежим(Истина), помните, что при регистрации обработки в СведенияОВнешнейОбработке параметр БезопасныйРежим должен быть установлен в Ложь. В противном случае привилегированный режим будет игнорироваться, и запрос может не вернуть данные из-за отсутствия прав у текущего пользователя на определенные поля таблиц.
Подводя итог: если вы получили ошибку «не сформирован табличный документ», первым же делом сравните идентификатор в СведенияОВнешнейОбработке и в условии НужноПечататьМакет внутри процедуры Печать. В 90% случаев проблема кроется именно в опечатке или копировании кода из другой обработки без правки имен идентификаторов.