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