Как настроить отбор по свойству в динамическом списке 1С без выбора типа данных и с фильтрацией по владельцу

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке управляемых форм в среде "1С:Предприятие" программисты часто сталкиваются с задачей вывода дополнительных реквизитов или свойств объектов (документов, номенклатуры, контрагентов) в динамические списки. Обычно такие свойства хранятся в регистре сведений ЗначенияСвойствОбъектов, где поле Значение имеет составной тип данных. Из-за этого при попытке интерактивно настроить отбор по этой колонке платформа заставляет пользователя сначала выбрать тип данных, а затем выводит абсолютно все элементы справочника ЗначенияСвойствОбъектов, игнорируя привязку к конкретному свойству.

В этой статье мы подробно разберем причины такого поведения платформы и изучим четыре практических способа решения данной проблемы, начиная от использования штатного механизма характеристик и заканчивая программным управлением элементами формы.

Выясняем причину проблемы: почему динамический список ведет себя подобным образом

Рассмотрим стандартный запрос динамического списка, в котором левым соединением получается значение определенного свойства (в нашем примере — с кодом "00000000055"):


ВЫБРАТЬ
    РеестрДокументов.Ссылка,
    РеестрДокументов.Дата,
    РеестрДокументов.Номер,
    ЗначенияСвойствОбъектов.Значение КАК СтатусДокумента
ИЗ
    ЖурналДокументов.РеестрДокументов КАК РеестрДокументов
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
        ПО РеестрДокументов.Ссылка = ЗначенияСвойствОбъектов.Объект
            И (ЗначенияСвойствОбъектов.Sвойство.Код = "00000000055")

Поле Значение в регистре ЗначенияСвойствОбъектов является составным (в него могут входить числа, строки, даты, а также ссылки на различные справочники системы). Поскольку платформа не может на этапе компиляции запроса однозначно определить конечный тип данных для конкретного свойства в этой строке, она предоставляет пользователю выбор из всех возможных типов. После выбора типа СправочникСсылка.ЗначенияСвойствОбъектов система открывает форму выбора справочника без какого-либо отбора по владельцу (свойству), выводя все существующие элементы. Проанализируем способы обхода этого ограничения.

Способ 1. Использование штатного механизма характеристик (рекомендуемый метод)

Наиболее правильным и архитектурно верным решением в платформе "1С:Предприятие 8" является использование механизма характеристик системы компоновки данных (СКД), на базе которой работают динамические списки. Этот механизм позволяет платформе автоматически определять типы данных свойств и связывать значения с их владельцами.

Для настройки характеристик выполним следующие действия:

  1. Откроем свойства динамического списка на управляемой форме и перейдем в настройку схемы компоновки данных (кнопка "Настройка списка" -> вкладка "Запрос").
  2. В тексте запроса динамического списка добавим специальное описание характеристик в фигурных скобках.

Пример синтаксиса описания характеристик в запросе:


{ХАРАКТЕРИСТИКИ
	ТИП(Документ.ИмяВашегоДокумента)
	ВИДЫХАРАКТЕРИСТИК ПланВидовХарактеристик.СвойстваОбъектов
	ПОЛЕКЛЮЧА Ссылка
	ПОЛЕИМЕНИ Наименование
	ПОЛЕТИПАЗНАЧЕНИЯ ТипЗначения
	ЗНАЧЕНИЯХАРАКТЕРИСТИК РегистрСведений.ЗначенияСвойствОбъектов
	ПОЛЕОБЪЕКТА Объект
	ПОЛЕВИДА Свойство
	ПОЛЕЗНАЧЕНИЯ Значение
}

Как это работает: Платформа анализирует данное описание и автоматически подменяет тип значения поля на тип, указанный в плане видов характеристик для конкретного свойства. При интерактивной установке отбора пользователю больше не предлагается выбор типа данных, а в форме выбора справочника автоматически устанавливается отбор по владельцу (конкретному свойству).

Способ 2. Явное приведение типов в запросе и программная установка связей параметров выбора

Если по каким-то причинам переходить на полноценный механизм характеристик неудобно или нежелательно, мы можем жестко ограничить тип поля непосредственно в тексте запроса динамического списка с помощью функции ВЫРАЗИТЬ, а ограничение по владельцу задать программно.

Разберем этот вариант по шагам:

Шаг 1. Модернизируем поле выбора в запросе динамического списка. Ограничим тип значения ссылкой на справочник значений свойств:


ВЫРАЗИТЬ(ЗначенияСвойствОбъектов.Значение КАК Справочник.ЗначенияСвойствОбъектов) КАК СтатусДокумента

Это исключит появление диалогового окна выбора типа данных, однако в форме выбора справочника по-прежнему будут отображаться все элементы без фильтрации по владельцу.

