Как получить значение элемента формы во внешней печатной форме?

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

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

Разберем причину проблемы: Клиент vs Сервер

Для начала проанализируем ситуацию, описанную в теме форума. Автор добавил элемент на форму документа через расширение и пытается обратиться к нему из кода внешней печатной формы. Рассмотрим, почему код типа Форма.ЭлементыФормы... выдает ошибку или не возвращает результат.

В современных конфигурациях 1С (на управляемых формах) печать происходит по следующей схеме:

  1. Пользователь нажимает кнопку «Печать» на клиенте.
  2. Система вызывает серверный метод модуля менеджера или внешней обработки.
  3. На сервере создается объект обработки, куда передается массив ссылок на документы.

Важный момент: на сервере в момент формирования печатной формы контекст экранной формы (клиента) недоступен. Объект «Форма» существует только в памяти клиентского приложения. Когда внешняя печатная форма начинает свою работу, она «знает» только о ссылке на объект (ДокументСсылка), которая хранится в базе данных. Она ничего не знает о том, что в данный момент введено в текстовое поле на экране у пользователя, если эти данные не были записаны в реквизиты документа.

Решение №1: Перенос реквизита из формы в объект (Рекомендуемый способ)

Проанализируем самый надежный и простой путь. Если данные, которые вы добавили в расширение, должны выводиться на печать, значит, они имеют смысл для самого документа. Вместо того чтобы создавать «Реквизит формы», создайте «Реквизит объекта» в расширении.

Рассмотрим по шагам:

  1. Откроем расширение конфигурации.
  2. Найдем нужный документ (например, КорректировкаРеализации).
  3. Добавим новый реквизит непосредственно в дерево метаданных документа (например, ДополнительныйТекстПечати).
  4. Вынесем этот реквизит на форму.

Теперь, когда пользователь нажмет «Записать» или «Печать» (если настроена автозапись), значение сохранится в базе данных. В коде внешней печатной формы мы сможем легко получить это значение по ссылке:


// В модуле внешней обработки
Для Каждого СсылкаИзМассива Из МассивОбъектов Цикл
    // Мы обращаемся к реквизиту напрямую через точку от ссылки
    ТекстДляВывода = СсылкаИзМассива.ДополнительныйТекстПечати;
    
    // Или через запрос для оптимизации
    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ ДополнительныйТекстПечати ИЗ Документ.КорректировкаРеализации ГДЕ Ссылка = &Ссылка";
    Запрос.УстановитьПараметр("Ссылка", СсылкаИзМассива);
    // ... дальнейшая логика формирования макета
КонецЦикла;

Решение №2: Использование дополнительных параметров печати (БСП)

Если ваша конфигурация построена на базе БСП (Библиотека стандартных подсистем), существует механизм передачи параметров из формы напрямую в обработку печати. Это полезно, если данные не нужно хранить в базе данных постоянно.

Выясним, как это работает. При вызове команды печати используется структура ПараметрыПечати. Чтобы передать значение из элемента формы, нам потребуется переопределить команду печати в расширении формы документа.

Рассмотрим пример перехвата управления:


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

В самой внешней печатной форме в процедуре Печать (которая находится в модуле менеджера или обработки) эти данные можно будет извлечь из структуры параметров.

Решение №3: Штатный механизм «Дополнительные реквизиты»

Посмотрим на ситуацию шире. Если вам нужно добавить поле «Строка» к документу, 1С уже имеет встроенный механизм, не требующий программирования в расширениях. Это «Дополнительные реквизиты и сведения».

Почему это удобно:

Пример запроса для получения такого значения в печатной форме:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	КорректировкаРеализацииДополнительныеРеквизиты.Значение КАК Значение
    |ИЗ
    |	Документ.КорректировкаРеализации.ДополнительныеРеквизиты КАК КорректировкаРеализацииДополнительныеРеквизиты
    |ГДЕ
    |	КорректировкаРеализацииДополнительныеРеквизиты.Ссылка = &Ссылка
    |	И КорректировкаРеализацииДополнительныеРеквизиты.Свойство.Наименование = &ИмяСвойства";

Запрос.УстановитьПараметр("Ссылка", СсылкаНаДокумент);
Запрос.УстановитьПараметр("ИмяСвойства", "НужныйРеквизитДляПечати");

Резюме

Мы выяснили причину, по которой нельзя просто «взять элемент формы» — это связано с разрывом контекста между клиентом и сервером. Для решения задачи выберите один из подходов:

  1. Если данные важны для истории — добавьте реквизит в объект (в расширении).
  2. Если данные нужны только один раз для печати — используйте передачу через структуру параметров печати БСП (сложнее в реализации).
  3. Если нужно быстро и без кода в расширении — используйте механизм Дополнительных реквизитов БСП.

Помните, что хорошим тоном в разработке на 1С считается хранение всех значимых данных в базе, а не на экранных формах. Это гарантирует, что при формировании печатной формы (даже в фоновом задании на сервере) информация будет доступна.

← На главную