v8: Функция для вывода отчета с группировками с помощью построителя отчетаФункция, с помощью которой можно быстро и удобно вывести отчет с группировками (а-ля сводная таблица), с произвольным порядком группировок и составом итогов. Достаточно только указать параметры, функция сделает все сама. | | Автор статьи: Гений 1С | Редакторы: Волшебник, Последняя редакция №6 от 14.07.06 | История URL: http://kb.mista.ru/article.php?id=293 | |
Ключевые слова: построитель,отчет
Построитель отчета - мощная штука для быстрого написания отчетов.
Однако иногда хочется использовать свои макеты, да и просто хотелось бы иметь "рыбу", которую можно было бы быстро использовать для написания отчета, особенно если данные берутся из таблицы значений.
Это именно такая "рыба".
Я предлагаю функцию обПостроительВывестиПоГруппировкам, которая занимается выводом таблицы значений с помощью построителя отчета с заданными группировками, итогами и параметрами группировок.
Итоги можно использовать любые - количество, сумма, среднее.
Пока еще не поддерживается сортировка, именно поэтому список параметров передается в виде структуры, чтобы можно было добавлять свои параметры.
Используется гибкое управление параметрами:
= Если не задан макет, то замена макета не производится
= Если не заданы параметры построителя, то они и не назначаются
= Может использоваться в качестве источника не только таблица значений, но и результат запроса
= Если не задан табличный документ, то она не выводится
Пример вызова функции:
Макет=Макеты.Получить("МакетПостроителя");
ПараметрыПостроителя=Новый Структура(
"РазмещениеИзмеренийВСтроках,РазмещениеРеквизитовИзмеренийВСтроках, РазмещениеРеквизитовИзмеренийВКолонках,ВыводитьОбщиеИтоги",
ТипРазмещенияИзмерений.Отдельно, ТипРазмещенияРеквизитовИзмерений.Вместе, ТипРазмещенияРеквизитовИзмерений.Вместе, истина);
спзИтоги=Новый СписокЗначений();
спзИтоги.Добавить("Остаток","Сумма");
спзГруппы=Новый СписокЗначений();
спзГруппы.Добавить("Товар");
спзГруппы.Добавить("Склад");
обПостроительВывестиПоГруппировкам(Новый Структура(
"Источник, Таб, Макет, Группы, Итоги, ПараметрыПостроителя",
ТЗ, Т, Макет, спзГруппы, спзИтоги, ПараметрыПостроителя));
Структура макета
Строки с уровнями именуются Уровень0, Уровень1, ...
Колонки с уровнями именуются кУровень0, кУровень1, …
Детальная информация по строкам именуется кДетали.
Общие итоги именуются ОбщиеИтоги, шапка таблицы - ШапкаТаблицы, подвал таблицы - ПодвалТаблицы.
Может быть на картинке не заметно, но колонки с итогами содержат параметры, которые называются так же, как итоги в таблице значений, т.е. например "Сумма", "Остаток", "Количество".
Кроме измерений и итогов, можно выводить доп.параметры, например на рисунке виден параметр Адрес.
Замечания по коду
Пусть у нас есть некая таблица значений ТЗ.
Построитель отчета, привязанный к этой таблице значений, создается так:
ПостроительОтчета=Новый ПостроительОтчета();
ПостроительОтчета.ИсточникДанных=Новый ОписаниеИсточникаДанных(ТЗ);
Допустим, в списке значений спзГруппы у нас находится список колонок-группировок для отчета, в структуре спзИтоги - список колонок-итогов (колонки-итоги должны иметь явно указанный тип число, иначе не будет суммироваться итог).
Нужно указать, что колонки спзГруппы будут измерениями построителя - функция обПостроительОтчетаУстановитьИзмерения.
Нужно указать, что колонки спзИтоги будут итогами построителя и назначить им некоторую функцию итогов (Количество,Сумма) - функция обПостроительОтчетаУстановитьИтоги.
Затем вызывает заполнение настроек построителя:
ПостроительОтчета.ЗаполнитьНастройки();
Настройки построителя сформировались, но порядок измерений может не соответствовать тому порядку, который есть у нас в стрГруппы, нужно поправить порядок групп - функция обПостроительОтчетаСкорректироватьПорядокИзмерений.
Затем мы выполняем построитель и заполняем параметры вывода макета:
ПостроительОтчета.Выполнить();
Теперь нужно подставить в построитель наш собственный макет. Но в макете построителя и в нашем названия групп могут не совпадать, поэтому нужно скорректировать названия. В переменной Макет хранится наш макет, мы его обработаем и подставим в макет построителя:
ПостроительОтчета.Макет=ПреобразоватьМакетПостроителя(Макет, спзГруппы);
Затем мы заполняем параметры вывода макета:
ЗаполнитьЗначенияСвойств(ПостроительОтчета, ПараметрыПостроителя);
Ну и теперь можно вывести результаты построителя в табличный документ:
ПостроительОтчета.Вывести(Таб);
Библиотека функций
Вот исходный код библиотеки функций:
Функция обПостроительВывестиПоГруппировкам(П)
Перем Источник, Таб, Макет, спзГруппы, спзИтоги, ПараметрыПостроителя, ПостроительОтчета;
П.Свойство("Источник", Источник);
П.Свойство("Таб", Таб);
П.Свойство("Макет", Макет);
П.Свойство("Группы", спзГруппы);
П.Свойство("Итоги", спзИтоги);
П.Свойство("ПараметрыПостроителя", ПараметрыПостроителя);
ПостроительОтчета=Новый ПостроительОтчета();
ПостроительОтчета.ИсточникДанных=Новый ОписаниеИсточникаДанных(Источник);
обПостроительОтчетаУстановитьИзмерения(ПостроительОтчета, спзГруппы);
обПостроительОтчетаУстановитьИтоги(ПостроительОтчета, спзИтоги);
ПостроительОтчета.ЗаполнитьНастройки();
обПостроительОтчетаСкорректироватьПорядокИзмерений(ПостроительОтчета, спзГруппы);
ПостроительОтчета.Выполнить();
Если Макет<>Неопределено Тогда
ПостроительОтчета.Макет=обПостроительПреобразоватьМакет(Макет, спзГруппы);
КонецЕсли;
Если ПараметрыПостроителя<>Неопределено Тогда
ЗаполнитьЗначенияСвойств(ПостроительОтчета, ПараметрыПостроителя);
КонецЕсли;
обПостроительПреобразоватьМакет(Макет, спзГруппы);
Если Таб<>Неопределено Тогда
ПостроительОтчета.Вывести(Таб);
КонецЕсли;
П.Вставить("ПостроительОтчета", ПостроительОтчета);
Возврат ПостроительОтчета;
КонецФункции
Функция обПостроительОтчетаУстановитьИзмерения(ПостроительОтчета, спзГруппы)
Перем Эл;
Для Каждого Эл из спзГруппы Цикл
ПостроительОтчета.ИсточникДанных.Колонки[Эл.Значение].Измерение=истина;
КонецЦикла;
КонецФункции
Функция обПостроительОтчетаУстановитьИтоги(ПостроительОтчета,спзИтоги)
Перем Эл;
Для Каждого Эл Из спзИтоги Цикл
ПостроительОтчета.ИсточникДанных.Колонки[Эл.Значение].Итог = ""+Эл.Представление+"("+Эл.Значение+")";
КонецЦикла;
КонецФункции
Функция обПостроительОтчетаСкорректироватьПорядокИзмерений(ПостроительОтчета, спзГруппы)
Перем Уровень, Эл, ИмяГруппировки, Элементы, Элемент;
Уровень=0;
Для Каждого Эл из спзГруппы Цикл
ИмяГруппировки=Эл.Значение;
Элементы=ПостроительОтчета.ИзмеренияСтроки;
Элемент=Элементы.Найти(ИмяГруппировки);
Если Элемент<>Неопределено Тогда
Элементы.Сдвинуть(Элемент, Уровень-Элементы.Индекс(Элемент));
Уровень=Уровень+1;
КонецЕсли;
КонецЦикла;
КонецФункции
//Заменяет названия уровней на конкретные названия полей
Функция обПостроительПреобразоватьМакет(Макет, спзГруппы)
Перем Эл, Уровень, ИмяУровня, ИмяГруппы, НазваниеГруппы, сУровеньПуть;
Для Каждого Эл ИЗ спзГруппы Цикл
Уровень=спзГруппы.Индекс(Эл);
ИмяУровня="Уровень"+Уровень;
ИмяГруппы=Эл.Значение;
НазваниеГруппы=Эл.Представление;
обМакетЗаменитьТекст(Макет, "Параметр", ИмяУровня, ИмяГруппы);
обМакетЗаменитьТекст(Макет, "Текст", "имя"+ИмяУровня, НазваниеГруппы);
обМакетПереименоватьОбласть(Макет, ""+ИмяУровня, ИмяГруппы);
КонецЦикла;
сУровеньПуть="";
Для Каждого Эл ИЗ спзГруппы Цикл
сУровеньПуть=сУровеньПуть+?(сУровеньПуть="","",Символы.ПС)+Эл.Представление;
КонецЦикла;
обМакетЗаменитьТекст(Макет, "Текст", "УровеньПуть", сУровеньПуть);
//Убираем ненужные группировки и реквизиты в колонках
Уровень=спзГруппы.Количество();
Пока Истина Цикл
ИмяУровня="кУровень"+Уровень;
Область=Макет.Области.Найти(ИмяУровня);
Если Область=Неопределено Тогда
Прервать;
КонецЕсли;
Макет.УдалитьОбласть(Область,ТипСмещенияТабличногоДокумента.ПоГоризонтали);
Уровень=Уровень+1;
КонецЦикла;
Возврат Макет;
КонецФункции
Функция обМакетЗаменитьТекст(Макет, Параметр, сИсточник, сЗамена)
Перем Область, СледОбласть;
СледОбласть=Неопределено;
Пока (истина) Цикл
Область=Макет.НайтиТекст(сИсточник,СледОбласть);
Если Область=Неопределено Тогда
Прервать;
КонецЕсли;
Если Область[Параметр]=сИсточник тогда
Область[Параметр]=сЗамена;
КонецЕсли;
СледОбласть=Область;
КонецЦикла;
КонецФункции
Функция обМакетПереименоватьОбласть(Макет, сИсточник, сЗамена)
Перем Область;
Область=Макет.Области.Найти(сИсточник);
Если Область<>Неопределено Тогда
Область.Имя=сЗамена;
КонецЕсли;
КонецФункции |