Как программно открыть и сформировать отчет СКД с внешним набором данных Объект

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

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

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

Понятие внешнего набора данных в СКД

Проанализируем сначала саму концепцию. Набор данных Объект в схеме компоновки данных — это «посадочное место» для внешней коллекции (обычно это ТаблицаЗначений), которую разработчик должен передать в СКД непосредственно перед процессом компоновки. В отличие от набора данных Запрос, система не знает, откуда брать данные, пока мы явно не укажем их в коде.

Шаг 1. Подготовка схемы и структуры данных

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

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

  1. Строгая типизация: Колонки таблицы значений должны иметь четко определенные типы. Если оставить типы неопределенными, СКД может некорректно обрабатывать фильтры или итоги.
  2. Соответствие имен: Имена колонок в таблице значений должны в точности совпадать с именами полей в наборе данных СКД.

Шаг 2. Программное формирование отчета (классический метод)

Разберем алгоритм формирования отчета полностью программным способом. Этот метод подходит, если нам нужно получить результат (например, в табличный документ) без открытия формы отчета или внутри какой-либо обработки.

Выполним следующие шаги:

  1. Создадим объект отчета.
  2. Подготовим таблицу значений с данными.
  3. Инициализируем процессор компоновки, передав в него наши данные.

// 1. Подготовка данных
ТЗДанных = ПолучитьТаблицуДанных(); // Ваша функция, возвращающая ТЗ

// 2. Инициализация объектов СКД
ОтчетОбъект = Отчеты.МойОтчетСОбъектом.Создать();
СхемаСКД = ОтчетОбъект.СхемаКомпоновкиДанных;
Настройки = ОтчетОбъект.КомпоновщикНастроек.ПолучитьНастройки();

// 3. Формируем макет компоновки
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаСКД, Настройки);

// 4. Передача внешних данных
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ИмяНабораДанныхВ_СКД", ТЗДанных);

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

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

Шаг 3. Передача данных при открытии формы отчета

Ситуация усложняется, когда отчет нужно открыть по кнопке и сразу показать пользователю уже заполненным. Напрямую передать ТаблицаЗначений в параметры открытия формы нельзя, так как она не является сериализуемой для передачи между клиентом и сервером в некоторых контекстах. Выясним, как обойти это ограничение.

Наиболее правильный метод — использование Временного хранилища. Рассмотрим этот процесс по шагам:

В модуле обработки (на клиенте):


&НаКлиенте
Процедура СформироватьОтчетПоКнопке(Команда)
    АдресДанных = ПодготовитьДанныеНаСервере();
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("АдресВнешнихДанных", АдресДанных);
    ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
    
    ОткрытьФорму("Отчет.МойОтчет.Форма", ПараметрыФормы);
КонецПроцедуры

&НаСервере
Функция ПодготовитьДанныеНаСервере()
    ТЗ = СформироватьНужнуюТаблицу();
    Возврат ПоместитьВоВременноеХранилище(ТЗ, УникальныйИдентификатор);
КонецФункции

Шаг 4. Обработка данных в модуле отчета

Чтобы отчет «подхватил» данные из хранилища, нам нужно использовать стандартное событие ПриКомпоновкеРезультата в модуле объекта отчета. Это ключевой момент для реализации гибкой логики, о которой упоминалось в обсуждении.

Проанализируем код внутри модуля отчета:


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

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

Нюансы и рекомендации

Разберем несколько важных моментов, которые помогут избежать типичных ошибок при работе с набором данных Объект:

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

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

← На главную