Книга знаний

1С:Предприятие / v8 / Объекты конфигурации / Отчеты

v8: Функция для вывода отчета с группировками с помощью построителя отчета

Функция, с помощью которой можно быстро и удобно вывести отчет с группировками (а-ля сводная таблица), с произвольным порядком группировок и составом итогов. Достаточно только указать параметры, функция сделает все сама.Автор статьи: Гений 1С | Редакторы: Волшебник,
Последняя редакция №4 от 14.07.06 | История
URL: http://kb.mista.ru/article.php?id=293

Ключевые слова: построитель,отчет


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

Я предлагаю функцию обПостроительВывестиПоГруппировкам, которая занимается выводом таблицы значений с помощью построителя отчета с заданными группировками, итогами и параметрами группировок.
Итоги можно использовать любые - количество, сумма, среднее.
Пока еще не поддерживается сортировка, именно поэтому список параметров передается в виде структуры, чтобы можно было добавлять свои параметры.
Используется гибкое управление параметрами:
= Если не задан макет, то замена макета не производится
= Если не заданы параметры построителя, то  они и не назначаются
= Может использоваться в качестве источника не только таблица значений, но и результат запроса
= Если не задан табличный документ, то она не выводится

Пример вызова функции:

Макет=Макеты.Получить("МакетПостроителя");
ПараметрыПостроителя=Новый Структура(
        "РазмещениеИзмеренийВСтроках,РазмещениеРеквизитовИзмеренийВСтроках, РазмещениеРеквизитовИзмеренийВКолонках,ВыводитьОбщиеИтоги", 
        ТипРазмещенияИзмерений.Отдельно, ТипРазмещенияРеквизитовИзмерений.Вместе, ТипРазмещенияРеквизитовИзмерений.Вместе, истина);

спзИтоги=Новый СписокЗначений();
    спзИтоги.Добавить("Остаток","Сумма");
спзГруппы=Новый СписокЗначений();
    спзГруппы.Добавить("Товар");
    спзГруппы.Добавить("Склад");

обПостроительВывестиПоГруппировкам(Новый Структура(
        "Источник, Таб, Макет, Группы, Итоги, ПараметрыПостроителя",
        ТЗ, Т, Макет, спзГруппы, спзИтоги, ПараметрыПостроителя));


Структура макета


А вот сюда ДОБРЫЙ ДЯДЯ ВОЛШЕБНИК вставит мою картинку, которую я вышлю по почте.
<<Использование построителя отчета с таблицами.JPG>>

Строки с уровнями именуются Уровень0, Уровень1, ...
Колонки с уровнями именуются кУровень0, кУровень1, …
Детальная информация по строкам именуется кДетали.
Общие итоги именуются ОбщиеИтоги, шапка таблицы - ШапкаТаблицы, подвал таблицы - ПодвалТаблицы.



Замечания по коду


Пусть у нас есть некая таблица значений ТЗ.
Построитель отчета, привязанный к этой таблице значений, создается так:
ПостроительОтчета=Новый ПостроительОтчета();
ПостроительОтчета.ИсточникДанных=Новый ОписаниеИсточникаДанных(ТЗ);


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

Нужно указать, что колонки спзГруппы будут измерениями построителя - функция обПостроительОтчетаУстановитьИзмерения.
Нужно указать, что колонки спзИтоги будут итогами построителя и назначить им некоторую функцию итогов  (Количество,Сумма) - функция обПостроительОтчетаУстановитьИтоги.
Затем вызывает заполнение настроек построителя:
ПостроительОтчета.ЗаполнитьНастройки();


Настройки построителя сформировались, но порядок измерений может не соответствовать тому порядку, который есть у нас в стрГруппы, нужно поправить порядок групп - функция обПостроительОтчетаСкорректироватьПорядокИзмерений.

Затем мы выполняем построитель и заполняем параметры вывода макета:
ПостроительОтчета.Выполнить();


Теперь нужно подставить в построитель наш собственный макет. Но в макете построителя и в нашем названия групп могут не совпадать, поэтому нужно скорректировать названия. В переменной Макет хранится наш макет, мы его обработаем и подставим в макет построителя:
ПостроительОтчета.Макет=ПреобразоватьМакетПостроителя(Макет, спзГруппы);


Затем мы заполняем параметры вывода макета:
ЗаполнитьЗначенияСвойств(ПостроительОтчета, ПараметрыПостроителя);


Ну и теперь можно вывести результаты построителя в табличный документ:
ПостроительОтчета.Вывести(Таб);


Библиотека функций


Вот исходный код библиотеки функций:

