Почему не работает вывод макета в управляемом приложении и как правильно заполнить параметры

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Работа с печатными формами в режиме управляемого приложения значительно отличается от работы в обычных формах. Основная сложность заключается в строгом разделении контекста между клиентом и сервером, а также в особенностях связки визуальных элементов с программным кодом. Разберем пошагово, почему кнопка печати может «молчать» и как исправить ошибки при заполнении макета данными.

Причина 1: Отсутствие связи между командой и её действием

Первая проблема, с которой часто сталкиваются разработчики: кнопка на форме есть, код написан, но при нажатии ничего не происходит. В управляемом интерфейсе кнопка — это лишь визуальное представление Команды формы. Рассмотрим механизм их взаимодействия.

Проанализируем ситуацию: вы создали процедуру &НаКлиенте, написали в ней вызов серверной функции, но забыли проверить свойство команды Действие. Если в этом поле не выбрана ваша процедура, 1С просто не «знает», какой код запускать при клике. Бывают случаи, когда после ручного переименования процедуры в модуле связь «отваливается», и поле Действие становится пустым, хотя визуально кажется, что всё настроено правильно. В таком случае помогает простое перевыбор (нажатие на лупу) нужного обработчика в свойствах команды.

Причина 2: Контекст исполнения и ошибка «Переменная не определена»

Когда мы переходим к заполнению макета данными документа (например, Номер, Дата, Сотрудник), возникает типичная ошибка: {Форма.ФормаДокумента.Форма(15)}: Переменная не определена (Номер). Выясним причину этой ошибки.

В серверной функции управляемой формы у вас нет прямого доступа к реквизитам объекта так, как это было в обычных формах (через ЭтотОбъект). На сервере формы существует РеквизитФормы (обычно это Объект), который является лишь отображением данных. Чтобы получить полноценный объект документа со всеми его методами и данными, мы используем конструкцию РеквизитФормыВЗначение("Объект"). Однако даже после этого нужно помнить, что Номер или Дата — это свойства полученного объекта, а не глобальные переменные.

Рассмотрим правильный способ обращения к данным:


&НаСервере
Функция СформироватьМакетНаСервере()
    
    // Преобразуем данные формы в объект документа
    ДокументОбъект = РеквизитФормыВЗначение("Объект");
    
    // Получаем макет, хранящийся в метаданных документа
    Макет = ДокументОбъект.ПолучитьМакет("Макет");
    
    // Создаем новый табличный документ
    ТабДок = Новый ТабличныйДокумент;
    
    // Теперь обращаемся к реквизитам через переменную ДокументОбъект
    НомерДокумента = ДокументОбъект.Номер;
    ДатаДокумента  = ДокументОбъект.Дата;
    
    Возврат ТабДок;
КонецФункции

Причина 3: Неправильный вывод областей макета

Часто новички пытаются вывести весь макет целиком командой ТабДок.Вывести(Макет). Это технически возможно, но лишает вас возможности гибко управлять данными. Проанализируем стандартную практику 1С: макет делится на Области (Заголовок, Шапка, Строка, Подвал).

Чтобы заполнить параметры, нужно сначала получить конкретную область макета, заполнить её параметры и только потом вывести эту область в итоговый табличный документ. Посмотрим на примере:


&НаСервере
Функция МакетСервер() 
    ТабДок = Новый ТабличныйДокумент;
    ОбъектныйОбъект = РеквизитФормыВЗначение("Объект");
    Макет = ОбъектныйОбъект.ПолучитьМакет("Макет");
    
    // 1. Получаем область (в макете должна быть именованная область "Заголовок")
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    
    // 2. Заполняем параметры этой области данными из объекта
    ОбластьЗаголовок.Параметры.НомерЛиста = ОбъектныйОбъект.Номер;
    ОбластьЗаголовок.Параметры.ДатаЛиста  = Формат(ОбъектныйОбъект.Дата, "ДЛФ=D");
    ОбластьЗаголовок.Параметры.Сотрудник  = ОбъектныйОбъект.Сотрудник;
    
    // 3. Выводим готовую область в итоговый документ
    ТабДок.Вывести(ОбластьЗаголовок);
    
    Возврат ТабДок;
КонецФункции

Работа с оформлением макета: Шаблоны и Параметры

Разберем подробнее настройку самих ячеек в редакторе макета. Существует три основных режима заполнения, которые выбираются в свойствах ячейки (поле «Заполнение»):

  1. Текст: В ячейке отображается ровно то, что в ней написано.
  2. Параметр: В ячейке пишется имя (например, Сотрудник). В коде мы обращаемся к нему как Область.Параметры.Сотрудник. В этом режиме не используются квадратные скобки.
  3. Шаблон: Позволяет комбинировать статичный текст и переменные данные. Вот здесь используются квадратные скобки. Например: Больничный лист № [НомерЛиста] от [ДатаЛиста]. 1С автоматически распознает текст в скобках как параметры и позволит присвоить им значения в коде.

Оптимизация: когда не нужно использовать РеквизитФормыВЗначение

Важно понимать, что метод РеквизитФормыВЗначение является ресурсоемким (тяжелым), так как платформа создает в памяти сервера полный экземпляр объекта. Если ваша задача — просто прочитать Номер и Дату, которые уже и так отображены на форме, вы можете обращаться к ним напрямую через Объект (реквизит формы) без конвертации.

Рассмотрим более производительный вариант кода:


&НаСервере
Функция ПечатьБезКонвертации()
    ТабДок = Новый ТабличныйДокумент;
    
    // Получаем макет через менеджер документа, это быстрее
    Макет = Документы.БольничныйЛист.ПолучитьМакет("Макет");
    
    Область = Макет.ПолучитьОбласть("Шапка");
    
    // Обращаемся напрямую к реквизиту формы "Объект"
    Область.Параметры.НомерЛиста = Объект.Номер;
    Область.Параметры.ДатаЛиста  = Объект.Дата;
    
    ТабДок.Вывести(Область);
    Возврат ТабДок;
КонецФункции

Итоговый алгоритм действий

Подведем итог и составим чек-лист для реализации вывода макета в управляемом приложении:

  1. Создайте Команду формы (например, "ПечатьЛиста").
  2. Перетащите команду на визуальную панель формы (создастся Кнопка).
  3. В модуле формы создайте процедуру &НаКлиенте, которая будет вызывать серверную функцию.
  4. Убедитесь, что в свойствах команды в поле Действие выбрана ваша клиентская процедура.
  5. На сервере получите область макета, заполните её параметры через Область.Параметры, используя данные Объект.ИмяРеквизита.
  6. Верните ТабличныйДокумент на клиент и вызовите метод Показать().

Не забудьте установить свойство ТабДок.ТолькоПросмотр = Истина; перед возвратом на клиент. Это защитит сформированный документ от случайного редактирования пользователем, оставив только возможность печати и сохранения.

← На главную