При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда результат запроса выдает избыточное количество строк. Например, если один и тот же сотрудник фигурирует в нескольких записях с разными суммами, отчет может вывести их отдельными строками, в то время как нам необходимо получить одну строку с итоговой суммой по этому человеку. Рассмотрим подробно, как правильно настроить «схлопывание» строк и суммирование ресурсов в 1С 8.3.
Самый очевидный способ решить задачу на уровне получения данных — использовать конструкцию СГРУППИРОВАТЬ ПО непосредственно в языке запросов. Это позволяет объединить идентичные строки еще до того, как они попадут в компоновщик. Проанализируем, как должен выглядеть такой запрос.
Для того чтобы строки объединились, все поля, которые не являются суммируемыми (агрегируемыми), должны быть перечислены в секции группировки. Разберем пример кода:
ВЫБРАТЬ
Сотрудники.Фамилия КАК Фамилия,
Сотрудники.Имя КАК Имя,
Сотрудники.Отчество КАК Отчество,
Сотрудники.Счет КАК Счет,
СУММА(Сотрудники.Сумма) КАК Сумма
ИЗ
Справочник.Сотрудники КАК Сотрудники
ГДЕ
...
СГРУППИРОВАТЬ ПО
Сотрудники.Фамилия,
Сотрудники.Имя,
Сотрудники.Отчество,
Сотрудники.Счет
Важное замечание: Как справедливо отмечено в обсуждении, использование только строковых полей (Фамилия, Имя, Отчество) может привести к ошибкам, если в базе есть полные тезки. Чтобы этого избежать, всегда добавляйте в группировку уникальный идентификатор объекта — ссылку.
ВЫБРАТЬ
СотрудникСсылка КАК Сотрудник,
СУММА(Сумма) КАК Сумма
ИЗ
РегистрНакопления.Начисления КАК Начисления
СГРУППИРОВАТЬ ПО
СотрудникСсылка
СКД — это мощный инструмент, который умеет выполнять агрегацию данных автоматически, даже если в самом запросе нет группировки. Этот метод является более гибким и предпочтительным в профессиональной разработке. Выясним, как его настроить.
Сумма из левого списка в правый.Сумма(Сумма). Это означает, что при любом уровне группировки в отчете данное поле будет складываться.Сумма выбрано для вывода.Преимущество этого метода в том, что если пользователь захочет изменить структуру отчета (например, убрать группировку по счету), СКД мгновенно пересчитает итоги без изменения кода запроса.
Рассмотрим ситуацию подробнее: у нас есть два Ивановых Алексея Петровича. Если мы сгруппируем их только по ФИО, их суммы сложатся в одну строку, что будет фактической ошибкой. Чтобы этого не произошло, проанализируем роль ссылочных типов.
В СКД правильно группировать данные по полю, содержащему ссылку на справочник (например, СправочникСсылка.Сотрудники). Но как тогда вывести красивые колонки «Фамилия», «Имя», «Отчество» в одну строку? Сделаем следующее:
Сотрудник (ссылка).Сотрудник.Сотрудник через «плюсик» и выберем нужные реквизиты: Сотрудник.Фамилия, Сотрудник.Имя, Сотрудник.Отчество.Таким образом, СКД будет различать людей по их внутреннему уникальному идентификатору (ссылке), но в отчете мы увидим привычное текстовое представление.
Часто СКД по умолчанию выводит данные в виде иерархического дерева (группировка сверху, детальные записи снизу). Чтобы получить плоскую таблицу, как в примере автора вопроса, выполним следующие шаги:
Это заставит систему выводить все поля группировки в одной строке, имитируя обычный список, но с корректно рассчитанными суммами.
Проанализируем ситуацию с полем Счет. В исходном вопросе данные объединяются, так как счета у Иванова совпадают (33 и 33). Однако, если в одной строке будет счет 33, а в другой 44, простая группировка их не объединит, так как значения в строках разные.
Если ваша задача — получить общую сумму по сотруднику независимо от счета, то поле Счет нельзя включать в группировку и выбранные поля детальных записей. Если же счет важен, он должен стать частью ключа группировки. В случае, когда нужно вывести «хоть какой-нибудь» счет (например, первый попавшийся), в запросе можно использовать агрегатную функцию МАКСИМУМ(Счет).
Резюмируем: Для корректного объединения строк в СКД используйте вкладку «Ресурсы» для числовых данных и группируйте данные по ссылкам на объекты, а не по строковым представлениям. Это гарантирует точность отчета даже при наличии дублирующейся информации или тезок в базе данных.