При разработке отчетов в конфигурации «Управление производственным предприятием» (УПП) или других решениях на платформе «1С:Предприятие 8» разработчики часто сталкиваются с необходимостью вывода дополнительных свойств объектов. Эти свойства (например, «Размер обуви», «Размер одежды», «Цвет») хранятся в регистре сведений ЗначенияСвойствОбъектов в «вертикальном» виде. Проблема заключается в том, что при обычном соединении регистра с основной таблицей (например, со справочником сотрудников) на каждое свойство создается отдельная строка, что приводит к дублированию данных в отчете. Рассмотрим подробнее, как решить эту задачу и вывести все свойства в одну строку.
Проанализируем ситуацию: в регистре ЗначенияСвойствОбъектов записи хранятся в разрезе измерений Объект и Свойство. Если у одного сотрудника заполнено два свойства, то в регистре это две разные записи. Когда мы выполняем простое ЛЕВОЕ СОЕДИНЕНИЕ по полю Объект, система находит две подходящие записи и закономерно выводит две строки для одного сотрудника. Использование конструкции ВЫБОР КОГДА внутри одного соединения не помогает «схлопнуть» строки, так как условие выполняется для каждой записи регистра отдельно.
Это наиболее простой и быстрый в реализации метод, если количество выводимых свойств невелико и заранее известно. Мы создаем для каждого нужного свойства отдельное соединение с регистром сведений, задавая фильтр по конкретному свойству непосредственно в условии связи ПО.
Разберем этот метод на примере кода. Предположим, нам нужно вывести размер обуви и размер одежды для сотрудника:
ВЫБРАТЬ
Работники.Сотрудник КАК Сотрудник,
РазмерыОбуви.Значение КАК РазмерОбуви,
РазмерыОдежды.Значение КАК РазмерОдежды
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних(&Период, ) КАК Работники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК РазмерыОбуви
ПО Работники.Сотрудник = РазмерыОбуви.Объект
И РазмерыОбуви.Свойство = &Свойство_РазмерОбуви
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК РазмерыОдежды
ПО Работники.Сотрудник = РазмерыОдежды.Объект
И РазмерыОдежды.Свойство = &Свойство_РазмерОдежды
Преимущества метода:
Недостатки:
Система компоновки данных (СКД) обладает встроенным механизмом для работы с дополнительными свойствами и категориями. Это «правильный» архитектурный подход в 1С. Если настроить характеристики, то свойства будут доступны в списке полей через «точку» от объекта (например, Сотрудник.[Размер обуви]), как если бы они были реквизитами справочника.
Выполним настройку по шагам:
СправочникСсылка.СотрудникиОрганизаций).СвойстваОбъектов.
ВЫБРАТЬ Ссылка, Наименование ИЗ Справочник.СвойстваОбъектов ГДЕ НазначениеСвойства = &НазначениеЗначенияСвойствОбъектов.
Объект, Вид — Свойство, Значение — Значение.После этой настройки нам даже не нужно трогать основной текст запроса. В настройках отчета пользователь сможет сам выбрать нужные свойства из списка доступных полей. СКД автоматически сформирует оптимальный запрос к базе данных.
Если мы не хотим использовать механизм характеристик и нам нужно обойтись одним соединением с регистром (например, для повышения производительности при очень большом количестве свойств), можно применить метод агрегации. Выясним, как это работает: мы выбираем все записи свойств, а затем «схлопываем» их по объекту, используя функцию МАКСИМУМ.
Посмотрим на пример реализации:
ВЫБРАТЬ
Работники.Сотрудник КАК Сотрудник,
МАКСИМУМ(ВЫБОР
КОГДА Свойства.Свойство = &Свойство_РазмерОбуви ТЕКСТ
ТОГДА Свойства.Значение
ИНАЧЕ NULL
КОНЕЦ) КАК РазмерОбуви,
МАКСИМУМ(ВЫБОР
КОГДА Свойства.Свойство = &Свойство_РазмерОдежды
ТОГДА Свойства.Значение
ИНАЧЕ NULL
КОНЕЦ) КАК РазмерОдежды
ИЗ
РегистрСведений.РаботникиОрганизаций.СрезПоследних КАК Работники
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК Свойства
ПО Работники.Сотрудник = Свойства.Объект
СГРУППИРОВАТЬ ПО
Работники.Сотрудник
В данном случае функция МАКСИМУМ игнорирует значения NULL, и для каждого сотрудника остается только одна строка, в которой заполнены те колонки, для которых нашлись соответствующие записи в регистре.
Проанализируем ситуацию с производительностью. В типовых конфигурациях, таких как УПП, поле Объект в регистре ЗначенияСвойствОбъектов имеет составной тип. Это означает, что прямое соединение может работать медленно, если в таблице миллионы записей.
Чтобы ускорить работу отчета, придерживайтесь следующих правил:
ПО. Это позволит SQL-серверу использовать индекс по полям Объект + Свойство.Сотрудник, и только потом присоединяйте свойства.ЕСТЬNULL(Значение, "") или настроить условное оформление в самой компоновке.Таким образом, выбор метода зависит от ваших задач. Для быстрого разового отчета подойдет Способ 1 (соединения), для гибкого универсального инструмента лучше один раз настроить Характеристики (Способ 2), а для высоконагруженных отчетов с большим количеством данных стоит рассмотреть Агрегацию (Способ 3).