При разработке отчетов и обработок на управляемых формах в 1С:ERP Управление предприятием 2 или 1С:Управление торговлей 11 программисты часто сталкиваются со следующей проблемой: в консоли системы компоновки данных (СКД) отборы по свойствам характеристик номенклатуры выводятся и работают идеально, но при переносе кода в реальную обработку эти свойства просто исчезают из доступных полей выбора.
В этой статье мы подробно разберем, почему возникает такое поведение платформы "1С:Предприятие", проанализируем типичные ошибки инициализации схемы и научимся правильно выводить свойства характеристик в отбор программным путем.
Выясним первопричину проблемы. Дополнительные реквизиты и свойства характеристик в 1С являются динамическими метаданными. Платформа определяет их состав на лету, обращаясь к базе данных. Когда мы инициализируем объект ИсточникДоступныхНастроекКомпоновкиДанных на основе схемы, сохраненной во временном хранилище, платформа компилирует эту схему для определения доступных полей отбора.
Если в запросе СКД прописано жесткое условие связи характеристик с определенным Видом номенклатуры, а сам параметр ВидНоменклатуры на момент генерации источника настроек пуст или не определен, то СКД не может связаться с базой данных для получения конкретного набора дополнительных реквизитов. В результате пользователь видит только базовые реквизиты ссылки, без динамических свойств.
Главное правило: заполнять параметры (такие как вид номенклатуры, группа и др.) необходимо непосредственно в самом объекте СхемаКомпоновкиДанных ДО того, как схема будет помещена во временное хранилище и перенесена на сторону клиента для инициализации компоновщика.
Рассмотрим по шагам правильный алгоритм инициализации схемы компоновки данных и компоновщика настроек на сервере:
ВидНоменклатуры) непосредственно в коллекцию параметров самой схемы.Проанализируем пример кода, реализующий этот алгоритм:
&НаСервере
Процедура ИнициализироватьОтборНаСервере()
// 1. Получаем макет СКД из объекта обработки
СхемаСКД = РеквизитФормыВЗначение("Объект").ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
// 2. Устанавливаем параметр ВидНоменклатуры в СХЕМЕ до её сериализации
ПараметрВидНоменклатуры = СхемаСКД.Параметры.Найти("ВидНоменклатуры");
Если ПараметрВидНоменклатуры <> Неопределено Тогда
ПараметрВидНоменклатуры.Значение = Объект.ВидНоменклатуры;
ПараметрВидНоменклатуры.Использование = Истина;
КонецЕсли;
// 3. Помещаем настроенную схему во временное хранилище
АдресСхемыВХранилище = ПоместитьВоВременноеХранилище(СхемаСКД, УникальныйИдентификатор);
// 4. Инициализируем источник доступных настроек по новому адресу
ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресСхемыВХранилище);
КомпоновщикНастроек.Инициализировать(ИсточникНастроек);
// 5. Загружаем настройки по умолчанию
НастройкиПоУмолчанию = СхемаСКД.НастройкиПоУмолчанию;
// Устанавливаем этот же параметр в настройках компоновщика для корректной работы отчетов
ПараметрНастроек = НастройкиПоУмолчанию.ПараметрыДанных.Элементы.Найти("ВидНоменклатуры");
Если ПараметрНастроек <> Неопределено Тогда
ПараметрНастроек.Значение = Объект.ВидНоменклатуры;
ПараметрНастроек.Использование = Истина;
КонецЕсли;
КомпоновщикНастроек.ЗагрузитьНастройки(НастройкиПоУмолчанию);
КонецПроцедуры
Благодаря такому подходу платформа при компиляции источника настроек на шаге 4 уже четко знает, для какого именно вида номенклатуры нужно прочитать свойства характеристик, и успешно выведет их в доступные поля отбора.
Разберем еще одну частую проблему: при интерактивном выборе значения свойства в отборе (например, свойства "Цвет") пользователь видит в списке выбора абсолютно все значения дополнительных реквизитов информационной базы (и размеры, и материалы, и бренды). Это происходит из-за отсутствия связи по владельцу.
Чтобы исправить это поведение средствами СКД, настроим связи параметров выбора:
Характеристика.Значение или аналогичное поле, содержащее значение свойства).Отбор.Владелец.Характеристика.Свойство или Свойство).После этой настройки при попытке выбрать значение свойства система автоматически передаст в форму выбора владельца (само свойство), ограничив список только подходящими значениями.
По умолчанию свойства характеристик отображаются в дереве доступных полей компоновщика как дочерние элементы родительской ссылки (например: Характеристика -> [Имя свойства]). Это не всегда удобно для пользователей.
Рассмотрим два способа, как вынести эти свойства на верхний уровень списка доступных полей отбора.
Мы можем явно объявить свойства характеристик в секции {ВЫБРАТЬ...} нашего запроса в СКД. Квадратные скобки указывают системе на обращение к динамическим свойствам объектов:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
ХарактеристикаНоменклатуры.Ссылка КАК Характеристика
{ВЫБРАТЬ
Характеристика.[Цвет] КАК Цвет,
Характеристика.[Размер] КАК Размер
}
ИЗ
Справочник.Номенклатура КАК Номенклатура
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры КАК ХарактеристикаНоменклатуры
ПО ХарактеристикаНоменклатуры.Владелец = Номенклатура.Ссылка
После этого поля Цвет и Размер будут отображаться в списке доступных полей компоновщика на самом верхнем уровне, отдельно от поля "Характеристика".
Если структура отборов настраивается динамически в коде, мы можем напрямую создавать элементы отбора, используя путь к данным в квадратных скобках. Рассмотрим пример программного добавления элемента отбора по свойству "Цвет":
// Добавляем новый элемент отбора в компоновщик настроек
ЭлементыОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы;
НовыйЭлемент = ЭлементыОтбора.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
// Задаем левое значение отбора через специальный путь к данным
НовыйЭлемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Характеристика.[Цвет]");
НовыйЭлемент.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
НовыйЭлемент.Использование = Истина;
Использование этого синтаксиса позволяет гибко управлять динамическими характеристиками на управляемых формах, создавая удобный и понятный интерфейс для конечных пользователей.