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

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

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

Анализ исходной ситуации: в чем ошибка?

Рассмотрим типичный фрагмент кода, который вызывает затруднения. Программист пытается открыть форму выбора справочника «Подразделения организаций» с установленным отбором по родителю:


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

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

Решение №1: Правильное указание владельца (Элемент)

Самый простой и эффективный способ решить проблему «в лоб» — передать в качестве владельца объект Элемент. В контексте процедуры НачалоВыбора переменная Элемент ссылается именно на то поле ввода, по которому кликнул пользователь. Когда мы назначаем поле ввода владельцем, платформа включает стандартный механизм: она понимает, куда именно нужно записать выбранную ссылку после закрытия формы выбора.

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


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

Теперь система автоматически заполнит поле ввода, так как владельцем формы выбора является само поле (контрол).

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

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

Выясним, как это работает по шагам:

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

Пример реализации:


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

Решение №3: Современный асинхронный подход (ОписаниеОповещения)

В современной разработке (особенно для Web-клиента) наиболее правильным считается использование объекта ОписаниеОповещения. Этот метод позволяет не привязываться к событиям формы, а четко определить процедуру, которая выполнится строго после закрытия формы выбора.

Разберем этот подход подробнее:


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

&НаКлиенте
Процедура ПослеВыбораПодразделения(РезультатВыбора, ДополнительныеПараметры) Экспорт
    Если РезультатВыбора <> Неопределено Тогда
        // РезультатВыбора содержит ссылку на выбранный элемент
        Сообщить("Пользователь выбрал: " + РезультатВыбора);
    КонецЕсли;
КонецПроцедуры

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

Решение №4: Декларативный метод (Связи параметров выбора)

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

Рассмотрим возможности настройки без программирования:

Использование стандартных механизмов предпочтительнее, так как это снижает объем кода, упрощает поддержку и сохраняет работу стандартных кнопок очистки и быстрого выбора.

Нюансы работы с параметрами

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

  1. ЗакрыватьПриВыборе: Если вы устанавливаете этот параметр в Истина, форма закроется сразу после клика по элементу. Если вы организуете «Подбор» (множественный выбор), этот параметр должен быть Ложь.
  2. ГруппыИЭлементы: Используйте системное перечисление ИспользованиеГруппИЭлементов. Помните, что если справочник не иерархический, попытка установить отбор по группам может привести к пустому списку.
  3. СтандартнаяОбработка: Устанавливая её в Ложь, вы берете на себя полную ответственность за открытие формы. Если вы просто хотите добавить отбор, иногда эффективнее использовать событие ПриСозданииНаСервере самой формы выбора, считывая переданные параметры.

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

← На главную