Шаг 2. В модуле управляемой формы в обработчике события ПриСозданииНаСервере настроим связь параметров выбора для элемента формы, отображающего колонку СтатусДокумента:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Находим ссылку на свойство "Статус документа" по коду или иному идентификатору
    СсылкаНаСвойство = ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоКоду("00000000055");
    
    Если ЗначениеЗаполнено(СсылкаНаСвойство) Тогда
        // Создаем параметр отбора по владельцу для подчиненного справочника
        ПараметрОтбора = Новый ПараметрВыбора("Отбор.Владелец", СсылкаНаСвойство);
        
        МассивПараметров = Новый Массив;
        МассивПараметров.Добавить(ПараметрОтбора);
        
        // Устанавливаем параметры выбора для элемента формы (колонки списка)
        // Замените "СписокСтатусДокумента" на имя вашего элемента на форме
        Элементы.СписокСтатусДокумента.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
    КонецЕсли;
    
КонецПроцедуры

Благодаря этому коду при попытке установить отбор непосредственно в строке или через стандартное окно настроек списка, система откроет форму выбора с уже предустановленным фильтром по владельцу.

Способ 3. Создание отдельного быстрого отбора на управляемой форме

Для повышения удобства работы пользователей часто практикуется вынесение полей отбора непосредственно в шапку управляемой формы (над таблицей динамического списка). Это позволяет исключить необходимость работы со стандартным окном настройки списка.

Выполним следующие действия для реализации быстрого отбора:

  1. Создадим новый реквизит формы с именем ОтборСтатусДокумента и типом данных СправочникСсылка.ЗначенияСвойствОбъектов.
  2. Вынесем созданный реквизит на форму в виде поля ввода над динамическим списком.
  3. В свойствах этого поля ввода в строке "Связи параметров выбора" или "Параметры выбора" укажем фиксированный отбор по владельцу (нашему свойству ПВХ).
  4. Создадим обработчик события ПриИзменении для этого поля ввода.

В модуле формы пропишем программную установку отбора в динамическом списке при изменении значения в поле ввода:


&НаКлиенте
Процедура ОтборСтатусДокументаПриИзменении(Элемент)
    
    // Получаем доступ к элементам отбора компоновщика настроек динамического списка
    ПолеОтбора = Новый ПолеКомпоновкиДанных("СтатусДокумента");
    
    ЭлементОтбора = Неопределено;
    
    // Ищем существующий отбор по нашему полю в настройках списка
    Для Каждого ЭлементСписка Из Список.КомпоновщикНастроек.Настройки.Отбор.Элементы Цикл
        Если ЭлементСписка.ЛевоеЗначение = ПолеОтбора Тогда
            ЭлементОтбора = ЭлементСписка;
            Прервать;
        КонецЕсли;
    КонецЦикла;
    
    // Если отбор не найден, создаем новый
    Если ЭлементОтбора = Неопределено Тогда
        ЭлементОтбора = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
        ЭлементОтбора.ЛевоеЗначение = ПолеОтбора;
    КонецЕсли;
    
    // Настраиваем параметры отбора
    ЭлементОтбора.ВидСравнения   = ВидСравненияКомпоновкиДанных.Равно;
    ЭлементОтбора.ПравоеЗначение = ОтборСтатусДокумента;
    ЭлементОтбора.Использование  = ЗначениеЗаполнено(ОтборСтатусДокумента);
    
КонецПроцедуры

Этот способ является наиболее предпочтительным с точки зрения эргономики интерфейса, так как пользователь всегда видит, по какому именно статусу сейчас отфильтрован журнал документов.

Способ 4. Программный перехват начала выбора в колонке динамического списка

Если требуется оставить стандартный интерактивный отбор непосредственно через ячейку таблицы динамического списка, но необходимо жестко ограничить открывающийся список значений, мы можем перехватить событие начала выбора.

Проанализируем алгоритм реализации программного выбора:

  1. Для элемента формы (колонки списка СтатусДокумента) создадим обработчик события НачалоВыбора.
  2. В обработчике программно отменим стандартное действие системы и откроем форму выбора справочника с наложенным отбором.

Реализация в модуле формы:


&НаКлиенте
Процедура СписокСтатусДокументаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // Отменяем стандартный выбор платформы, чтобы избежать появления окна выбора типа
    СтандартнаяОбработка = Ложь;
    
    // Получаем ссылку на свойство на сервере
    СсылкаНаСвойство = ПолучитьСвойствоНаСервере();
    
    Если Не ЗначениеЗаполнено(СсылкаНаСвойство) Тогда
        Возврат;
    КонецЕсли;
    
    // Формируем структуру параметров и отбора для открываемой формы выбора
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", Новый Структура("Владелец", СсылкаНаСвойство));
    ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Истина);
    
    // Открываем форму выбора справочника значений свойств объектов
    ОткрытьФорму("Справочник.ЗначенияСвойствОбъектов.ФормаВыбора", ПараметрыФормы, Элемент);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьСвойствоНаСервере()
    Возврат ПланыВидовХарактеристик.СвойстваОбъектов.НайтиПоКоду("00000000055");
КонецФункции

Важное примечание: При выборе значения из открывшейся формы оно автоматически подставится в поле отбора динамического списка благодаря тому, что в качестве владельца формы выбора (третий параметр метода ОткрытьФорму) мы передали сам элемент управления Элемент.

Подводим итоги

Мы рассмотрели четыре различных подхода к решению проблемы интерактивного отбора по свойствам составного типа в динамических списках 1С. Выбор конкретного метода зависит от требований к интерфейсу вашего прикладного решения:

← На главную