Как передать параметры и отборы из обработки в отчет на СКД?

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

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

Ограничение на прямую передачу таблицы значений в параметры отбора

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

Поэтому перед отправкой данных в отчет таблицу значений необходимо преобразовать в массив:


// Получаем массив значений из колонки таблицы значений
МассивНоменклатуры = ТЗ.ВыгрузитьКолонку("Номенклатура");

Способ 1. Открытие формы отчета с передачей структуры отбора (Управляемые формы)

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

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


// На клиенте подготавливаем параметры для открытия отчета
МассивНоменклатуры = ПолучитьМассивНоменклатурыНаСервере();

Отбор = Новый Структура;
Отбор.Вставить("Номенклатура", МассивНоменклатуры);

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", Отбор);
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);

ОткрытьФорму("Отчет.НашОтчет.Форма", ПараметрыФормы);

Если в типовой конфигурации на базе БСП требуется передать не отбор, а именно параметр данных СКД (объявленный на вкладке «Параметры» схемы компоновки), используется специализированный ключ структуры ЗначенияПараметров:


ПараметрыСКД = Новый Структура("Номенклатура", МассивНоменклатуры);

ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("ЗначенияПараметров", ПараметрыСКД);
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);

ОткрытьФорму("Отчет.НашОтчет.Форма", ПараметрыФормы);

Обратите внимание: если параметры или отборы отчета выведены в пользовательские настройки, сохраненный пользовательский вариант может переопределить переданные значения. В таких случаях для сброса сохраненных вариантов в ПараметрыФормы дополнительно передают ключ КлючТекущихНастроек = Неопределено.

Способ 2. Программная установка отбора в компоновщике настроек (Обычные формы)

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


ФормаОтчета = Отчеты.НашОтчет.ПолучитьФорму("ФормаОтчета");

// Получаем доступ к отборам компоновщика настроек
ЭлементыОтбора = ФормаОтчета.Отчет.КомпоновщикНастроек.Настройки.Отбор.Элементы;

// Создаем новый элемент отбора или находим существующий
ЭлементОтбора = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Номенклатура");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке;
ЭлементОтбора.ПравоеЗначение = СписокНоменклатуры;
ЭлементОтбора.Использование = Истина;

ФормаОтчета.Открыть();
ФормаОтчета.СкомпоноватьРезультат();

Способ 3. Передача таблицы значений через «Набор данных — объект» (Внешний источник данных)

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

Разберем по шагам правильную архитектуру передачи таблицы во внешний набор данных:

  1. Помещение таблицы во временное хранилище на сервере обработки:

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

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

В модуле объекта отчета используем предопределенный обработчик ПриКомпоновкеРезультата. Отключаем стандартную компоновку и передаем внешнюю таблицу в процессор компоновки:


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

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

Способ 4. Формирование отчета прямо на форме обработки без открытия отдельного окна

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


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

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

← На главную