Каталог решений - Передача объекта ТаблицаЗначений в СКД в качестве параметра

Передача объекта ТаблицаЗначений в СКД в качестве параметра

Передача объекта ТаблицаЗначений в СКД в качестве параметра

В наличии

Передача объекта ТаблицаЗначений в СКД в качестве параметра путем замены набора данных с сохранением механизма пользовательских настроек и отборов.

Категория:

Описание

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

  1. Нужно вручную расписывать структуру полей набора данных типа объект.

  2. Соединение наборов данных происходит по правилам, несколько отличным от соединения таблиц в запросе и так как пользоваться этим приходится редко, то не хочется тратить время и разбираться в этом, если можно все свести к старым привычным запросам.

      В результате был найден обходной путь. Не знаю — возможно этот велосипед уже кто-то раньше изобрел, но я работающей схемы не встречал , поэтому решил поделиться опытом.

  Теперь собственно «ноу-хау»: Для начала представим таблицу , которую нужно передать в СКД. Пусть это будет, например таблица периодов.

ВыбИнтервал = "ДЕНЬ";

тзИнтервалов = Новый ТаблицаЗначений;

тзИнтервалов.Колонки.Добавить("НачИнтервала", Новый ОписаниеТипов("Дата"));

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

| НАЧАЛОПЕРИОДА(&НачДата, "+ВыбИнтервал+") КАК НачИнтервала

|УПОРЯДОЧИТЬ ПО

| НачИнтервала

|ИТОГИ ПО

| НачИнтервала ПЕРИОДАМИ("+ВыбИнтервал+", &НачДата, &КонДата)";

//Параметры запроса

Запрос.УстановитьПараметр("НачДата", НачПериода);

Запрос.УстановитьПараметр("КонДата", КонПериода);

 

Выборка = Запрос.Выполнить().Выбрать(ОбходРезультатаЗапроса.ПоГруппировкам, "НачИнтервала", "ВСЕ");

Пока Выборка.Следующий() Цикл

НоваяСтрока = тзИнтервалов.Добавить();

НоваяСтрока.НачИнтервала = Выборка.НачИнтервала;

КонецЦикла;

//тзИнтервалов.ВыбратьСтроку();

     Теперь возвращаемся в конструктор запросов СКД, где мы ваяем наш большой и сложный запрос. Создаем описание временной таблицы с помощью кнопки.

Сотав полей должен быть аналогичен внешней таблице. В нашем случае это одно поле.

ВЫБРАТЬ
    тзИнтервалов.НачИнтервала КАК ДатаКалендаря
ПОМЕСТИТЬ втИнтервалов
ИЗ
    тзИнтервалов КАК тзИнтервалов

;

////////////////////////////////////////////////////////////////////////////////

Далее строим запрос как обычно. Затем извлекаем текст запроса для построения набора данных типа объект:

СКДНастроек = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");

ТекстЗапроса = СКДНастроек.НаборыДанных.НаборДанных1.Запрос;

Меняем текст запроса так, чтобы первая временная таблица принимала через параметр нашу таблицу значений:

 ТекстЗапроса = СтрЗаменить(ТекстЗапроса,

"тзИнтервалов КАК тзИнтервалов",

"&тзИнтервалов КАК тзИнтервалов");

 

Запрос = Новый Запрос;

Запрос.Текст = ТекстЗапроса;

     Затем формируем отчет програмным способом, при этом подменяя набор данных — вместо набора запроса подставляем эквивалентный набор данных типа объект:

настройкиСКД = СКДНастроек.ВариантыНастроек.Найти("Основной").Настройки;

 

ТабДанных = Запрос.Выполнить().Выгрузить();

ВнешниеНаборыДанных = Новый Структура;

ВнешниеНаборыДанных.Вставить("ТаблицаДанных", ТабДанных);

 

//Макет компоновки

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

 

ВнешнийНД = СКДНастроек.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));

ИмяНД = СКДНастроек.НаборыДанных[0].Имя;

ЗаполнитьЗначенияСвойств(ВнешнийНД, СКДНастроек.НаборыДанных.НаборДанных1);

Для каждого ПолеСКД Из СКДНастроек.НаборыДанных[0].Поля Цикл

НовоеПоле = ВнешнийНД.Поля.Добавить(ТипЗнч(ПолеСКД));//(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));

ЗаполнитьЗначенияСвойств(НовоеПоле,ПолеСКД);

КонецЦикла;

СКДНастроек.НаборыДанных.Удалить(СКДНастроек.НаборыДанных[0]);

СКДНастроек.НаборыДанных[0].Имя = ИмяНД;

СКДНастроек.НаборыДанных[0].ИмяОбъекта = "ТаблицаДанных";

 

МакетКомпоновки = КомпоновщикМакета.Выполнить(СКДНастроек,НастройкиСКД,ДанныеРасшифровки );

 

//Компоновка данных

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

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

 

//Вывод результата

ДокументРезультат = ЭлементыФормы.Результат;

ДокументРезультат.Очистить();

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

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

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

ДокументРезультат.Показать();

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

has been added to your cart:
Оформление заказа