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