Как получить колонки дерева значений из общей формы во внешней печатной форме на сервере

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

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

Разберем причину сложности: почему Метаданные не помогут

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

Поскольку модуль объекта внешней печатной формы (процедура Печать) работает на сервере без прямой ссылки на форму-владельца, мы не можем просто «дотянуться» до колонок. Выясним, какие инструменты платформы и БСП позволяют нам пробросить эти данные.

Способ 1: Использование типа команды «Вызов клиентского метода»

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

Во-первых, в модуле объекта внешней печатной формы в функции СведенияОВнешнейОбработке() необходимо указать правильный тип команды. Вместо привычного ВызовСерверногоМетода мы используем ВызовКлиентскогоМетода.


ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке("2.2.2.1");
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru = 'Печать дерева значений'");
НоваяКоманда.Идентификатор = "ПечатьДерева";
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовКлиентскогоМетода();

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


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

Способ 2: Преобразование ДанныеФормы в Значение на сервере

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

Рассмотрим пример кода в модуле объекта внешней печатной формы:


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

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

Способ 3: Передача через Временное хранилище

Если дерево значений очень объемное, правильнее будет выгрузить его в обычное ДеревоЗначений на стороне формы, поместить во временное хранилище и передать на сервер только адрес (строку GUID).

Разберем этот процесс по шагам:

  1. На стороне формы: Вызываем серверный метод формы, который выполняет РеквизитФормыВЗначение("ДеревоНаФорме").
  2. Полученный объект помещаем в ПоместитьВоВременноеХранилище(ДеревоОбъект, УникальныйИдентификатор).
  3. Адрес хранилища передаем в структуру ДополнительныеПараметры.
  4. В модуле печатной формы: Извлекаем данные через ПолучитьИзВременногоХранилища(Адрес).

Использование расширений для получения доступа

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

Тем не менее, для внешних печатных форм связка ТипКомандыВызовКлиентскогоМетода + ДанныеФормыВЗначение остается «золотым стандартом», так как она не требует изменения метаданных конфигурации и работает в рамках типовой логики БСП.

Резюме по реализации

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

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

← На главную