Как обратиться из внешней печатной формы к реквизитам формы справочника в 1С?

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

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

В чем заключается архитектурная сложность

Проанализируем контекст выполнения кода в управляемом приложении 1С:Предприятие 8.3:

  1. Изоляция контекста формы: Дополнительные (так называемые «виртуальные») реквизиты формы существуют только в оперативной памяти конкретного открытого клиентского окна. Они не записываются в базу данных вместе со ссылкой на справочник.
  2. Разделение клиента и сервера: Стандартное формирование печатных форм в подсистеме БСП (Библиотека стандартных подсистем) выполняется на сервере в процедуре Печать. Серверный код получает только массив ссылок на объекты и физически не имеет доступа к состоянию элементов открытых окон на клиенте.
  3. Попытка повторного открытия формы: Если на сервере попытаться заново создать форму через ПолучитьФорму, платформа создаст абсолютно новый экземпляр формы со значениями по умолчанию, а не вернет форму, открытую у пользователя.

Рассмотрим основные способы решения этой задачи — от простых до архитектурно верных.

Способ 1. Повторный расчет алгоритма в модуле печати

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

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


Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт

    Для Каждого СсылкаНаСправочник Из МассивОбъектов Цикл
        // Рассчитываем значение по тому же алгоритму, что и в форме
        ВычисленноеЗначение = РассчитатьДополнительныйПоказатель(СсылкаНаСправочник);
        
        // Выводим данные в табличный документ
        // ...
    КонецЦикла;

КонецПроцедуры

Этот подход гарантирует, что печатная форма сформируется корректно не только из открытого элемента, но и при групповой печати из формы списка справочника.

Способ 2. Передача значений через структуру ПараметрыПечати (механизм БСП)

Если печать вызывается пользователем прямо из открытой формы справочника, мы можем переопределить вызов команды печати и передать значения реквизитов формы через параметры.

Разберем по шагам, как это работает в типовых конфигурациях с БСП:

  1. На клиенте в модуле формы справочника перехватываем или создаем команду печати.
  2. Формируем структуру ПараметрыПечати и добавляем в нее необходимые значения из реквизитов формы.
  3. На сервере во внешней печатной форме извлекаем эти данные из переданной структуры параметров.

Посмотрим на пример заполнения параметров на стороне формы:


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

В модуле внешней обработки в процедуре Печать получаем значение:


Если ПараметрыПечати <> Неопределено И ПараметрыПечати.Свойство("МойРеквизитФормы") Тогда
    ЗначениеРеквизита = ПараметрыПечати.МойРеквизитФормы;
КонецЕсли;

Способ 3. Передача данных через ДополнительныеСвойства объекта

Если печать выполняется для еще не записанного объекта или непосредственно в контексте его формы, можно использовать свойство ДополнительныеСвойства объекта.

Разберем логику:


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

Важно: коллекция ДополнительныеСвойства живет только до тех пор, пока экземпляр объекта находится в памяти. При чтении объекта из базы через ссылку эти свойства будут очищены.

Способ 4. Использование временного хранилища

Если используется нестандартный механизм вызова внешней печатной формы, данные можно упаковать во временное хранилище на клиенте и передать обработке полученный адрес.

Рассмотрим реализацию на клиенте:


&НаКлиенте
Процедура ОткрытьПечатнуюФорму()
    
    ДанныеФормы = Новый Структура;
    ДанныеФормы.Вставить("РеквизитПользователя", ЭтаФорма.РеквизитФормы);
    
    АдресХранилища = ПоместитьВоВременноеХранилище(ДанныеФормы, ЭтаФорма.УникальныйИдентификатор);
    
    ПараметрыОткрытия = Новый Структура("АдресДанных", АдресХранилища);
    ОткрытьФорму("ВнешняяОбработка.ИмяОбработки.Форма", ПараметрыОткрытия, ЭтаФорма);
    
КонецПроцедуры

Затем в форме обработки в процедуре ПриСозданииНаСервере извлекаем сохраненную структуру с помощью метода ПолучитьИзВременногоХранилища(Параметры.АдресДанных).

Способ 5. Прямой доступ через клиентский контекст при вызове обработки

Если обработка открывает форму справочника программно, она может сохранить ссылку на открытую форму в переменную модуля и прочитать ее значения напрямую на клиенте:


&НаКлиенте
Перем ФормаСправочника;

&НаКлиенте
Процедура ОткрытьИПрочитать()
    
    ФормаСправочника = ОткрытьФорму("Справочник.Контрагенты.ФормаОбъекта");
    
    // Обращение по имени реквизита формы
    ЗначениеПоля = ФормаСправочника.ИмяРеквизитаФормы;
    
КонецПроцедуры

Обратите внимание: данный подход работает только на клиенте при явном программном открытии формы и не подходит для стандартного механизма формирования отчетов и обработок БСП.

Архитектурные рекомендации

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

  1. Расширение конфигурации: Добавьте настоящий реквизит справочника через расширение конфигурации. Это позволит автоматически сохранять его в базу данных и получать запросом в модуле печати.
  2. Типовой механизм дополнительных реквизитов: Если конфигурация типовая и находится на замке, используйте подсистему «Дополнительные реквизиты и сведения», которая уже встроена в справочник и доступна для вывода в печатные формы.
← На главную