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

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

При разработке прикладных решений на платформе 1С:Предприятие 8.3 (в конфигурациях на базе управляемых форм, таких как «Бухгалтерия предприятия 3.0») нередко возникает задача переопределить стандартное поведение поля ввода при нажатии кнопки выбора. Типичный сценарий: требуется открыть форму подчиненного справочника (например, договоров контрагентов) с жестким отбором по владельцу (контрагенту из документа).

Однако начинающие разработчики часто сталкиваются с ситуацией, когда после отмены стандартного механизма строкой СтандартнаяОбработка = Ложь; и вызова метода ОткрытьФорму пользователь выбирает строку в справочнике, но значение в поле документа не попадает, а обработчик ОбработкаВыбора не срабатывает вовсе. Разберем по шагам, почему возникает эта ошибка и как корректно реализовать выбор значения несколькими способами.

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

Посмотрим на исходный код, который часто приводит к ошибке:


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

Проанализируем ситуацию и выделим две критические ошибки в данном коде:

  1. Отсутствует параметр «Владелец» при открытии формы. Форма выбора открывается изолированно, платформа не связывает её ни с вызывающей формой документа, ни с конкретным полем ввода. В управляемом интерфейсе событие ОбработкаВыбора генерируется только в контексте формы или элемента, выступающего владельцем открытого окна.
  2. Включен параметр «МножественныйВыбор». Если передать МножественныйВыбор = Истина, форма выбора возвращает не одиночную ссылку СправочникСсылка.ДоговорыКонтрагентов, а коллекцию типа Массив. Одиночное поле ввода формы, связанное со ссылочным реквизитом, не может принять массив в качестве значения при автоматическом заполнении.

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

Рассмотрим синтаксис глобального метода ОткрытьФорму:


ОткрытьФорму(ИмяФормы, Параметры, Владелец, Уникальность, Окно, НавигационнаяСсылка, ОписаниеОповещенияОЗакрытии, РежимОткрытияОкна)

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

Если в качестве владельца передан конкретный элемент управления, поведение платформы следующее:

  1. После выбора строки в списке форма выбора закрывается.
  2. Управление передается в событие ОбработкаВыбора данного элемента.
  3. Если выбор одиночный (параметр МножественныйВыбор равен Ложь или не задан), платформа сама присваивает выбранное значение в реквизит, с которым связан элемент. Дополнительного кода в обработчике не требуется.

Посмотрим на пример правильного вызова в обработчике НачалоВыбора:


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

Параметр ТекущаяСтрока обеспечивает удобство: при открытии списка курсор автоматически установится на уже выбранный договор, а не на начало справочника.

Способ 2. Указание формы в качестве владельца и ручная обработка

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

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


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

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

Если же использовался МножественныйВыбор = Истина, в параметре ВыбранноеЗначение вернется Массив. В этом случае мы должны вручную перебрать массив в цикле и заполнить, например, табличную часть документа.

Способ 3. Асинхронное открытие формы через ОписаниеОповещения

В современных конфигурациях стандарт разработки 1С рекомендует использовать асинхронный вызов без жесткой привязки владельца. Для этого используется седьмой параметр метода ОткрытьФорму — ОписаниеОповещенияОЗакрытии.

Разберем реализацию этого подхода:


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

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

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

Способ 4. Декларативная настройка без программного кода

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

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

  1. Откроем свойства реквизита документа (или свойства элемента формы) ДоговорКонтрагента.
  2. Найдем свойство «Связи параметров выбора» (ChoiceParameterLinks).
  3. Добавим новую связь: укажем имя параметра режима выбора Отбор.Владелец и свяжем его с полем Объект.Контрагент.

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

← На главную