Как вывести несколько дополнительных свойств объекта в одну строку отчета СКД

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

При разработке отчетов в конфигурации «Управление производственным предприятием» (УПП) или других решениях на платформе «1С:Предприятие 8» разработчики часто сталкиваются с необходимостью вывода дополнительных свойств объектов. Эти свойства (например, «Размер обуви», «Размер одежды», «Цвет») хранятся в регистре сведений ЗначенияСвойствОбъектов в «вертикальном» виде. Проблема заключается в том, что при обычном соединении регистра с основной таблицей (например, со справочником сотрудников) на каждое свойство создается отдельная строка, что приводит к дублированию данных в отчете. Рассмотрим подробнее, как решить эту задачу и вывести все свойства в одну строку.

Причина возникновения дублей в запросе

Проанализируем ситуацию: в регистре ЗначенияСвойствОбъектов записи хранятся в разрезе измерений Объект и Свойство. Если у одного сотрудника заполнено два свойства, то в регистре это две разные записи. Когда мы выполняем простое ЛЕВОЕ СОЕДИНЕНИЕ по полю Объект, система находит две подходящие записи и закономерно выводит две строки для одного сотрудника. Использование конструкции ВЫБОР КОГДА внутри одного соединения не помогает «схлопнуть» строки, так как условие выполняется для каждой записи регистра отдельно.

Способ 1. Использование нескольких левых соединений

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

Разберем этот метод на примере кода. Предположим, нам нужно вывести размер обуви и размер одежды для сотрудника:


ВЫБРАТЬ
    Работники.Сотрудник КАК Сотрудник,
    РазмерыОбуви.Значение КАК РазмерОбуви,
    РазмерыОдежды.Значение КАК РазмерОдежды
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних(&Период, ) КАК Работники
    
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК РазмерыОбуви
        ПО Работники.Сотрудник = РазмерыОбуви.Объект
        И РазмерыОбуви.Свойство = &Свойство_РазмерОбуви
        
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК РазмерыОдежды
        ПО Работники.Сотрудник = РазмерыОдежды.Объект
        И РазмерыОдежды.Свойство = &Свойство_РазмерОдежды

Преимущества метода:

  1. Простота написания и понимания логики.
  2. Каждое свойство попадает в свою колонку, и строки не дублируются.

Недостатки:

  1. При большом количестве свойств запрос становится громоздким.
  2. Каждое соединение создает дополнительную нагрузку на СУБД.

Способ 2. Механизм характеристик в СКД (Рекомендуемый)

Система компоновки данных (СКД) обладает встроенным механизмом для работы с дополнительными свойствами и категориями. Это «правильный» архитектурный подход в 1С. Если настроить характеристики, то свойства будут доступны в списке полей через «точку» от объекта (например, Сотрудник.[Размер обуви]), как если бы они были реквизитами справочника.

Выполним настройку по шагам:

  1. Откроем схему компоновки данных и перейдем на вкладку «Характеристики».
  2. Нажмем кнопку добавить. В поле «Тип значения» выберем тип нашего объекта (например, СправочникСсылка.СотрудникиОрганизаций).
  3. В поле «Виды характеристик» укажем запрос или таблицу, откуда брать названия свойств. Для УПП это справочник СвойстваОбъектов.
    • Запрос: ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.СвойстваОбъектов ГДЕ НазначениеСвойства = &Назначение
  4. В поле «Значения характеристик» укажем таблицу регистра сведений ЗначенияСвойствОбъектов.
    • Поля: Объект — Объект, Вид — Свойство, Значение — Значение.

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

Способ 3. Агрегация через СГРУППИРОВАТЬ ПО

Если мы не хотим использовать механизм характеристик и нам нужно обойтись одним соединением с регистром (например, для повышения производительности при очень большом количестве свойств), можно применить метод агрегации. Выясним, как это работает: мы выбираем все записи свойств, а затем «схлопываем» их по объекту, используя функцию МАКСИМУМ.

Посмотрим на пример реализации:


ВЫБРАТЬ
    Работники.Сотрудник КАК Сотрудник,
    МАКСИМУМ(ВЫБОР 
        КОГДА Свойства.Свойство = &Свойство_РазмерОбуви ТЕКСТ
        ТОГДА Свойства.Значение 
        ИНАЧЕ NULL 
    КОНЕЦ) КАК РазмерОбуви,
    МАКСИМУМ(ВЫБОР 
        КОГДА Свойства.Свойство = &Свойство_РазмерОдежды 
        ТОГДА Свойства.Значение 
        ИНАЧЕ NULL 
    КОНЕЦ) КАК РазмерОдежды
ИЗ
    РегистрСведений.РаботникиОрганизаций.СрезПоследних КАК Работники
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК Свойства
        ПО Работники.Сотрудник = Свойства.Объект
СГРУППИРОВАТЬ ПО
    Работники.Сотрудник

В данном случае функция МАКСИМУМ игнорирует значения NULL, и для каждого сотрудника остается только одна строка, в которой заполнены те колонки, для которых нашлись соответствующие записи в регистре.

Важные замечания по оптимизации

Проанализируем ситуацию с производительностью. В типовых конфигурациях, таких как УПП, поле Объект в регистре ЗначенияСвойствОбъектов имеет составной тип. Это означает, что прямое соединение может работать медленно, если в таблице миллионы записей.

Чтобы ускорить работу отчета, придерживайтесь следующих правил:

Таким образом, выбор метода зависит от ваших задач. Для быстрого разового отчета подойдет Способ 1 (соединения), для гибкого универсального инструмента лучше один раз настроить Характеристики (Способ 2), а для высоконагруженных отчетов с большим количеством данных стоит рассмотреть Агрегацию (Способ 3).

← На главную