Работа с печатными формами в режиме управляемого приложения значительно отличается от работы в обычных формах. Основная сложность заключается в строгом разделении контекста между клиентом и сервером, а также в особенностях связки визуальных элементов с программным кодом. Разберем пошагово, почему кнопка печати может «молчать» и как исправить ошибки при заполнении макета данными.
Первая проблема, с которой часто сталкиваются разработчики: кнопка на форме есть, код написан, но при нажатии ничего не происходит. В управляемом интерфейсе кнопка — это лишь визуальное представление Команды формы. Рассмотрим механизм их взаимодействия.
Проанализируем ситуацию: вы создали процедуру &НаКлиенте, написали в ней вызов серверной функции, но забыли проверить свойство команды Действие. Если в этом поле не выбрана ваша процедура, 1С просто не «знает», какой код запускать при клике. Бывают случаи, когда после ручного переименования процедуры в модуле связь «отваливается», и поле Действие становится пустым, хотя визуально кажется, что всё настроено правильно. В таком случае помогает простое перевыбор (нажатие на лупу) нужного обработчика в свойствах команды.
Когда мы переходим к заполнению макета данными документа (например, Номер, Дата, Сотрудник), возникает типичная ошибка: {Форма.ФормаДокумента.Форма(15)}: Переменная не определена (Номер). Выясним причину этой ошибки.
В серверной функции управляемой формы у вас нет прямого доступа к реквизитам объекта так, как это было в обычных формах (через ЭтотОбъект). На сервере формы существует РеквизитФормы (обычно это Объект), который является лишь отображением данных. Чтобы получить полноценный объект документа со всеми его методами и данными, мы используем конструкцию РеквизитФормыВЗначение("Объект"). Однако даже после этого нужно помнить, что Номер или Дата — это свойства полученного объекта, а не глобальные переменные.
Рассмотрим правильный способ обращения к данным:
&НаСервере
Функция СформироватьМакетНаСервере()
// Преобразуем данные формы в объект документа
ДокументОбъект = РеквизитФормыВЗначение("Объект");
// Получаем макет, хранящийся в метаданных документа
Макет = ДокументОбъект.ПолучитьМакет("Макет");
// Создаем новый табличный документ
ТабДок = Новый ТабличныйДокумент;
// Теперь обращаемся к реквизитам через переменную ДокументОбъект
НомерДокумента = ДокументОбъект.Номер;
ДатаДокумента = ДокументОбъект.Дата;
Возврат ТабДок;
КонецФункции
Часто новички пытаются вывести весь макет целиком командой ТабДок.Вывести(Макет). Это технически возможно, но лишает вас возможности гибко управлять данными. Проанализируем стандартную практику 1С: макет делится на Области (Заголовок, Шапка, Строка, Подвал).
Чтобы заполнить параметры, нужно сначала получить конкретную область макета, заполнить её параметры и только потом вывести эту область в итоговый табличный документ. Посмотрим на примере:
&НаСервере
Функция МакетСервер()
ТабДок = Новый ТабличныйДокумент;
ОбъектныйОбъект = РеквизитФормыВЗначение("Объект");
Макет = ОбъектныйОбъект.ПолучитьМакет("Макет");
// 1. Получаем область (в макете должна быть именованная область "Заголовок")
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
// 2. Заполняем параметры этой области данными из объекта
ОбластьЗаголовок.Параметры.НомерЛиста = ОбъектныйОбъект.Номер;
ОбластьЗаголовок.Параметры.ДатаЛиста = Формат(ОбъектныйОбъект.Дата, "ДЛФ=D");
ОбластьЗаголовок.Параметры.Сотрудник = ОбъектныйОбъект.Сотрудник;
// 3. Выводим готовую область в итоговый документ
ТабДок.Вывести(ОбластьЗаголовок);
Возврат ТабДок;
КонецФункции
Разберем подробнее настройку самих ячеек в редакторе макета. Существует три основных режима заполнения, которые выбираются в свойствах ячейки (поле «Заполнение»):
Сотрудник). В коде мы обращаемся к нему как Область.Параметры.Сотрудник. В этом режиме не используются квадратные скобки.Больничный лист № [НомерЛиста] от [ДатаЛиста]. 1С автоматически распознает текст в скобках как параметры и позволит присвоить им значения в коде.Важно понимать, что метод РеквизитФормыВЗначение является ресурсоемким (тяжелым), так как платформа создает в памяти сервера полный экземпляр объекта. Если ваша задача — просто прочитать Номер и Дату, которые уже и так отображены на форме, вы можете обращаться к ним напрямую через Объект (реквизит формы) без конвертации.
Рассмотрим более производительный вариант кода:
&НаСервере
Функция ПечатьБезКонвертации()
ТабДок = Новый ТабличныйДокумент;
// Получаем макет через менеджер документа, это быстрее
Макет = Документы.БольничныйЛист.ПолучитьМакет("Макет");
Область = Макет.ПолучитьОбласть("Шапка");
// Обращаемся напрямую к реквизиту формы "Объект"
Область.Параметры.НомерЛиста = Объект.Номер;
Область.Параметры.ДатаЛиста = Объект.Дата;
ТабДок.Вывести(Область);
Возврат ТабДок;
КонецФункции
Подведем итог и составим чек-лист для реализации вывода макета в управляемом приложении:
&НаКлиенте, которая будет вызывать серверную функцию.Область.Параметры, используя данные Объект.ИмяРеквизита.ТабличныйДокумент на клиент и вызовите метод Показать().Не забудьте установить свойство ТабДок.ТолькоПросмотр = Истина; перед возвратом на клиент. Это защитит сформированный документ от случайного редактирования пользователем, оставив только возможность печати и сохранения.