При разработке внешних печатных форм (ВПФ) для систем на базе 1С:Предприятие 8.3 программисты часто сталкиваются с ситуацией, когда при тестировании из консоли или через тестовую форму всё работает идеально, но после подключения в справочник «Дополнительные отчеты и обработки» система выдает критическую ошибку: «В обработчике печати не был сформирован табличный документ». Рассмотрим подробно причины возникновения этой проблемы и разберем по шагам способы её решения.
Проанализируем ситуацию, когда запрос печатной формы возвращает пустой результат или значения NULL в вычисляемых полях. В языке запросов 1С любое арифметическое действие с NULL (например, Количество * NULL) приводит к результату NULL. Если логика формирования табличного документа опирается на выборку, которая оказывается пустой, цикл обхода данных не выполняется, и метод возвращает пустой ТабличныйДокумент.
Для решения этой проблемы необходимо использовать функцию ЕСТЬNULL. Разберем пример кода в запросе, который часто становится источником ошибки:
// Неправильно: если цена не установлена, Сумма будет NULL
| ПоступлениеТоваровУслуг.Количество * ЦеныНоменклатурыСрезПоследних.Цена КАК Сумма
// Правильно: заменяем потенциальный NULL на ноль
| ЕСТЬNULL(ПоступлениеТоваровУслуг.Количество * ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Сумма
Выясним причину, почему это критично именно для внешних форм. При обычном открытии через тестовую форму вы можете передавать конкретную ссылку, для которой данные точно есть. Однако при работе в составе конфигурации через БСП (Библиотеку стандартных подсистем) механизм может передавать массив объектов, и если хотя бы по одному из них данные не соберутся корректно, система может прервать формирование коллекции печатных форм.
Рассмотрим структурное различие между обычной обработкой и ВПФ. Многие начинающие разработчики совершают ошибку, размещая основной код формирования печатной формы в модуле формы обработки. Это удобно для отладки, но абсолютно недопустимо для механизмов БСП.
Важно помнить: когда вы регистрируете внешнюю печатную форму в программе, система вызывает экспортную процедуру Печать, которая должна находиться строго в Модуле объекта. Если код печати остался в модуле формы, БСП просто его «не увидит», коллекция печатных форм останется пустой, и вы получите обсуждаемую ошибку.
Проанализируем содержание функции СведенияОВнешнейОбработке. В этой функции мы описываем таблицу команд, которую увидит пользователь. Каждая команда имеет свой уникальный Идентификатор. Посмотрим на пример заполнения этой таблицы:
НоваяСтрока = ТаблицаКоманд.Добавить();
НоваяСтрока.Представление = "Печать накладной (внешняя)";
НоваяСтрока.Идентификатор = "ПФ_Накладная_С_Ценами"; // Тот самый Идентификатор
НоваяСтрока.Использование = "ВызовСерверногоМетода";
НоваяСтрока.ПоказыватьОповещение = Истина;
НоваяСтрока.Модификатор = "ПечатьMXL";
Теперь обратим внимание на процедуру Печать в модуле объекта. В ней происходит проверка: какой именно макет нужно формировать. Если идентификатор в «Сведениях...» и в условии Если не совпадает хотя бы на один символ (включая регистр), формирование документа будет пропущено.
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Проверяем, нужно ли печатать наш макет
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПФ_Накладная_С_Ценами") Тогда
ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
// Обязательно выводим результат в коллекцию
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ПФ_Накладная_С_Ценами",
"Печать накладной (внешняя)",
ТабличныйДокумент);
КонецЕсли;
КонецПроцедуры
Разберем типичную ситуацию: при отладке разработчик привык работать с одной ссылкой (СсылкаНаДокумент). Однако внешняя печатная форма в реальных условиях может вызываться для списка выделенных документов в журнале. БСП всегда передает параметр МассивОбъектов.
Если внутри вашей функции формирования макета вы обращаетесь к данным через МассивОбъектов[0] или ожидаете одиночное значение, это приведет к ошибке, если массив пуст или логика требует обработки всех переданных ссылок. Всегда используйте цикл или запрос с условием ГДЕ Ссылка В (&МассивОбъектов).
Посмотрим на ситуацию со стороны системного администрирования. При регистрации внешней обработки в 1С по умолчанию включается флаг «Безопасный режим». В этом режиме ограничивается доступ к файловой системе, COM-объектам и некоторым методам платформы.
Если ваша печатная форма пытается получить данные, требующие привилегированного доступа (например, расчет себестоимости или данные о зарплате), запрос под обычным пользователем может вернуть пустой результат без вызова исключения. В таких случаях следует:
УстановитьПривилегированныйРежим(Истина) в коде формирования данных, если это допустимо политикой безопасности.СведенияОВнешнейОбработке указаны необходимые разрешения, если безопасный режим должен остаться включенным.Проанализируем технический нюанс обновления кода. Когда вы вносите правки в epf-файл на компьютере, изменения не попадают в 1С автоматически. Система хранит бинарные данные обработки в справочнике «Дополнительные отчеты и обработки».
Если вы исправили запрос (добавили ЕСТЬNULL), но забыли нажать кнопку «Обновить из файла» в карточке дополнительной обработки в интерфейсе 1С, система продолжит исполнять старый код. Это часто создает иллюзию того, что правки «не работают».
Для того чтобы гарантированно избавиться от ошибки «Табличный документ не сформирован», пройдемся по следующим пунктам:
ЕСТЬNULL? Нет ли ситуации, когда запрос возвращает 0 строк?Процедура Печать(...) стандартам вашей версии БСП (количество и порядок параметров)?УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию в конце процедуры печати?НужноПечататьМакет?ОбъектыПечати внутри вашего кода для корректной привязки областей к ссылкам?Соблюдение этих правил и внимательный подход к отладке через массив объектов позволят вам создавать стабильные и надежные внешние печатные формы.