Почему при выборе из общей формы не срабатывает событие ПриИзменении и как это исправить

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

При разработке и кастомизации конфигураций на управляемых формах 1С (таких как ERP, КА 2 или УТ 11) часто возникает задача заменить стандартную форму выбора справочника на свою собственную — например, на универсальную или специализированную общую форму. Однако разработчики нередко сталкиваются с неприятным эффектом: после выбора элемента в новой форме перестает отрабатывать стандартное событие поля ввода ПриИзменении.

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

Выясняем причину: как работает стандартный выбор «под капотом»

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

В типовой форме выбора справочника (например, СоглашенияСКлиентами) в модуле формы вы не найдете явных вызовов функций оповещения или закрытия с передачей значения. Тем не менее, выбор работает отлично. Это происходит благодаря автоматическим механизмам платформы «1С:Предприятие 8»:

  1. Расширение динамического списка: У стандартных форм выбора основной реквизит формы имеет тип ДинамическийСписок, связанный с конкретной таблицей БД. Форма использует системное расширение формы динамического списка.
  2. Режим выбора (ChoiceMode): Когда форма открывается как форма выбора, платформа автоматически передает ей параметр РежимВыбора = Истина. Динамический список переходит в режим ожидания интерактивного выбора.
  3. Интерактивный перехват событий: При двойном клике или нажатии Enter на строке списка платформа понимает, что нужно не открыть элемент для редактирования, а выбрать его. Она считывает ссылку на объект, закрывает форму выбора и передает полученное значение Владельцу формы. Владельцем в данном случае выступает конкретный элемент управления (поле ввода), который инициировал выбор.
  4. Запуск обработчиков: Получив значение, поле ввода инициирует стандартную цепочку событий на вызывающей форме: сначала срабатывает событие элемента ОбработкаВыбора, затем значение записывается в реквизит, и в самом конце вызывается процедура ПриИзменении.

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

---

Способ 1. Использование метода ОповеститьОВыборе()

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

Рассмотрим, как правильно реализовать этот механизм в нашей общей форме. Предположим, на вашей общей форме расположен список выбора (таблица формы с динамическим списком).

Нам необходимо перехватить стандартное событие выбора строки в этой таблице и перенаправить выбранное значение владельцу:


&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    
    // 1. Отменяем стандартное открытие карточки элемента справочника
    СтандартнаяОбработка = Ложь; 
    
    // 2. Оповещаем владельца о том, что выбор сделан, и передаем ссылку
    ОповеститьОВыборе(ВыбраннаяСтрока); 
    
КонецПроцедуры

Метод ОповеститьОВыборе() автоматически выполняет следующие действия:

---

Способ 2. Современный стандарт — метод Закрыть() с параметром

В современных конфигурациях 1С, работающих в интерфейсе «Такси» и ориентированных на отказ от модальности, более предпочтительным и универсальным способом возврата значения является использование метода управляемой формы Закрыть() с передачей ему возвращаемого значения в качестве параметра.

Разберем, как выглядит этот код в модуле нашей общей формы выбора:


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

Как это работает: Если общая форма была открыта с явным указанием владельца (а мы передавали Элемент третьим параметром в ОткрытьФорму), то платформа при закрытии формы с параметром автоматически передаст этот параметр в обработку выбора элемента-владельца. Это также приведет к корректному срабатыванию события ПриИзменении.

---

Критически важный нюанс: параметр «Владелец» при открытии формы

Даже если вы напишете идеальный код возврата значения внутри общей формы, событие ПриИзменении все равно может не отработать, если вы допустили ошибку при вызове формы. Проанализируем ключевой параметр функции ОткрытьФорму().

Синтаксис метода открытия формы выглядит так:

ОткрытьФорму("ИмяФормы", Параметры, Владелец)

Разберем два варианта передачи третьего параметра (Владелец):

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

---

Резюме и пошаговый чек-лист для реализации

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

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

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

← На главную