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

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает задача не просто открыть список справочника для выбора, а сделать это с предварительно установленными фильтрами. При этом стандартное поведение платформы не всегда подходит, и разработчики прибегают к переопределению события НачалоВыбора. В этот момент возникает закономерный вопрос: как и где «поймать» результат выбора пользователя, если стандартный механизм был отключен?

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

Причина проблемы: Почему не срабатывает стандартный выбор?

Проанализируем ситуацию, описанную в начале темы. Разработчик использует процедуру НачалоВыбора у поля формы и устанавливает параметр СтандартнаяОбработка = Ложь. Это ключевой момент. Устанавливая «Ложь», мы сообщаем платформе: «Я беру управление процессом на себя, не открывай форму автоматически и не жди возврата значения стандартным путем».

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

Решение 1: Использование ОписанияОповещения (Асинхронный подход)

Это современный и наиболее правильный метод для работы в управляемом интерфейсе. Рассмотрим, как он работает. Нам необходимо создать объект ОписаниеОповещения, который укажет платформе, какую процедуру нужно выполнить сразу после того, как форма выбора будет закрыта с результатом.

Посмотрим на пример кода, который решает задачу:


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

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

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

Решение 2: Передача отборов через параметры формы

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

Разберем по шагам, как это реализовать:


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

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

Важный нюанс: Такой способ работает только для простых сравнений «Равно». Если вам нужен вид сравнения ВИерархии, как в исходном вопросе, придется либо использовать фиксированные настройки компоновки данных, либо все-таки программно обращаться к настройкам списка открытой формы, как делал автор темы.

Решение 3: Использование события ОбработкаВыбора

Если вы не хотите использовать ОписаниеОповещения, можно воспользоваться стандартным событием формы ОбработкаВыбора. Оно срабатывает автоматически, когда какая-либо форма, открытая «от имени» текущей формы, возвращает результат.

Проанализируем порядок действий:

  1. При открытии формы в качестве владельца указываем ЭтаФорма.
  2. В модуле формы документа создаем обработчик события ОбработкаВыбора.

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

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

Дополнительные настройки и возможности

Посмотрим на полезные параметры, которые можно передавать при открытии формы выбора, чтобы сделать интерфейс удобнее:

Резюме

Выясним краткий итог: если вы программно открываете справочник и хотите получить результат обратно, лучше всего использовать ОписаниеОповещения. Это делает код читаемым и соответствующим стандартам разработки 1С. Помните, что при СтандартнаяОбработка = Ложь вы полностью берете на себя ответственность за то, куда и как будет записано выбранное значение. Использование связей параметров выбора в свойствах реквизитов часто позволяет избежать написания кода вовсе, если задача сводится к простой фильтрации списка.

← На главную