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