Группировки СКД собирают записи с одинаковым значением поля в одну строку отчета и считают по ней итоги: продажи по менеджерам, остатки по складам, обороты по группам номенклатуры. Ниже — как добавить группировку строк в схеме компоновки 1С, сгруппировать по нескольким полям, включить иерархию справочника, вложить уровни друг в друга и собрать ту же структуру из кода. Примеры для платформы 8.3, от конфигурации не зависят.
Почти любой заказ на отчет сводится к группировкам, даже если заказчик этого слова не произносит:
Программист задает группировки в схеме, пользователь меняет их в форме отчета — это описано в статье о настройке отчета. Здесь — сторона разработчика.
На закладке «Настройки» конструктора схемы вверху находится дерево структуры. Корень — «Отчет», под ним элементы четырех видов: группировка, таблица, диаграмма и вложенные настройки. Когда группировка выделена, внизу открываются ее собственные настройки:
Группировка без полей называется «Детальные записи» и выводит каждую запись набора данных как есть. Вложенность в дереве — это вложенность уровней в отчете: дочерняя группировка выводится внутри каждой строки родительской.
Группировки строит сама система компоновки, писать СГРУППИРОВАТЬ ПО в запросе для этого не нужно. Если в структуре нет детальных записей, компоновщик сам добавит в запрос группировку по используемым полям и агрегатные функции ресурсов, а итоги по уровням посчитает процессор компоновки. Итоги в строках группировок считаются только по ресурсам — полям с закладки «Ресурсы» схемы. Об устройстве схемы в целом — в статье про схему компоновки данных.
Пример: отчет по продажам, в наборе данных есть поля Менеджер, Контрагент, Номенклатура, Количество и Сумма, последние два объявлены ресурсами.
Получится такая структура:
В отчете строка менеджера показывает его итог, под ней идут клиенты со своими итогами, внутри — отдельные записи. Уровни сворачиваются плюсами слева.
В новой группировке конструктор сам ставит в выбранные поля элемент «Авто». Он выводит поля группировки и все, что выбрано уровнем выше. Поэтому ресурсы достаточно выбрать один раз у «Отчета», а не в каждой группировке.
Группировка полей в СКД не ограничена одним полем. Если поставить в одну группировку несколько полей, строки соберутся по сочетанию значений: «Контрагент + Договор» даст строку на каждую пару и итог по паре, но без промежуточного итога по контрагенту. Вложенные группировки, наоборот, дают отдельный уровень и подытог на каждое поле.
| Вариант | Что в отчете | Когда подходит |
|---|---|---|
| Несколько полей в одной группировке | Один уровень, строка на каждое сочетание значений | Подытог по первому полю не нужен: «Склад + Номенклатура» в ведомости остатков, «Контрагент + Договор» в сверке |
| Вложенные группировки | Уровень на каждое поле, итоги на каждом уровне, свертка плюсами | Нужны промежуточные итоги: продажи по менеджеру, а внутри по клиентам |
Полем группировки может быть любое доступное поле схемы, в том числе реквизит через точку (Контрагент.ОсновнойМенеджер) и вычисляемое поле. Ресурс полем группировки не бывает: в списке выбора его нет. Флажок использования у поля позволяет временно отключить его, не удаляя.
Как поля разных уровней лягут на лист, задает параметр «Расположение полей группировок» на закладке «Другие настройки»: при «Вместе» уровни идут в одной колонке с отступом, при «Отдельно» у каждой группировки своя колонка. Подписи и оформление полей — в статье о полях СКД, а если стандартного вида строки группировки не хватает, для нее рисуют свой макет.
Тип задается для каждого поля группировки отдельно, в колонке «Тип группировки».
| Тип | Что выводится | Пример |
|---|---|---|
| Элементы | Только значения, которые есть в данных, без групп справочника | Список товаров с продажами |
| Иерархия | Группы справочника с итогами на всех уровнях вложенности и элементы внутри них | Продажи по товарным группам с подытогами и товарами |
| Только иерархия | Только группы, без элементов | Свод по товарным группам без расшифровки до товара |
Иерархия работает у полей ссылочного типа с иерархией: иерархический справочник, план счетов, план видов характеристик с иерархией. Если в поле строка (наименование, представление) или справочник без иерархии, тип «Иерархия» не даст групп — отчет выйдет таким же, как с «Элементами». Родителей СКД подбирает сама, выбирать поле Родитель в запросе для этого не нужно.
Частая подмена — группировка по Номенклатура.Родитель. Она дает один уровень, непосредственную группу товара, и итог верхней группы не включает товары из ее подгрупп. Для настоящего дерева групп нужен тип «Иерархия» на самой номенклатуре.
Для отчета по месяцам поле группировки должно содержать дату, приведенную к началу месяца. Проще всего посчитать его в запросе: НАЧАЛОПЕРИОДА(Продажи.Период, МЕСЯЦ) КАК Месяц. Группировка по исходной дате документа даст строку на каждое значение даты и времени, а не на месяц.
У поля группировки с датой есть свойство «Тип дополнения». Если выбрать в нем «Месяц» и задать начало и конец периода, СКД добавит строки за месяцы без данных, и в хронологии не будет пропусков. Границы удобно брать из параметров отчета.
Элемент «Таблица» строит кросс-таблицу из двух веток: группировки строк и группировки колонок. Например, строки — «Менеджер», колонки — «Месяц», ресурс «Сумма» выводится на пересечении, итоги считаются и по строкам, и по колонкам. Внутрь группировки строк можно вложить следующую, как в обычной структуре, и получить «Менеджер → Контрагент» по строкам при тех же месяцах по колонкам.
ИМЕЮЩИЕ в запросе.Из кода структура собирается теми же объектами, что в конструкторе. У настроек (НастройкиКомпоновкиДанных) и у группировки (ГруппировкаКомпоновкиДанных) есть коллекция Структура. Поля группировки лежат в ПоляГруппировки.Элементы, тип — в свойстве ТипГруппировки со значениями системного перечисления ТипГруппировкиКомпоновкиДанных. У таблицы (ТаблицаКомпоновкиДанных) вместо структуры — коллекции Строки и Колонки.
Общий модуль ниже добавляет группировки по списку полей, проверяет, что поле есть в схеме, и собирает две типовые структуры. Настройки берите у инициализированного компоновщика: в форме отчета это Отчет.КомпоновщикНастроек.Настройки.
// Общий модуль ГруппировкиСКД.
// Свойства модуля: Сервер - Истина, Вызов сервера - Ложь.
// Платформа 8.3, режим совместимости не ниже 8.3.6 (СтрРазделить, СтрШаблон).
// Настройки берите у инициализированного компоновщика,
// например Отчет.КомпоновщикНастроек.Настройки в модуле формы отчета.
#Область ПрограммныйИнтерфейс
// Добавляет группировку в корень настроек или внутрь другой группировки.
//
// Параметры:
// Родитель - НастройкиКомпоновкиДанных, ГруппировкаКомпоновкиДанных - куда добавить.
// ИменаПолей - Строка - пути полей через запятую, например "Контрагент, Договор".
// Пустая строка - детальные записи.
// ТипГруппировки - ТипГруппировкиКомпоновкиДанных - по умолчанию Элементы.
//
// Возвращаемое значение:
// ГруппировкаКомпоновкиДанных
//
Функция ДобавитьГруппировку(Родитель, ИменаПолей = "", ТипГруппировки = Неопределено) Экспорт
Группировка = Родитель.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
ЗаполнитьПоляГруппировки(Группировка.ПоляГруппировки, ИменаПолей, ТипГруппировки);
ДобавитьАвтополя(Группировка);
Возврат Группировка;
КонецФункции
// Добавляет таблицу: группировка строк и группировка колонок.
//
// Параметры:
// Родитель - НастройкиКомпоновкиДанных, ГруппировкаКомпоновкиДанных - куда добавить.
// ПоляСтрок - Строка - пути полей через запятую.
// ПоляКолонок - Строка - пути полей через запятую.
//
// Возвращаемое значение:
// ТаблицаКомпоновкиДанных
//
Функция ДобавитьТаблицу(Родитель, ПоляСтрок, ПоляКолонок) Экспорт
Таблица = Родитель.Структура.Добавить(Тип("ТаблицаКомпоновкиДанных"));
Таблица.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
// У строк и колонок таблицы Добавить() вызывается без типа.
Строки = Таблица.Строки.Добавить();
ЗаполнитьПоляГруппировки(Строки.ПоляГруппировки, ПоляСтрок);
ДобавитьАвтополя(Строки);
Колонки = Таблица.Колонки.Добавить();
ЗаполнитьПоляГруппировки(Колонки.ПоляГруппировки, ПоляКолонок);
ДобавитьАвтополя(Колонки);
Возврат Таблица;
КонецФункции
// Оставляет в группировке строки, у которых итог ресурса не меньше порога.
// Отбор по ресурсу проверяет итог группы, а не отдельные записи.
// Итоги вышестоящих группировок и общий итог он не меняет: скрытые группы в них учтены.
//
// Параметры:
// Группировка - ГруппировкаКомпоновкиДанных
// ИмяРесурса - Строка - имя поля-ресурса схемы.
// Порог - Число
//
Процедура ОтобратьПоИтогу(Группировка, ИмяРесурса, Порог) Экспорт
ЭлементОтбора = Группировка.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных(ИмяРесурса);
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.БольшеИлиРавно;
ЭлементОтбора.ПравоеЗначение = Порог;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
// Сортирует строки группировки по одному полю, остальное - автоматически.
//
// Параметры:
// Группировка - ГруппировкаКомпоновкиДанных, ГруппировкаТаблицыКомпоновкиДанных
// ИмяПоля - Строка - путь поля.
// ПоУбыванию - Булево
//
Процедура УпорядочитьГруппировку(Группировка, ИмяПоля, ПоУбыванию = Ложь) Экспорт
Порядок = Группировка.Порядок.Элементы;
Порядок.Очистить();
ЭлементПорядка = Порядок.Добавить(Тип("ЭлементПорядкаКомпоновкиДанных"));
ЭлементПорядка.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
ЭлементПорядка.ТипУпорядочивания = ?(ПоУбыванию,
НаправлениеСортировкиКомпоновкиДанных.Убыв,
НаправлениеСортировкиКомпоновкиДанных.Возр);
ЭлементПорядка.Использование = Истина;
Порядок.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
КонецПроцедуры
// Пример 1. Менеджер → Контрагент → Номенклатура с иерархией групп → детальные записи.
// В наборе данных схемы нужны поля Менеджер, Контрагент, Номенклатура
// и ресурс Сумма.
//
// Параметры:
// Настройки - НастройкиКомпоновкиДанных
//
Процедура ПостроитьСтруктуруПродаж(Настройки) Экспорт
Настройки.Структура.Очистить();
ВыбратьПолеВКорне(Настройки, "Сумма");
ПоМенеджерам = ДобавитьГруппировку(Настройки, "Менеджер");
УпорядочитьГруппировку(ПоМенеджерам, "Сумма", Истина);
ПоКлиентам = ДобавитьГруппировку(ПоМенеджерам, "Контрагент");
ОтобратьПоИтогу(ПоКлиентам, "Сумма", 100000);
ПоТоварам = ДобавитьГруппировку(ПоКлиентам, "Номенклатура",
ТипГруппировкиКомпоновкиДанных.Иерархия);
ДобавитьГруппировку(ПоТоварам); // группировка без полей - детальные записи
КонецПроцедуры
// Пример 2. Менеджеры по строкам, месяцы по колонкам.
// В наборе данных нужно поле Месяц: НАЧАЛОПЕРИОДА(Дата, МЕСЯЦ) КАК Месяц.
//
// Параметры:
// Настройки - НастройкиКомпоновкиДанных
//
Процедура ПостроитьТаблицуПоМесяцам(Настройки) Экспорт
Настройки.Структура.Очистить();
ВыбратьПолеВКорне(Настройки, "Сумма");
ДобавитьТаблицу(Настройки, "Менеджер", "Месяц");
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
// Ресурс выбирается у корня: элемент «Авто» в группировках и таблицах
// выводит поля группировки и выбранные поля вышестоящего уровня.
Процедура ВыбратьПолеВКорне(Настройки, ИмяПоля)
Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
Для Каждого Элемент Из Настройки.Выбор.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ВыбранноеПолеКомпоновкиДанных")
И Элемент.Поле = Поле Тогда
Элемент.Использование = Истина;
Возврат;
КонецЕсли;
КонецЦикла;
ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(
Тип("ВыбранноеПолеКомпоновкиДанных"));
ВыбранноеПоле.Поле = Поле;
ВыбранноеПоле.Использование = Истина;
КонецПроцедуры
Процедура ЗаполнитьПоляГруппировки(ПоляГруппировки, ИменаПолей, ТипГруппировки = Неопределено)
Если ТипГруппировки = Неопределено Тогда
ТипГруппировки = ТипГруппировкиКомпоновкиДанных.Элементы;
КонецЕсли;
Для Каждого ИмяПоля Из СтрРазделить(ИменаПолей, ",", Ложь) Цикл
ПутьПоля = СокрЛП(ИмяПоля);
Если ПустаяСтрока(ПутьПоля) Тогда
Продолжить;
КонецЕсли;
Поле = Новый ПолеКомпоновкиДанных(ПутьПоля);
ПроверитьПолеГруппировки(ПоляГруппировки, Поле, ПутьПоля);
ПолеГруппировки = ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
ПолеГруппировки.Поле = Поле;
ПолеГруппировки.ТипГруппировки = ТипГруппировки;
ПолеГруппировки.Использование = Истина;
КонецЦикла;
КонецПроцедуры
Процедура ПроверитьПолеГруппировки(ПоляГруппировки, Поле, ПутьПоля)
ДоступныеПоля = ПоляГруппировки.ДоступныеПоляПолейГруппировок;
// Настройки без компоновщика доступных полей не знают - проверить не по чему.
Если ДоступныеПоля = Неопределено Тогда
Возврат;
КонецЕсли;
Если ДоступныеПоля.НайтиПоле(Поле) = Неопределено Тогда
ВызватьИсключение СтрШаблон(
НСтр("ru = 'Поле ""%1"" недоступно для группировки: его нет в схеме или это ресурс'"),
ПутьПоля);
КонецЕсли;
КонецПроцедуры
Процедура ДобавитьАвтополя(Группировка)
// То самое "Авто", которое конструктор схемы ставит в новую группировку сам.
Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));
КонецПроцедуры
#КонецОбласти
Вызов из формы собственного отчета: команда перестраивает структуру и сразу формирует результат. В отчетах на БСП у формы свой механизм настроек, там структуру обычно меняют в варианте или в модуле отчета.
// Модуль формы собственного отчета (управляемая форма, отчет без БСП).
// Команда формы СтруктураПоМенеджерам выведена на командную панель.
&НаКлиенте
Процедура СтруктураПоМенеджерам(Команда)
СтруктураПоМенеджерамНаСервере();
СкомпоноватьРезультат(РежимКомпоновкиРезультата.Авто);
КонецПроцедуры
&НаСервере
Процедура СтруктураПоМенеджерамНаСервере()
ГруппировкиСКД.ПостроитьСтруктуруПродаж(Отчет.КомпоновщикНастроек.Настройки);
КонецПроцедуры
Родитель.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных")) — тип указываем явно: в ту же коллекцию добавляются таблицы и диаграммы. Функция работает и для корня настроек, и для вложенного уровня.СтрРазделить(ИменаПолей, ",", Ложь) — пустая строка дает пустой массив, группировка остается без полей и становится детальными записями.ДоступныеПоляПолейГруппировок.НайтиПоле(Поле) — проверка до добавления: опечатка в пути поля или попытка сгруппировать по ресурсу сразу дает понятное исключение, а не странный отчет.АвтоВыбранноеПолеКомпоновкиДанных и АвтоЭлементПорядкаКомпоновкиДанных — то самое «Авто», которое конструктор ставит в новую группировку сам. Из кода его добавляют явно.Таблица.Строки.Добавить() — у строк и колонок таблицы метод вызывается без параметра, там бывают только группировки.ОтобратьПоИтогу — отбор по ресурсу добавлен в группировку, а не в корень настроек, поэтому отбираются группы по итогу. Если «Контрагент» вложен в «Менеджер», порог сравнивается с продажами клиента у конкретного менеджера; чтобы отобрать клиентов по всем продажам, сделайте «Контрагент» верхним уровнем.Номенклатура.Наименование или представление, — либо справочник без иерархии.Таблица.Строки.Добавить(Тип(...)). Для строк и колонок таблицы тип не передается.СГРУППИРОВАТЬ ПО, написанный в запросе набора данных, сворачивает строки до компоновки: детальные записи в отчете будут уже свернутыми, а ресурсы вроде среднего или количества различных посчитаются по свернутым строкам. Группировки СКД строятся по настройкам, бывают вложенными, дают итоги на каждом уровне, и пользователь перестраивает их сам. Уменьшать объем данных вручную не нужно: без детальных записей компоновщик сам сгруппирует запрос. В запросе группируют, когда это нужно для логики, например во временной таблице или вложенном запросе.
В отчете на БСП откройте «Настройки», переключитесь в расширенный режим и добавьте группировку в структуру. В отчете со стандартной формой платформы выберите «Еще → Изменить вариант...»: там такое же дерево структуры, как в конструкторе схемы. Чтобы результат не потерялся, сохраните его как вариант отчета.
У корня «Отчет» на закладке «Другие настройки» есть параметр «Расположение общих итогов по вертикали», выберите в нем «Конец». Для итогов отдельной группировки то же делает параметр «Расположение итогов» на закладке «Другие настройки» самой группировки.
Пользователь сворачивает уровни кнопками с номерами над табличным документом. Если отчет формируется вашим кодом, после вывода вызовите у табличного документа ПоказатьУровеньГруппировокСтрок(0) — останется только верхний уровень.
Две-три группировки в конструкторе собираются быстро. Если же нужен отчет в типовой конфигурации без снятия с поддержки, с иерархией по нестандартному полю, кросс-таблицей и своей расшифровкой, быстрее отдать его программисту: доработка отчетов и обработок 1С. Разместите задачу на площадке — оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.