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

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

При разработке внешних отчетов и обработок в среде «1С:Предприятие» (особенно на обычных формах, таких как в конфигурации «Зарплата и Управление Персоналом 2.5») часто возникает задача предоставить пользователю возможность выбора элементов справочника в список значений с предварительной фильтрацией. Типичный пример — выбор значений подчиненного справочника (например, ЗначенияСвойствОбъектов) с отбором по его владельцу (конкретному свойству из Плана видов характеристик СвойстваОбъектов).

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

Анализ исходной проблемы: почему данные не возвращаются в список?

Рассмотрим ситуацию, с которой столкнулся автор темы. В обработчике события СписокБазНачалоВыбора был написан следующий код:


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

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

В платформе «1С:Предприятие» при работе с обычными формами метод ОткрытьФормуМодально, вызванный с передачей структуры параметров, не всегда корректно связывает вызывающий элемент управления с открываемой формой. Для того чтобы форма выбора знала, куда именно нужно вернуть результат, ей необходимо передать контекст — владельца формы (в данном случае это сам элемент управления поля ввода Элемент, а не объект ЭтаФорма).

Кроме того, если мы переопределяем стандартную обработку (СтандартнаяОбработка = Ложь), платформа полностью снимает с себя обязательства по автоматическому заполнению поля. Мы должны либо явно получить возвращаемое значение и присвоить его, либо правильно связать форму выбора с элементом управления.

Ниже мы подробно разберем четыре практических способа реализации этой задачи.

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

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

Разберем этот вариант по шагам и напишем правильный обработчик события:


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

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

Способ 2. Использование режима «Подбора» (Множественный выбор)

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

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

Шаг 1. Открываем форму в режиме подбора:


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

Шаг 2. Обрабатываем выбор в событии ОбработкаВыбора поля ввода. Нам необходимо подписать наше поле ввода (или саму форму) на событие ОбработкаВыбора и добавить туда следующий код:


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

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

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

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

Рассмотрим, как настроить это визуально в конфигураторе:

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

Этот способ является наиболее предпочтительным с точки зрения стандартов разработки фирмы «1С», так как он использует декларативный подход и оптимально работает на уровне платформы.

Способ 4. Создание собственной формы выбора во внешнем отчете

В сообщении №4 автор упоминает критически важное ограничение: «Конфа на замках...». Это означает, что вносить изменения в типовую конфигурацию «Зарплата и Управление Персоналом» нельзя, а все доработки должны быть выполнены строго в рамках одного внешнего файла отчета (.erf).

Если типовая форма выбора справочника ЗначенияСвойствОбъектов не обладает нужной нам гибкостью (например, в ней скрыта колонка «Владелец» или жестко переопределяются отборы при открытии), самым надежным и стабильным решением будет создание собственной формы выбора непосредственно внутри внешнего отчета.

Давайте разберем, как это реализовать:

  1. В конфигураторе откроем наш внешний отчет и перейдем на вкладку Формы.
  2. Добавим новую форму, укажем ее тип как «Форма выбора» или «Произвольная форма». Назовем ее, например, ФормаВыбораЗначенийСвойств.
  3. Разместим на этой форме табличное поле с типом значения СправочникСписок.ЗначенияСвойствОбъектов.
  4. В модуле этой новой формы в процедуре ПриОткрытии напишем жесткий отбор по входящему параметру владельца:
    
    Процедура ПриОткрытии()
        // Устанавливаем отбор по переданному владельцу свойства
        Если ЗначениеЗаполнено(ПараметрВладелец) Тогда
            СправочникСписок.Отбор.Владелец.Установить(ПараметрВладелец);
        КонецЕсли;
    КонецПроцедуры
    
  5. В основном отчете вызовем эту форму программно, передав туда нужное свойство, и обработаем результат. Это гарантирует полную независимость нашей разработки от обновлений типовой конфигурации.

Важные особенности справочника «ЗначенияСвойствОбъектов»

Работая с подчиненными справочниками и планами видов характеристик, всегда помните о следующих правилах:

Мы подробно разобрали все возможные варианты решения проблемы выбора элементов справочника с отбором. Выбирайте наиболее подходящий способ в зависимости от ваших задач и ограничений доступа к изменению конфигурации!

← На главную