При разработке внешних печатных форм для конфигураций на базе Библиотеки стандартных подсистем (БСП), таких как «1С:Зарплата и управление персоналом 3.1», «1С:ERP» или «1С:Бухгалтерия предприятия», разработчики часто сталкиваются с исключением:
{ОбщийМодуль.ДополнительныеОтчетыИОбработки.Модуль}: В обработчике печати не был сформирован табличный документ для:
Обратите внимание на характерный признак: после двоеточия в тексте ошибки ничего не выводится. Разберем внутренние механизмы подсистемы печати БСП, выясним причину такого поведения и пошагово исправим код обработки.
Для понимания корня проблемы проанализируем, как БСП выполняет команду формирования печатной формы:
Печать подсистема формирует внутреннюю таблицу КоллекцияПечатныхФорм на основании команд, зарегистрированных в функции СведенияОВнешнейОбработке.ИмяМакета, ИмяВРЕГ, СинонимМакета и ТабличныйДокумент (со значением Неопределено).УправлениеПечатью.НужноПечататьМакет проверяет необходимость формирования конкретного макета по его идентификатору. Если проверка проходит, табличный документ формируется и помещается в коллекцию вызовом УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию.ТабличныйДокумент хотя бы в одной строке осталось равным Неопределено, вызывается исключение: В обработчике печати не был сформирован табличный документ для: %ИмяМакета%.Если после слова «для:» имя макета отсутствует, это прямо указывает на то, что идентификатор печатной формы оказался пустым еще на этапе регистрации команды в БСП.
Посмотрим на типовую вспомогательную процедуру добавления команды, которая часто переносится между обработками вручную:
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Обратим внимание на перечень параметров: параметр Идентификатор объявлен во входных данных процедуры, однако в теле процедуры отсутствует строка присвоения значения реквизиту строки таблицы! Поле НоваяКоманда.Идентификатор остается пустой строкой.
В результате БСП регистрирует команду с пустым идентификатором. При выполнении печати метод УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПриказНаСлужебнуюПоездку") ищет переданную строку среди идентификаторов коллекции. Так как идентификатор пуст, метод возвращает Ложь. Формирование макета пропускается, колонка ТабличныйДокумент остается со значением Неопределено, и платформа генерирует исключение с пустым именем команды.
Добавим недостающую строку инициализации идентификатора в процедуру ДобавитьКоманду:
Процедура ДобавитьКоманду(ТаблицаКоманд, Представление, Идентификатор, Использование, ПоказыватьОповещение = Ложь, Модификатор = "")
НоваяКоманда = ТаблицаКоманд.Добавить();
НоваяКоманда.Представление = Представление;
НоваяКоманда.Идентификатор = Идентификатор; // Восстанавливаем заполнение идентификатора
НоваяКоманда.Использование = Использование;
НоваяКоманда.ПоказыватьОповещение = ПоказыватьОповещение;
НоваяКоманда.Модификатор = Модификатор;
КонецПроцедуры
Чтобы исключить аналогичные ошибки, проверим соблюдение соответствия идентификаторов. Строка идентификатора должна совпадать символ в символ (с учетом регистра и пробелов) в трех ключевых местах:
ДобавитьКоманду(Команды, "Приказ на служебную поездку (внешний)", "ПриказНаСлужебнуюПоездку", "ВызовСерверногоМетода", Ложь, "ПечатьMXL");
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ПриказНаСлужебнуюПоездку") Тогда
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"ПриказНаСлужебнуюПоездку",
НСтр("ru = 'Приказ о направлении в командировку (Т-9)'"),
ТабДок);
Если идентификатор заполнен корректно, но ошибка продолжает появляться, проанализируем следующие факторы:
ВывестиТабличныйДокументВКоллекцию расположен внутри цикла обхода выборки запроса, а запрос вернул 0 строк (например, из-за условий отбора или ограничений доступа RLS), строка в коллекции останется незаполненной. Метод вывода в коллекцию должен вызываться всегда, даже если итоговый табличный документ пустой.УправлениеПечатью.МакетПечатнойФормы("Имя") обращается к общим макетам конфигурации. Если макет встроен в саму внешнюю печатную форму, получать его следует через контекст объекта обработки: ЭтотОбъект.ПолучитьМакет("ИмяМакета").Для ускорения поиска ошибок рекомендуется предусмотреть возможность отладки обработки через меню Файл — Открыть без постоянной загрузки в справочник. Для этого создадим форму обработки, добавим на нее реквизит ДокументСсылка и кнопку формирования:
&НаСервере
Процедура СформироватьНаСервере()
ОбъектыНазначения = Новый Массив;
ОбъектыНазначения.Добавить(ДокументСсылка);
КоллекцияПечатныхФорм = УправлениеПечатью.СоздатьКоллекциюПечатныхФорм("ПриказНаСлужебнуюПоездку");
ОбъектыПечати = Новый СписокЗначений;
ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
Печать(ОбъектыНазначения, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
ПечатнаяФорма = КоллекцияПечатныхФорм.Найти("ПриказНаСлужебнуюПоездку", "ИмяМакета");
Если ПечатнаяФорма <> Неопределено И ЗначениеЗаполнено(ПечатнаяФорма.ТабличныйДокумент) Тогда
ТабличныйДокумент = ПечатнаяФорма.ТабличныйДокумент;
Иначе
ВызватьИсключение "Документ не был сформирован!";
КонецЕсли;
КонецПроцедуры
Такой подход позволяет напрямую устанавливать точки останова в модуле объекта и оперативно отслеживать корректность заполнения коллекций БСП.