Как настроить отбор по владельцу в форме выбора справочника?

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

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

Разберем постановку задачи

Представим ситуацию: у нас есть справочник Номенклатура и подчиненный ему справочник ЕдиницыИзмерения. В форме элемента номенклатуры имеется реквизит БазоваяЕдиница. Нам необходимо, чтобы при нажатии на кнопку выбора в этом поле открывалась форма, в которой отображаются только единицы измерения, владельцем которых является именно эта номенклатура. Проанализируем наиболее эффективные способы решения этой задачи.

Способ 1. Использование механизма «Связи параметров выбора»

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

  1. Откроем конфигуратор и найдем реквизит, для которого нужно установить отбор (в нашем примере это реквизит БазоваяЕдиница справочника Номенклатура).
  2. В окне свойств реквизита найдем пункт Связи параметров выбора.
  3. Нажмем на кнопку выбора (три точки). В открывшемся окне добавим новую связь.
  4. В колонке Параметр выбора укажем Отбор.Владелец. Это системное поле, которое говорит платформе, что мы хотим наложить фильтр на реквизит Владелец в открываемой форме.
  5. В колонке Путь к данным выберем Ссылка (если мы настраиваем это внутри самого справочника-владельца) или имя реквизита на форме, который содержит ссылку на владельца.

Важный нюанс: если вы создаете новый элемент справочника, который еще не записан в базу данных, Объект.Ссылка будет пустой. В этом случае связь параметров выбора по ссылке не сработает. Чтобы отбор функционировал корректно даже для новых объектов, в «Пути к данным» следует указывать реквизит формы, а не ссылку объекта из базы.

Способ 2. Программная установка параметров выбора

Иногда логика отбора должна меняться динамически, и жесткой настройки в метаданных недостаточно. В таком случае мы можем использовать свойство элемента формы ПараметрыВыбора. Рассмотрим пример кода, который можно разместить в процедуре ПриСозданииНаСервере или при изменении условий на форме:


// Создаем массив параметров
НовыеПараметры = Новый Массив;

// Формируем параметр отбора по владельцу
// "Отбор.Владелец" - стандартное имя параметра для фильтрации динамического списка
ПараметрВладелец = Новый ПараметрВыбора("Отбор.Владелец", Объект.Ссылка);
НовыеПараметры.Добавить(ПараметрВладелец);

// Устанавливаем параметры для элемента формы
Элементы.БазоваяЕдиница.ПараметрыВыбора = Новый ФиксированныйМассив(НовыеПараметры);

Проанализируем этот код: мы создаем объект ПараметрВыбора, где первым аргументом идет строка с условием, а вторым — само значение фильтра. Этот массив затем преобразуется в ФиксированныйМассив и назначается элементу формы. После этого платформа автоматически будет передавать данный отбор во все формы выбора, открываемые из этого поля.

Способ 3. Перехват в событии «НачалоВыбора»

Если нам нужно полностью контролировать процесс открытия формы выбора, воспользуемся событием НачалоВыбора у поля ввода. Выясним, как это реализовать:


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

В данном примере мы устанавливаем СтандартнаяОбработка = Ложь, чтобы предотвратить обычное открытие формы. Затем мы подготавливаем структуру ПараметрыФормы. Ключ "Отбор" является зарезервированным словом: платформа понимает, что структуру, переданную под этим ключом, нужно применить к динамическому списку открываемой формы.

Почему использование запроса в форме выбора — это плохая практика?

В исходном сообщении автор пытался использовать Новый Запрос в процедуре ПриСозданииНаСервере формы выбора. Посмотрим на причины, по которым так делать не стоит:

Работа с динамическим списком в самой форме выбора

Если вы все же решили настраивать отбор внутри самой формы выбора (например, если логика зависит от каких-то глобальных настроек), то следует работать напрямую с объектом Список (тип ДинамическийСписок). Рассмотрим правильный подход в процедуре ПриСозданииНаСервере формы выбора:


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

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

Итоги и рекомендации

Подведем итог нашему анализу. Для реализации отбора по владельцу в 1С 8.3:

  1. В первую очередь пробуйте использовать Связи параметров выбора в свойствах реквизита. Это наиболее производительный и простой метод.
  2. Если отбор сложный (зависит от нескольких полей), используйте программную установку ПараметрыВыбора для элемента формы.
  3. Никогда не используйте прямые запросы (Новый Запрос) для фильтрации элементов в формах списков и выбора, так как для этого существуют штатные инструменты настройки Компоновки данных динамического списка.

Следуя этим правилам, вы обеспечите быструю работу интерфейса и чистоту программного кода вашей конфигурации.

← На главную