Функция обПостроительВывестиПоГруппировкам(П)
    Перем Источник, Таб, Макет, спзГруппы, спзИтоги, ПараметрыПостроителя, ПостроительОтчета;
    П.Свойство("Источник", Источник);
    П.Свойство("Таб", Таб);
    П.Свойство("Макет", Макет);
    П.Свойство("Группы", спзГруппы);
    П.Свойство("Итоги", спзИтоги);
    П.Свойство("ПараметрыПостроителя", ПараметрыПостроителя);
    
    ПостроительОтчета=Новый ПостроительОтчета();
    ПостроительОтчета.ИсточникДанных=Новый ОписаниеИсточникаДанных(Источник);
    обПостроительОтчетаУстановитьИзмерения(ПостроительОтчета, спзГруппы);
    обПостроительОтчетаУстановитьИтоги(ПостроительОтчета, спзИтоги);

    ПостроительОтчета.ЗаполнитьНастройки();
    обПостроительОтчетаСкорректироватьПорядокИзмерений(ПостроительОтчета, спзГруппы);
    ПостроительОтчета.Выполнить();
    Если Макет<>Неопределено Тогда
        ПостроительОтчета.Макет=обПостроительПреобразоватьМакет(Макет, спзГруппы);
    КонецЕсли;
    Если ПараметрыПостроителя<>Неопределено Тогда
        ЗаполнитьЗначенияСвойств(ПостроительОтчета, ПараметрыПостроителя);
    КонецЕсли;
    обПостроительПреобразоватьМакет(Макет, спзГруппы);
    Если Таб<>Неопределено Тогда
        ПостроительОтчета.Вывести(Таб);
    КонецЕсли;
    
    П.Вставить("ПостроительОтчета", ПостроительОтчета);
    
    Возврат ПостроительОтчета;
КонецФункции

Функция обПостроительОтчетаУстановитьИзмерения(ПостроительОтчета, спзГруппы)
    Перем Эл;
    Для Каждого Эл из спзГруппы Цикл
        ПостроительОтчета.ИсточникДанных.Колонки[Эл.Значение].Измерение=истина;
    КонецЦикла;
КонецФункции

Функция обПостроительОтчетаУстановитьИтоги(ПостроительОтчета,спзИтоги)
    Перем Эл;
    Для Каждого Эл Из спзИтоги Цикл
        ПостроительОтчета.ИсточникДанных.Колонки[Эл.Значение].Итог = ""+Эл.Представление+"("+Эл.Значение+")";
    КонецЦикла;
КонецФункции

Функция обПостроительОтчетаСкорректироватьПорядокИзмерений(ПостроительОтчета, спзГруппы)
    Перем Уровень, Эл, ИмяГруппировки, Элементы, Элемент;
    Уровень=0;
    Для Каждого Эл из спзГруппы Цикл
        ИмяГруппировки=Эл.Значение;
        Элементы=ПостроительОтчета.ИзмеренияСтроки;
        Элемент=Элементы.Найти(ИмяГруппировки);
        Если Элемент<>Неопределено Тогда
            Элементы.Сдвинуть(Элемент, Уровень-Элементы.Индекс(Элемент));
            Уровень=Уровень+1;
        КонецЕсли;
    КонецЦикла;
КонецФункции


//Заменяет названия уровней на конкретные названия полей
Функция обПостроительПреобразоватьМакет(Макет, спзГруппы)
    Перем Эл, Уровень, ИмяУровня, ИмяГруппы, НазваниеГруппы, сУровеньПуть;
    
    Для Каждого Эл ИЗ спзГруппы Цикл
        Уровень=спзГруппы.Индекс(Эл);
        ИмяУровня="Уровень"+Уровень;
        ИмяГруппы=Эл.Значение;
        НазваниеГруппы=Эл.Представление;
        обМакетЗаменитьТекст(Макет, "Параметр", ИмяУровня, ИмяГруппы);
        обМакетЗаменитьТекст(Макет, "Текст", "имя"+ИмяУровня, НазваниеГруппы);
        обМакетПереименоватьОбласть(Макет, ""+ИмяУровня, ИмяГруппы);
    КонецЦикла;
    
    сУровеньПуть="";
    Для Каждого Эл ИЗ спзГруппы Цикл
        сУровеньПуть=сУровеньПуть+?(сУровеньПуть="","",Символы.ПС)+Эл.Представление;
    КонецЦикла;
    обМакетЗаменитьТекст(Макет, "Текст", "УровеньПуть", сУровеньПуть);
    
    //Убираем ненужные группировки и реквизиты в колонках
    Уровень=спзГруппы.Количество();
    Пока Истина Цикл
        ИмяУровня="кУровень"+Уровень;
        Область=Макет.Области.Найти(ИмяУровня);
        Если Область=Неопределено Тогда
            Прервать;
        КонецЕсли;
        Макет.УдалитьОбласть(Область,ТипСмещенияТабличногоДокумента.ПоГоризонтали);
        Уровень=Уровень+1;
    КонецЦикла;

    Возврат Макет;
КонецФункции

Функция обМакетЗаменитьТекст(Макет, Параметр, сИсточник, сЗамена)
    Перем Область, СледОбласть;
    СледОбласть=Неопределено;
    Пока (истина) Цикл
        Область=Макет.НайтиТекст(сИсточник,СледОбласть);
        Если Область=Неопределено Тогда
            Прервать;
        КонецЕсли;
        Если Область[Параметр]=сИсточник тогда
            Область[Параметр]=сЗамена;
        КонецЕсли;
        СледОбласть=Область;
    КонецЦикла;
КонецФункции

Функция обМакетПереименоватьОбласть(Макет, сИсточник, сЗамена)
    Перем Область;
    Область=Макет.Области.Найти(сИсточник);
    Если Область<>Неопределено Тогда
        Область.Имя=сЗамена;
    КонецЕсли;
КонецФункции

Описание | Рубрикатор | Поиск | ТелепатБот | Захваченные статьи | Установки | Форум
© Станислав Митичкин (Волшебник), 2005-2025 | Mista.ru

Яндекс.Метрика