Создание печатных форм в управляемом приложении значительно отличается от работы в обычном приложении из-за клиент-серверной архитектуры. Нам необходимо четко разделять логику подготовки данных на сервере и отображение результата пользователю на клиенте. В рамках данной статьи мы разберем несколько способов реализации печатных форм: от самого простого (с помощью конструктора) до профессионального (с использованием модуля менеджера и СКД).
Если вы только начинаете разработку конфигурации или вам нужно быстро создать простую форму, мы рекомендуем воспользоваться встроенным инструментом платформы. Это самый быстрый путь, который автоматически сгенерирует необходимый код и макет.
Разберем по шагам:
ПоступлениеТоваров) и нажмем на него правой кнопкой мыши.ТабличныйДокумент, команду для печати и пропишет программный код в модуле менеджера и модуле команды.Этот метод хорош тем, что платформа учитывает все требования управляемого приложения: создает команду, которая будет доступна в форме документа и списка, и размещает основной код на сервере.
В серьезных проектах (или при интеграции с БСП — Библиотекой стандартных подсистем) принято размещать логику формирования печатной формы в модуле менеджера объекта. Почему это важно? Модуль менеджера доступен без создания тяжелого объекта ДокументОбъект, что существенно экономит ресурсы сервера и ускоряет работу системы.
Проанализируем типичную структуру такого решения. В форме документа мы создаем команду, которая вызывает процедуру печати. Однако правильнее будет передавать на сервер не одну ссылку, а массив ссылок, чтобы пользователь мог распечатать сразу несколько документов из списка.
Пример вызова с клиента:
&НаКлиенте
Процедура КомандаПечать(Команда)
МассивСсылок = Новый Массив;
МассивСсылок.Добавить(Объект.Ссылка);
ТабличныйДокумент = СформироватьПечатнуюФормуНаСервере(МассивСсылок);
ТабличныйДокумент.Показать("Печать документа");
КонецПроцедуры
На сервере мы подготавливаем данные. Использование запроса — это наиболее эффективный способ получения данных для печати. Рассмотрим пример функции, которая возвращает сформированный документ:
&НаСервереБезКонтекста
Функция СформироватьПечатнуюФормуНаСервере(МассивСсылок)
ТабДок = Новый ТабличныйДокумент;
// Получаем макет из модуля менеджера
Макет = Документы.ПоступлениеТехники.ПолучитьМакет("Печать");
// Получаем области макета
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПоступлениеТехники.Номер КАК Номер,
| ПоступлениеТехники.Дата КАК Дата,
| ПоступлениеТехники.Контрагент КАК Контрагент
|ИЗ
| Документ.ПоступлениеТехники КАК ПоступлениеТехники
|ГДЕ
| ПоступлениеТехники.Ссылка В(&МассивСсылок)";
Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ОбластьЗаголовок.Параметры.Заполнить(Выборка);
ТабДок.Вывести(ОбластьЗаголовок);
// Если печатаем несколько документов, вставляем разделитель страниц
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЦикла;
Возврат ТабДок;
КонецФункции
Выясним причину популярности этого метода. СКД позволяет гибко настраивать внешний вид формы без изменения программного кода в будущем. Если пользователю нужно добавить колонку или изменить группировку, это можно сделать в настройках компоновки. Рассмотрим ситуацию, когда макетом печатной формы выступает схема СКД.
Ниже приведен программный код, который инициализирует схему компоновки, передает в нее параметр (ссылку на документ) и выводит результат в ТабличныйДокумент:
&НаСервере
Функция ПечатьНаСервереСКД()
// Получаем объект и его макет (схему СКД)
ДокОбъект = РеквизитФормыВЗначение("Объект");
Схема = ДокОбъект.ПолучитьМакет("МакетСКД");
// Настраиваем компоновщик
Настройки = Схема.НастройкиПоУмолчанию;
КомпоновщикНастроек = Новый КомпоновщикНастроекКомпоновкиДанных();
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
// Устанавливаем параметр "Документ" для фильтрации данных
ПараметрДок = Новый ПараметрКомпоновкиДанных("Документ");
ЗначениеПараметраДок = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(ПараметрДок);
ЗначениеПараметраДок.Значение = Объект.Ссылка;
ЗначениеПараметраДок.Использование = Истина;
// Инициализируем процессор компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, КомпоновщикНастроек.Настройки);
ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки);
// Выводим результат в табличный документ
ДокументРезультат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
// Тонкая настройка отображения
ДокументРезультат.ОтображатьЗаголовки = Ложь;
ДокументРезультат.ОтображатьСетку = Ложь;
ДокументРезультат.АвтоМасштаб = Истина;
Возврат ДокументРезультат;
КонецФункции
Обратите внимание: использование РеквизитФормыВЗначение оправдано только в простых нетиповых конфигурациях. В высоконагруженных системах лучше передавать только Объект.Ссылка и получать схему через менеджер документа.
При создании печатных форм в современных версиях платформы 1С:Предприятие 8.3 следует учитывать требования к производительности и удобству пользователя:
1. Использование объектов метаданных "Команды"
Вместо того чтобы рисовать кнопку вручную на каждой форме, создайте общую команду в дереве метаданных. Укажите тип параметра команды (ссылка на ваш документ) и группу (например, Печать). Это позволит кнопке автоматически появиться не только в форме документа, но и в списках, обеспечивая возможность групповой печати.
2. Асинхронные вызовы
В управляемом приложении (особенно в веб-клиенте) старайтесь избегать модальных окон. Используйте ПоказатьПредупреждение вместо Предупреждение. При проверке записи документа перед печатью используйте асинхронные методы:
&НаКлиенте
Процедура Печать(Команда)
Если Объект.Ссылка.Пустая() Тогда
ПоказатьПредупреждение(, "Документ необходимо записать перед печатью!");
Возврат;
КонецЕсли;
// Логика печати...
КонецПроцедуры
3. Использование шаблонов Office (Word/Excel)
Для сложных юридических документов (договоров, соглашений) иногда проще использовать макеты в формате .docx. Вы можете создать макет типа "Двоичные данные", программно заполнить параметры через COM-объекты (на стороне клиента) или специализированные библиотеки и вывести готовый файл пользователю.
4. Фоновое формирование
Если печатная форма очень тяжелая (например, отчет на тысячи страниц), рассмотрим возможность выноса её формирования в фоновое задание. Это позволит пользователю не ждать окончания процесса с заблокированным интерфейсом, а получить оповещение, когда документ будет готов к просмотру.
5. Расширения конфигурации
Если вы работаете с типовой конфигурацией, никогда не меняйте стандартные печатные формы напрямую. Используйте механизм расширений. Вы можете перехватить процедуру печати с помощью аннотации &Вместо и подменить стандартный макет на свой, сохранив при этом возможность легкого обновления основной конфигурации.
Подводя итог, выбор метода зависит от сложности задачи. Для простых форм идеально подходит Конструктор, для гибких отчетов — СКД, а для стандартных бизнес-решений — программная реализация в модуле менеджера с использованием запросов.