При разработке для современных конфигураций 1С, таких как "Управление торговлей 11", часто возникает задача быстро создать внешнюю печатную форму (ВПФ). Использование Системы Компоновки Данных (СКД) для этой цели — отличный способ сэкономить время, так как не нужно вручную рисовать макет. Однако при интеграции такой формы в систему можно столкнуться с неочевидными ошибками. Рассмотрим одну из самых распространенных: "в обработчике печати не был сформирован табличный документ...".
Проанализируем ситуацию: разработчик создал ВПФ на основе макета СКД, но при попытке печати система выдает ошибку, хотя сам запрос в СКД и код формирования отчета кажутся верными. Выясним причину этой проблемы и разберем правильный подход к созданию таких форм для конфигураций, использующих Библиотеку Стандартных Подсистем (БСП).
Давайте посмотрим на первоначальный код, который приводит к ошибке. Основная проблема кроется в структуре обработчика печати.
В старых конфигурациях или при разработке без учета стандартов БСП было принято, что обработчик печати — это функция, которая формирует и возвращает табличный документ с помощью оператора Возврат.
// НЕПРАВИЛЬНЫЙ код для конфигураций на БСП
Функция Печать(ОбъектыНазначения, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// ... далее код формирования отчета через СКД ...
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
// Ошибка здесь: БСП не ожидает, что функция вернет результат
Возврат ТабДок;
КонецФункции
Современные конфигурации на БСП используют унифицированный механизм печати. Система вызывает обработчик и ожидает, что он не вернет табличный документ, а самостоятельно поместит его в специальный параметр — КоллекцияПечатныхФорм. Если после выполнения кода эта коллекция остается пустой, БСП справедливо считает, что документ не был сформирован, и генерирует ошибку.
Ключевой момент: для совместимости с БСП обработчик печати должен быть процедурой, а не функцией.
Чтобы ВПФ корректно работала в среде БСП, ее структура должна соответствовать определенному стандарту. Разберем по шагам, как выглядит правильная реализация.
Это "паспорт" нашей обработки. Здесь мы сообщаем системе, что это печатная форма, к какому документу она относится и как будет называться команда для ее вызова.
Функция СведенияОВнешнейОбработке() Экспорт
// Используем стандартный шаблон для регистрации
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("1.0.0.0");
// Указываем, что это именно печатная форма
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
ПараметрыРегистрации.Версия = "1.0";
// Привязываем форму к документу "РеализацияТоваровУслуг"
ПараметрыРегистрации.Назначение.Добавить("Документ.РеализацияТоваровУслуг");
// Создаем команду (кнопку) для вызова печати
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Моя печатная форма'");
НоваяКоманда.Идентификатор = "ОсновнаяСхемаКомпоновкиДанных"; // Уникальный идентификатор
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
Это центральная процедура, которую вызывает система при нажатии на кнопку печати. Обратите внимание, что это именно Процедура. Ее задача — не сформировать документ, а вызвать функцию-помощник и передать ее результат в стандартный механизм БСП.
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
ПараметрыПечати = Новый Структура;
// Вызываем стандартную процедуру БСП для добавления документа в коллекцию
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм, // 1. Коллекция, куда поместить результат
"ОсновнаяСхемаКомпоновкиДанных", // 2. Уникальное имя макета
"Моя печатная форма", // 3. Представление для пользователя
ПечатьМакета(МассивОбъектов, ПараметрыПечати, ОбъектыПечати, ПараметрыВывода) // 4. Вызов функции, которая вернет готовый ТабДок
);
КонецПроцедуры
Здесь мы используем ключевой метод БСП — УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию. Он делает всю "грязную" работу: правильно добавляет наш сформированный табличный документ в очередь на печать, учитывая все стандарты системы.
А вот теперь самое интересное — код, который непосредственно работает с СКД и формирует табличный документ. Мы вынесли его в отдельную функцию для удобства. Эта функция уже возвращает результат (ТабличныйДокумент), который затем передается в процедуру БСП из предыдущего шага.
Функция ПечатьМакета(МассивОбъектов, ПараметрыПечати, ОбъектыПечати, ПараметрыВывода)
ТабДок = Новый ТабличныйДокумент;
// 1. Получаем макет СКД из нашей обработки
Макет = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Инициализируем настройки компоновки
ИсточникДоступныхНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(Макет);
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных;
КомпоновщикНастроек.Инициализировать(ИсточникДоступныхНастроек);
КомпоновщикНастроек.ЗагрузитьНастройки(Макет.НастройкиПоУмолчанию);
// 3. Устанавливаем параметры для запроса СКД
Настройки = КомпоновщикНастроек.Настройки;
// В параметре "Ссылка" (его нужно создать в СКД) передаем ссылку на печатаемый документ
Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("Ссылка", МассивОбъектов[0]);
// 4. Компонуем макет
ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Макет, Настройки, ДанныеРасшифровки);
// 5. Выполняем запрос и получаем данные
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
// 6. Выводим результат в табличный документ
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ТабДок);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
// 7. Возвращаем готовый документ
Возврат ТабДок;
КонецФункции
Важный момент: в параметре МассивОбъектов передаются ссылки на все документы, которые пользователь выделил для печати. В нашем примере мы для простоты берем только первый элемент МассивОбъектов[0]. Для корректной групповой печати следует организовать цикл по этому массиву и выводить документы последовательно.
Разобрав эту задачу, мы пришли к следующим выводам:
Печать.Возврат, а добавляется в систему с помощью специальной процедуры БСП — УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию.Такой подход не только исправляет ошибку, но и обеспечивает корректную интеграцию вашей печатной формы со всеми стандартными механизмами платформы: предварительным просмотром, отправкой по почте, сохранением в файл и т.д. Использование СКД при этом остается мощным и быстрым инструментом для создания сложных отчетов без ручного макетирования.