При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью реализовать кастомную кнопку печати. Стандартные механизмы 1С не всегда подходят под специфические требования интерфейса, и тогда приходится писать код вывода вручную. В этой статье мы подробно разберем, как правильно реализовать процедуру печати, чтобы в итоговый документ попадали все фильтры и параметры, установленные пользователем на форме.
Рассмотрим ситуацию, с которой столкнулся автор темы. Основная проблема заключалась в том, что при нажатии на кнопку сформированный отчет выводился пустым или без учета установленных отборов. Проанализируем код и выясним причины такого поведения.
Первая и самая критическая ошибка — создание нового экземпляра отчета внутри процедуры формы. Когда мы пишем Отчет = Отчеты.ИмяОтчета.Создать();, система создает абсолютно «чистый» объект. В нем нет тех данных, которые пользователь только что ввел в поля отбора на экране. Для корректной работы нам необходимо обращаться к текущему объекту отчета, с которым связана форма.
Вторая ошибка — использование настроек по умолчанию. Строка кода НастройкиСКД = СКД.НастройкиПоУмолчанию; полностью игрирует все изменения, внесенные пользователем (выбранные периоды, склады, контрагенты). Вместо этого система берет те настройки, которые были жестко заданы разработчиком в схеме компоновки при создании отчета.
Третья ошибка — путаница между управляемыми и обычными формами. Использование метода РеквизитФормыВЗначение допустимо только в управляемом интерфейсе. В обычном приложении (толстый клиент) работа с объектом идет напрямую, и подобные преобразования вызывают ошибку исполнения.
Для того чтобы отчет учитывал все пользовательские настройки, мы должны извлечь их из КомпоновщикаНастроек текущего объекта. Рассмотрим правильный способ подготовки настроек:
// В контексте формы обычного приложения обращаемся к текущему объекту
Настройки = ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки();
// Или, если код выполняется в процедуре, где доступен объект 'Отчет'
// Настройки = Отчет.КомпоновщикНастроек.Настройки;
Обратите внимание, что использование метода ПолучитьНастройки() является более предпочтительным, так как он собирает воедино основные настройки, настройки пользователя и фиксированные настройки, если они были заданы.
Иногда требуется программно «дозаполнить» параметры перед формированием макета. Разберем, как это сделать правильно. Создадим вспомогательную процедуру, которая будет искать нужный параметр в настройках и устанавливать его значение.
Процедура УстановитьЗначениеПараметра(НастройкиКомпоновки, ИмяПараметра, Значение)
Параметр = НастройкиКомпоновки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных(ИмяПараметра));
Если Параметр <> Неопределено Тогда
Параметр.Значение = Значение;
Параметр.Использование = Истина;
КонецЕсли;
КонецПроцедуры
В основной процедуре печати мы вызовем ее следующим образом:
УстановитьЗначениеПараметра(Настройки, "ЗаказПокупателя", Отчет.ЗаказПокупателя);
Теперь объединим все части кода в единую процедуру. Проанализируем последовательность действий: получение схемы, создание макета компоновки, инициализация процессора и вывод в табличный документ.
Процедура ДействияФормыПечать(Кнопка)
// 1. Получаем макет СКД из текущего отчета
СхемаКД = ЭтотОбъект.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Получаем текущие настройки пользователя
Настройки = ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки();
// 3. Формируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКД, Настройки);
// 4. Инициализируем процессор компоновки данных
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// 5. Готовим табличный документ для вывода
ГотовыйОтчет = Новый Табличный Document;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ГотовыйОтчет);
// 6. Выводим результат
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
// 7. Настраиваем оформление и выводим на экран/печать
ГотовыйОтчет.ОтображатьСетку = Ложь;
ГотовыйОтчет.ОтображатьЗаголовки = Ложь;
ГотовыйОтчет.АвтоМасштаб = Истина; // Чтобы отчет вписался в лист
ГотовыйОтчет.ОриентацияСтраницы = ОриентацияСтраницы.Ландшафт;
// Выводим диалог печати
ГотовыйОтчет.Напечатать(РежимИспользованияДиалогаПечати.Использовать);
КонецПроцедуры
Важно понимать различие между Параметрами данных и Отборами. Если пользователь добавил условие через механизм «Отбор» (на соответствующей закладке компоновщика), то обращаться к нему через ПараметрыДанных нельзя — система выдаст ошибку «Поле объекта не обнаружено». Отборы хранятся в коллекции Настройки.Отбор.Элементы. Если вы используете метод КомпоновщикНастроек.ПолучитьНастройки(), как было указано выше, все пользовательские отборы автоматически попадут в итоговый результат без дополнительного кода.
Чтобы отчет выглядел презентабельно, рекомендуем обратить внимание на следующие свойства объекта ТабличныйДокумент:
Истина система автоматически уменьшит шрифт отчета так, чтобы он поместился на одну страницу по ширине."ПечатьОтчетаПоЗаказам"), 1С запомнит настройки принтера и ориентацию страницы специально для этого отчета. При следующем открытии пользователю не придется снова выбирать «Ландшафт».Истина защитит отчет от случайного редактирования пользователем перед печатью.Таким образом, мы выяснили, что секрет успешной печати из СКД заключается в правильной работе с объектом отчета и его компоновщиком настроек. Избегайте пересоздания объектов и всегда опирайтесь на текущий контекст формы.