Выполнить пакетный запрос ПостроителемОтчета?
Выполнить пакетный запрос ПостроителемОтчета? Может каждый, но у вас не было времени 🙂
- Описание
- Подробнее
Описание
Не секрет, что ПостроительОтчета «не переваривает» пакетные запросы, однако можно поместить во временную таблицу результат некого (одного) запроса. «Ну и что?» — скажете Вы, — «Как потом такую ВТ прочитать и использовать??».
Тем не менее, всё предельно просто, если воспользоваться внешним по отношению в ПостроителюОтчета МенеджеромВременныхТаблиц, например, по такой схеме:
1)
//….
МенеджерВТ = Новый МенеджерВременныхТаблиц;
Результат = ВыполнитьПакетВПостроителе(МенеджерВТ);
//..
Функция ВыполнитьПакетВПостроителе(МенеджерВТ)
Построитель.Текст =
«ВЫБРАТЬ
//..
|ПОМЕСТИТЬ ВТ1
|ИЗ
//
|
|{ГДЕ
| Условие1 ,
//….
| ОтборN
| }
|»;
Запрос = Построитель.ПолучитьЗапрос();
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст = Запрос.Текст +
«
|;
|ВЫБРАТЬ
//…
|ИЗ ВТ1 КАК ВТ1
//…
|;
|УНИЧТОЖИТЬ ВТ1;
|»;
Возврат Запрос.Выполнить();
КонецФункции
Заметим, что «;» (точка с запятой), необходимая для первой ВТ, стоит не в текст ПостроителяОтчета, а в тексте доработанного запроса. Это связано с тем, что ПостроительОтчета, хоть и помещает результат во временную таблицу, но в тексте своего запроса окончание («;») «съедает».
2) Если перед вызовом функции ВыполнитьПакетВПостроителе() настройки (Отбор, ПараметрыДанных) были установлены, то простенький тестовый примерчик порадует своей работоспособностью.
А что если решение задачи «требует» использования разных выборок данных в различных разрезах, представлениях и т.п., причем желательно с использованием однажды установленных пользователем настроек?
Очевидно, расширить схему:
Функция ВыполнитьПакетВПостроителе(МенеджерВТ)
// Выборка1 с использованием настроек
Построитель.Текст =
«ВЫБРАТЬ
//..
|ПОМЕСТИТЬ ВТ1
|ИЗ
//
|
|{ГДЕ
| Условие1 ,
//….
| ОтборN
| }
|»;
Запрос = Построитель.ПолучитьЗапрос();
Запрос.МенеджерВременныхТаблиц = МенеджерВТ;
Запрос.Текст = Запрос.Текст +
«
|;
|ВЫБРАТЬ
//…
|ИЗ ВТ1 КАК ВТ1
//…
|;
|УНИЧТОЖИТЬ ВТ1;
|»;
Запрос.Выполнить();
// Выборка2 с использованием настроек, но в том же пакете
Построитель.Текст =
«ВЫБРАТЬ
//..
|ПОМЕСТИТЬ ВТ2
|ИЗ
//
|
|{ГДЕ
| Условие2 ,
//….
| ОтборK
| }
|»;
Запрос = Построитель.ПолучитьЗапрос();
Запрос.МенеджерВременныхТаблиц = МенеджерВТ; // менеджер тот же
Запрос.Текст = Запрос.Текст +
«
|;
|ВЫБРАТЬ
//…
|ИЗ ВТ1 КАК ВТ1
|ЛЕВОЕ СОЕДИНЕНИЕ ВТ2 КАК ВТ2
|ПО ВТ1.//…
//…
|;
|УНИЧТОЖИТЬ ВТ1;
|УНИЧТОЖИТЬ ВТ2;
|»;
Возврат Запрос.Выполнить();
КонецФункции
3) На первый взгляд, дополнение 2) уже лучше. Но. Без «Но» ну никуда… Всякий раз, когда текст Построителя меняется, система меняет в соответствии с текстом и коллекцию ДоступныхПолей, в том числе и у отбора. И эта ситуация, мягко говоря, неприятна.
Поэтому перед каждой генерацией запроса от Построителя, необходимо «руками» указывать ему, где он прав и где виноват:
//…
УстановитьОтборИПараметры();
Запрос = Построитель.ПолучитьЗапрос();
//…
Процедура УстановитьОтборИПараметры()
//Отбор
Доступные = Построитель.Отбор.ПолучитьДоступныеПоля();
Поле = Доступные.Найти(«ПараметрОтбора1»);
Если Поле <> Неопределено Тогда
Поле.Отбор = Истина;
Элт = Построитель.Отбор.Найти(«ПараметрОтбора1»);
Если Элт = Неопределено Тогда
Элт = Построитель.Отбор.Добавить(«ПараметрОтбора1»);
//…
Элт.Использование = Истина;
КонецЕсли;
КонецЕсли;
// другие поля отбора…
Построитель.Отбор.УстановитьДоступныеПоля(Доступные);
//ПараметрыДанных
Если НЕ Построитель.Параметры.Свойство(«ПараметрДанных1») Тогда
Построитель.Параметры.Вставить(«ПараметрДанных1»,Истина);
КонецЕсли;
// другие параметры данных…
КонецПроцедуры
4) Еще одно «Но». Чтобы при написании текста пакета (выполнении запроса) совсем уж не задумываться, «где он там найдет все параметры», Построитель нужно проинициализировать каким-нибудь «общим» текстом, в котором будут участвовать все необходимые отборы и параметры. Для этого не обязательно строить Вавилонскую башню, достаточно минимально адекватного запроса вида:
//..
«ВЫБРАТЬ ЛОЖЬ
|ИЗ <ВиртуальнаяТаблица>(&ДатаСреза, &ВидыСубконто {Отбор_1.*} ) КАК Запрос
|{ЛЕВОЕ СОЕДИНЕНИЕ …}
|{ГДЕ Отбор1, Отбор2.* КАК Отбор2}
|»;
//..
5) Вспомним о пользователе. Чтобы он «ничего не заметил», необходимо после вызова функции ВыполнитьПакетВПостроителе() проиницилизировать ПостроительОтчета «общим» текстом и еще раз УстановитьОтборИПараметры().
.. а кто слушал — молодец!

