Как в СКД сгруппировать данные в одну строку: решаем проблему дублирования записей

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При разработке отчетов в системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда один и тот же запрос в консоли запросов выдает компактную таблицу с одной строкой на объект, а в итоговом отчете СКД данные «расползаются» на несколько строк. Особенно остро эта проблема проявляется при сравнении показателей за разные периоды (например, цен или остатков), когда вместо одной строки с двумя колонками мы получаем две строки, в каждой из которых заполнена только одна колонка.

В этой статье мы подробно разберем, почему так происходит, проанализируем структуру запроса и настройки компоновки, а также изучим несколько способов «победить» СКД и заставить ее выводить данные именно так, как нам нужно.

Анализ проблемы и исходного запроса

Рассмотрим типовую ситуацию. Нам нужно сравнить цены номенклатуры на две разные даты. Для этого в запросе часто используется объединение (ОБЪЕДИНИТЬ ВСЕ) из двух срезов последних регистра сведений ЦеныНоменклатуры.

Посмотрим на пример кода, который часто используется в таких случаях:


ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура КАК Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Характеристика КАК Характеристика,
    ЦеныНоменклатурыСрезПоследних.Цена КАК ЦенаНаПервуюДату,
    0 КАК ЦенаНаВторуюДату
ПОМЕСТИТЬ ВТ_Цены
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ПериодНаПервуюДату, ) КАК ЦеныНоменклатурыСрезПоследних

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
    ЦеныНоменклатурыСрезПоследних.Номенклатура,
    ЦеныНоменклатурыСрезПоследних.Характеристика,
    0,
    ЦеныНоменклатурыСрезПоследних.Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&ПериодНаВторуюДату, ) КАК ЦеныНоменклатурыСрезПоследних;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    ВТ_Цены.Номенклатура,
    ВТ_Цены.Характеристика,
    СУММА(ВТ_Цены.ЦенаНаПервуюДату) КАК ЦенаНаПервуюДату,
    СУММА(ВТ_Цены.ЦенаНаВторуюДату) КАК ЦенаНаВторуюДату
ИЗ
    ВТ_Цены КАК ВТ_Цены
СГРУППИРОВАТЬ ПО
    ВТ_Цены.Номенклатура,
    ВТ_Цены.Характеристика

В консоли запросов такой код вернет одну строку по каждой номенклатуре. Однако в СКД результат может быть иным. Причина кроется в том, что СКД — это не просто «исполнитель запроса», а интеллектуальный генератор отчетов, который накладывает свои механизмы группировки поверх текста запроса.

Способ 1. Настройка ресурсов (вкладка «Ресурсы»)

Самая распространенная причина разделения строк — это отсутствие полей в списке ресурсов. Если вы добавили поля ЦенаНаПервуюДату и ЦенаНаВторуюДату в выбранные поля, но не определили их как ресурсы, СКД будет воспринимать их как детальные записи.

Разберем по шагам, что нужно сделать:

  1. Перейдем на вкладку Ресурсы в схеме компоновки данных.
  2. Перенесем числовые поля (цены) в правую колонку.
  3. Убедимся, что в колонке «Выражение» установлена функция СУММА(ЦенаНаПервуюДату).

Важный нюанс: если поле не является ресурсом, СКД пытается найти уникальное сочетание всех выбранных полей. Так как в одной строке результата запроса (до финальной агрегации СКД) цена на вторую дату равна 0, а в другой — наоборот, СКД считает эти записи уникальными и выводит их отдельно. Как только мы делаем их ресурсами, система понимает, что их нужно «схлопнуть» по полям группировки.

Способ 2. Правильная структура настроек группировки

Часто в настройках отчета (вкладка «Настройки») разработчики оставляют стандартный элемент «Детальные записи». Это заставляет систему выводить каждую строку, полученную из базы данных, без дополнительной обработки.

Рассмотрим правильный подход к структуре:

  1. Удалим элемент «Детальные записи» из иерархии настроек.
  2. Нажмем правую кнопку мыши на корневом элементе «Отчет» и выберем «Новая группировка».
  3. В списке полей выберем Номенклатура и Характеристика.
  4. Перейдем на вкладку «Выбранные поля» для этой конкретной группировки и добавим туда наши цены.

Таким образом, мы явно указываем компоновщику, по каким полям нужно производить объединение данных.

Способ 3. Настройка ролей полей в наборе данных

Иногда СКД автоматически неправильно определяет роли полей, особенно если включен флаг «Автозаполнение». Проанализируем колонку «Роль» на вкладке «Наборы данных».

Что нужно проверить:

Способ 4. Обработка пустых характеристик

Выясним причину, связанную с типами данных. В 1С пустая ссылка на справочник и значение NULL — это разные вещи. Если в одном срезе последних характеристика не заполнена (пустая ссылка), а в другом запросе объединения она подтягивается как-то иначе, СКД может увидеть разницу.

Чтобы исключить эту проблему, рекомендуется в тексте запроса использовать функцию ЕСТЬNULL для всех ссылочных полей, по которым идет группировка:


ВЫБРАТЬ
    ЕСТЬNULL(Цены.Характеристика, ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)) КАК Характеристика

Это гарантирует, что «пустоты» во всех частях объединения будут идентичны, и группировка отработает корректно.

Способ 5. Использование связей наборов данных

Профессиональный способ решения таких задач в СКД — это отказ от оператора ОБЪЕДИНИТЬ ВСЕ внутри одного запроса в пользу двух отдельных наборов данных.

Посмотрим, как это реализовать:

  1. Создадим Набор данных 1 с запросом цен на первую дату.
  2. Создадим Набор данных 2 с запросом цен на вторую дату.
  3. Перейдем на вкладку Связи наборов данных.
  4. Свяжем их по полям Номенклатура и Характеристика. В качестве источника связи выберем первый набор, в качестве приемника — второй.

В этом случае СКД сама выполнит соединение записей. Это наиболее надежный метод, который позволяет избежать проблем с «размножением» строк при сложных условиях в запросе.

Способ 6. Вычисляемые поля для итоговых показателей

Если вам нужно не просто вывести цены, но и посчитать разницу или процент изменения, крайне не рекомендуется делать это в тексте запроса перед группировкой. Рассмотрим пример: если мы считаем разницу в запросе, а потом в СКД выводим ее как ресурс СУММА, мы можем получить правильный итог, но сама формула может мешать СКД группировать строки.

Рекомендуемый алгоритм:

  1. Вычисляйте только базовые показатели (цены) в запросе.
  2. На вкладке Вычисляемые поля добавьте поле ПроцентИзменения.
  3. На вкладке Ресурсы укажите формулу для этого поля, используя агрегатные функции: (СУММА(ЦенаНаВторуюДату) - СУММА(ЦенаНаПервуюДату)) / СУММА(ЦенаНаПервуюДату) * 100.

Расчет ресурсов происходит на самом последнем этапе компоновки, когда все строки уже сгруппированы. Это гарантирует точность вычислений и чистоту группировки по строкам.

Заключение

Подведем итог. Чтобы данные в СКД выводились в одну строку, необходимо обеспечить единство ключевых полей (измерений) и перенести все числовые показатели в Ресурсы. Если простые настройки не помогают, следует проверить роли полей на предмет игнорирования NULL или перейти к архитектуре с несколькими наборами данных и их связями в самой СКД. Помните, что Детальные записи в настройках — это главный враг группировки, их стоит использовать только в простых плоских списках.

← На главную