В разработке на платформе 1С:Предприятие 8.3 (особенно в режиме управляемых форм) начинающие программисты часто сталкиваются с ситуацией, когда код формирования печатной формы написан, ошибки отсутствуют, но при нажатии на кнопку ничего не происходит. Это связано с особенностями взаимодействия между сервером и клиентом. Давайте разберем эту задачу подробно, проанализируем ошибки и выстроим правильную архитектуру вывода документа.
Типичная ошибка заключается в том, что разработчик пытается вызвать методы отображения документа непосредственно на сервере. Рассмотрим ситуацию: вы создаете объект ТабличныйДокумент на сервере, заполняете его данными из макета, используете метод Вывести(), но документ остается "жить" в памяти сервера. Сервер — это программный код, у него нет монитора. Чтобы пользователь увидел результат, объект должен быть передан на сторону клиента, где и будет вызван визуальный метод Показать().
Проанализируем архитектурную цепочку действий, которую мы должны реализовать:
РеквизитФормыВЗначение или напрямую.ТабличныйДокумент возвращается из функции обратно на клиент.Показать().Рассмотрим правильный пример кода, который объединяет заполнение макета и его возврат на клиент. В этом примере мы используем обработку, где макет хранится внутри самого объекта.
&НаСервере
Функция СформироватьПечатнуюФормуНаСервере()
// Преобразуем данные формы в объект обработки, чтобы иметь доступ к макетам
ОбъектОбработка = РеквизитФормыВЗначение("Объект");
// Создаем новый табличный документ
ТабДок = Новый ТабличныйДокумент;
// Получаем макет по имени
Макет = ОбъектОбработка.ПолучитьМакет("Макет");
// Получаем области макета
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
// Заполняем параметры области из реквизитов объекта
ОбластьШапка.Параметры.Организация = Объект.Организация;
ОбластьШапка.Параметры.Дата = Формат(Объект.ДатаКонец, "ДЛФ=DD");
// Выводим область в итоговый табличный документ
ТабДок.Вывести(ОбластьШапка);
// Очень важно вернуть объект!
Возврат ТабДок;
КонецФункции
&НаКлиенте
Процедура ВыполнитьПечать(Команда)
// Получаем сформированный документ с сервера
РезультатПечати = СформироватьПечатнуюФормуНаСервере();
// Выводим документ на экран
РезультатПечати.Показать("Печать реализации");
КонецПроцедуры
Обратите внимание на использование функции РеквизитФормыВЗначение("Объект"). В управляемых формах Объект — это данные формы, у которых нет метода ПолучитьМакет(). Чтобы добраться до макета, нам нужно временно превратить данные формы в полноценный прикладной объект обработки.
Часто пользователи жалуются, что печатная форма выглядит как "Excel-таблица с ячейками", а им нужен "цельный лист". Для этого мы можем программно управлять свойствами объекта ТабличныйДокумент. Разберем основные свойства, которые сделают форму профессиональной:
ТабДок.ОтображатьСетку = Ложь;.ТабДок.ОтображатьЗаголовки = Ложь;.ТабДок.ТолькоПросмотр = Истина;.ТабДок.АвтоМасштаб = Истина;.Добавим эти настройки в нашу серверную функцию:
// ... код заполнения областей ...
ТабДок.Вывести(ОбластьШапка);
// Настройки отображения
ТабДок.ОтображатьСетку = Ложь;
ТабДок.ОтображатьЗаголовки = Ложь;
ТабДок.ТолькоПросмотр = Истина;
ТабДок.АвтоМасштаб = Истина;
Возврат ТабДок;
Иногда требуется не просто вывести данные, но и подготовить их (например, просклонять ФИО менеджера или ответственного). Проанализируем пример из реальной практики, когда используются типовые функции конфигурации (например, из ЗУП или БП 3.0).
Для склонения ФИО в типовых конфигурациях часто используется общий модуль ФизическиеЛицаЗарплатаКадры. Вызов может выглядеть так:
ФИОРезультат = "";
ФизическиеЛицаЗарплатаКадры.Просклонять(КонтактноеЛицо.Наименование, 2, ФИОРезультат);
ОбластьШапка.Параметры.МенеджерВПадеже = ФИОРезультат;
Если ваша задача — вывести список номенклатуры, мы должны использовать циклы для вывода повторяющихся областей (строк таблицы). Рассмотрим этот процесс:
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
Для Каждого ТекСтрока Из Объект.Товары Цикл
// Заполняем параметры каждой строки
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, ТекСтрока);
// Проверяем, влезет ли строка на текущую страницу
МассивОбластей = Новый Массив;
МассивОбластей.Добавить(ОбластьСтрока);
Если Не ТабДок.ПроверитьВывод(МассивОбластей) Тогда
ТабДок.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ТабДок.Вывести(ОбластьСтрока);
КонецЦикла;
Метод ПроверитьВывод() очень полезен для больших документов, так как он позволяет избежать "разрыва" строк таблицы между страницами, принудительно вставляя разделитель там, где это необходимо.
В современных конфигурациях хорошим тоном считается использование БСП (Библиотеки стандартных подсистем). Вместо прямого вызова Показать(), разработчики используют подсистему «Печать». Это дает пользователю стандартное окно с возможностью сразу отправить документ на почту, сохранить в PDF или изменить количество копий.
Для интеграции с БСП в модуле менеджера объекта обычно создается процедура ДобавитьКомандыПечати, а в модуле объекта — функция Печать. Однако, если вы делаете простую внешнюю обработку, прямого возврата табличного документа на клиент через серверную функцию вполне достаточно для решения большинства задач.
Выясним еще одну важную деталь: если вы хотите, чтобы 1С запоминала настройки принтера (например, ландшафтную ориентацию) именно для этой формы, обязательно задайте имя параметрам печати:
ТабДок.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_РЕАЛИЗАЦИЯ_ПО_ПОСТАВЩИКАМ";
Мы выяснили, что для успешного вывода макета необходимо четко разделять логику: формирование и наполнение данными происходит в функции &НаСервере, а визуальное отображение — в процедуре &НаКлиенте. Использование свойств ОтображатьСетку и ТолькоПросмотр позволяет придать таблице вид полноценного печатного документа.