Как выгрузить данные из СКД в таблицу на форме в управляемом приложении

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

При работе с системой компоновки данных (СКД) часто возникает необходимость не просто вывести отчет в табличный документ, но и получить промежуточные результаты или выборки во внутреннюю таблицу значений (ТЗ) на форме. Это может понадобиться для дополнительной обработки данных пользователем, визуализации графиков или интеграции с другими элементами интерфейса. Рассмотрим, как правильно организовать передачу данных из модуля объекта отчета в контекст управляемой формы, проанализируем возможные ошибки и разберем наиболее надежные методы решения этой задачи.

Ситуация: ограничение контекста

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

Способ 1. Использование реквизитов объекта и РеквизитФормыВЗначение

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

Разберем алгоритм действий:

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

Однако, если мы просто вызовем формирование отчета, данные могут не отобразиться автоматически. Чтобы «пробросить» контекст формы в объект в момент программного вызова, используется метод РеквизитФормыВЗначение. Рассмотрим пример кода на стороне формы:


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

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

Способ 2. Использование временного хранилища (лучшая практика)

Проанализируем более профессиональный подход, который лишен недостатков предыдущего метода и стабильно работает в веб-клиенте и при использовании фоновых заданий. Временное хранилище позволяет передать таблицу значений по «адресу-ссылке».

Рассмотрим пошагово, как реализовать этот механизм в процедуре ПриКомпоновкеРезультата:

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

Пример кода в модуле объекта:


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

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


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

Способ 3. Выгрузка результата СКД напрямую в коллекцию

Выясним ситуацию, когда нам нужно выгрузить в таблицу не промежуточные данные, а сам результат отчета. Вместо вывода в ТабличныйДокумент, СКД позволяет использовать ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений. Это позволяет получить готовую ТЗ со структурой, полностью повторяющей настройки отчета (группировки, колонки).

Пример программной компоновки:


// Создаем процессор компоновки
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных);

// Создаем таблицу значений для результата
РезультатТЗ = Новый ТаблицаЗначений;

// Инициализируем процессор вывода в коллекцию
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ПроцессорВывода.УстановитьОбъект(РезультатТЗ);

// Выводим результат
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Этот метод идеален, если форма должна отображать те же данные, что и основной отчет, но в виде динамического списка или таблицы с возможностью сортировки и программного перебора строк.

Способ 4. Ручной перебор через ПроцессорКомпоновки

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

Разберем пример реализации:


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

Подведем итоги

Для реализации выгрузки данных из СКД в таблицу на форме рекомендуется придерживаться следующих правил:

  1. Если отчет простой и работает в интерактивном режиме — используйте реквизиты объекта и метод РеквизитФормыВЗначение.
  2. Если отчет сложный, работает через фоновые задания или в веб-клиенте — используйте Временное хранилище и передачу адреса через ДополнительныеСвойства.
  3. Если нужно получить результат всего отчета в виде таблицы — используйте Процессор вывода в коллекцию.
  4. Всегда помните о производительности: передача больших таблиц значений между сервером и клиентом может существенно замедлить интерфейс программы.

Рассмотренные подходы позволяют гибко управлять данными СКД и создавать интерактивные отчеты, которые не ограничиваются простым выводом печатной формы.

← На главную