К статье
Практический материал

Разработка и Конфигурация · 13 мин

1С: как работает обработка выбора

Как работает обработка выбора в 1С: событие ОбработкаВыбора, ОткрытьФорму, ОповеститьОВыборе, различия обычных и управляемых форм, примеры кода и ошибки.

Обработка выбора — механизм платформы 1С, который связывает две формы: форму выбора (например, список контрагентов) и форму-источник вызова (например, документ, в поле которого нужно подставить контрагента). Когда пользователь кликает по строке списка или нажимает кнопку «Выбрать», платформа передаёт выбранное значение обратно в вызвавшую форму, где оно обрабатывается программно или подставляется в поле автоматически.

Механика заметно различается между обычными и управляемыми формами. В обычных формах за приём результата отвечает событие ОбработкаВыбора модуля формы. В управляемых формах базовый сценарий вообще не требует кода: платформа сама подставляет выбранное значение в связанный реквизит, а событие ОбработкаВыбора нужно только для нестандартной логики — например, когда при выборе контрагента нужно автоматически заполнить договор, банковский счёт и проверить задолженность.

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

Общая схема: как формы обмениваются значением выбора

Цикл выбора состоит из четырёх этапов. Первый — инициация: пользователь нажимает кнопку выбора у поля ввода или программно вызывается ОткрытьФорму. Второй — работа в форме выбора: пользователь находит нужный элемент. Третий — фиксация выбора: либо стандартная команда «Выбрать», либо программный вызов ОповеститьОВыборе или Закрыть(Значение). Четвёртый — приём результата в вызвавшей форме.

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

Стандартный выбор в управляемых формах без единой строки кода

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

Управлять поведением можно через свойства поля ввода: КнопкаВыбора, ВыборГруппИЭлементов (группы, элементы или и то и другое), БыстрыйВыбор (выпадающий список вместо отдельной формы), ИсторияВыбораПриВводе. Также действуют параметры выбора и связи параметров выбора, заданные в конфигураторе, — они фильтруют список без программирования.

Событие ОбработкаВыбора: когда код всё-таки нужен

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

Типовая структура обработчика в управляемой форме:

&НаКлиенте

Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)

Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Контрагенты") Тогда

Объект.Контрагент = ВыбранноеЗначение;

ЗаполнитьДоговорПоУмолчанию();

Модифицированность = Истина;

КонецЕсли;

КонецПроцедуры

Обратите внимание на два приёма. Во-первых, проверка типа ВыбранноеЗначение: в одну форму оповещения могут приходить из разных источников, и без фильтрации обработчик отреагирует на чужое событие. Во-вторых, при необходимости можно анализировать ИсточникВыбора — например, различать выбор контрагента и выбор договора, если оба списка открываются из одной формы.

Программное открытие формы выбора и передача параметров

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

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

Третий параметр ОткрытьФорму — владелец. Передав ЭтотОбъект, вы гарантируете, что оповещение о выборе вернётся именно в эту форму и вызовет её ОбработкаВыбора. Параметр РежимВыбора = Истина переводит форму списка в режим выбора: появляется команда «Выбрать», двойной клик работает как выбор.

Альтернатива — ОписаниеОповещения с методом ПоказатьВводЗначения или открытием формы через ОткрытьФорму(..., ОписаниеОповещения). Тогда результат придёт не в ОбработкаВыбора, а в указанную процедуру при закрытии формы. Этот способ удобнее, когда разные кнопки одной формы должны обрабатывать выбор по-разному.

Способы получить результат выбора

Стандартный выбор поля ввода

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

ОбработкаВыбора + ОткрытьФорму с владельцем

Подходит для нестандартной обработки выбранного значения. Требует проверки типа и источника.

ОписаниеОповещения о закрытии

Гибкая маршрутизация: у каждой кнопки свой обработчик. Ограничение: форма должна возвращать значение через Закрыть(Значение).

ОповеститьОВыборе из формы выбора

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

Множественный подбор и ОповеститьОВыборе

Классический сценарий — подбор товаров в документ: форма подбора остаётся открытой, и каждый выбранный товар добавляется в табличную часть. Здесь стандартный механизм закрытия формы не подходит, поэтому в форме подбора программно вызывается ОповеститьОВыборе(Значение) — форма-владелец получает событие ОбработкаВыбора, добавляет строку, а форма подбора продолжает работать.

В обработчике владельца значение обычно не подставляется в реквизит, а превращается в новую строку табличной части:

&НаКлиенте

Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)

Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда

НоваяСтрока = Объект.Товары.Добавить();

НоваяСтрока.Номенклатура = ВыбранноеЗначение;

НоваяСтрока.Количество = 1;

Модифицированность = Истина;

КонецЕсли;

КонецПроцедуры

Как реализовать подбор с незакрывающейся формой
  1. 1
    Создайте форму подбора и откройте её с владельцем: ОткрытьФорму(..., ЭтотОбъект).
  2. 2
    В форме подбора при выборе строки вызовите ОповеститьОВыборе(ТекущиеДанные.Ссылка) без закрытия формы.
  3. 3
    В форме-владельце реализуйте ОбработкаВыбора с проверкой типа значения.
  4. 4
    Добавьте строку в табличную часть и установите Модифицированность = Истина.
  5. 5
    Проверьте: повторный выбор того же товара должен либо увеличивать количество, либо блокироваться — зафиксируйте нужное поведение кодом.

Обработка выбора в обычных формах

В обычном приложении механизм похож, но есть отличия. Событие ОбработкаВыбора также объявляется в модуле формы, однако формы выбора открываются методами ПолучитьФорму или через ОткрытьФормуМодально. Модальное открытие возвращает выбранное значение напрямую как результат метода — это простой, но устаревший подход, несовместимый с веб-клиентом и таксой интерфейса «Такси».

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

Типичные ошибки и как их диагностировать

Большинство проблем с обработкой выбора сводится к нескольким повторяющимся причинам. Ниже — признаки и способы проверки.

Типичные ошибки
01
Форма выбора открыта без владельца — оповещение никому не адресовано, ОбработкаВыбора не вызывается. Решение: передать ЭтотОбъект третьим параметром ОткрытьФорму.
02
Нет проверки типа ВыбранноеЗначение — обработчик реагирует на чужие оповещения и затирает данные формы.
03
Забыт признак РежимВыбора при открытии формы списка — вместо выбора открывается элемент на редактирование.
04
Дублирование логики: значение подставляется и стандартной обработкой, и вручную в ОбработкаВыбора — получаются двойные вызовы ПриИзменении и лишние запросы к серверу.
05
Использование модальных ОткрытьФормуМодально в управляемом приложении — код не работает при запрещённой модальности.
06
В форме подбора вызван Закрыть() вместо ОповеститьОВыборе — форма закрывается после первого выбора, множественный подбор невозможен.
Контрольные точки

Как проверить результат

Вызывается ли ОбработкаВыбора
Норма

Точка останова в обработчике срабатывает после выбора в форме списка

Тревожный признак

Обработчик молчит — проверьте владельца формы и вызов ОповеститьОВыборе

Что пришло в ВыбранноеЗначение
Норма

Тип совпадает с ожидаемым (ссылка нужного справочника или структура)

Тревожный признак

Приходит Неопределено или другой тип — смотрите, что передаёт источник

Состояние формы после выбора
Норма

Реквизиты заполнены, Модифицированность = Истина, лишних вызовов сервера нет

Тревожный признак

Данные затираются повторным событием или форма не считает себя изменённой

Маршрут решения

Как выбрать действие

Нужно просто подставить ссылку в поле документаИспользуйте стандартную кнопку выбора поля ввода, код не пишите
После выбора нужно заполнить связанные реквизиты или проверить условияОткройте форму выбора с владельцем и реализуйте ОбработкаВыбора
Нужен подбор нескольких позиций без закрытия формыВ форме подбора вызывайте ОповеститьОВыборе, форму не закрывайте
Разные кнопки формы должны по-разному обрабатывать результатИспользуйте ОткрытьФорму с ОписаниеОповещения о закрытии
Выбор не срабатывает вообщеПроверьте владельца формы, РежимВыбора и наличие вызова ОповеститьОВыборе в источнике

Ограничения и границы безопасной доработки

Событие ОбработкаВыбора выполняется на клиенте, поэтому обращение к базе данных из него требует серверного вызова — не выносите тяжёлые запросы в клиентский обработчик, это замедлит интерфейс. Логику заполнения связанных реквизитов правильнее размещать в серверной процедуре модуля формы или в модуле объекта.

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

При отладке обработки выбора удобно в начало обработчика временно поставить вывод типа и значения: Сообщить(ТипЗнч(ВыбранноеЗначение)). Это сразу показывает, какие события реально приходят в форму, — часто их оказывается больше, чем ожидал разработчик.
ПЗ
Практическое замечание

Частые вопросы

Почему ОбработкаВыбора не вызывается, хотя форма выбора открывается?

Чаще всего форма выбора открыта без владельца — не передан третий параметр в ОткрытьФорму, либо в форме выбора нет вызова ОповеститьОВыборе. Также проверьте, что форма списка открыта с параметром РежимВыбора = Истина: без него двойной клик открывает элемент, а не выбирает его.

Чем ОбработкаВыбора отличается от ОбработкаОповещения?

ОбработкаВыбора — частный случай оповещения: она срабатывает только на выбор значения из формы выбора. ОбработкаОповещения ловит произвольные оповещения, отправленные методом Оповестить с именем события. Для выбора из форм используйте первую, для собственных сигналов между формами — вторую.

Можно ли передать в ОбработкаВыбора не ссылку, а несколько значений?

Да. В ОповеститьОВыборе или Закрыть можно передать структуру, массив или таблицу значений. В обработчике тогда проверяйте соответствующий тип: например, ТипЗнч(ВыбранноеЗначение) = Тип("Структура"). Так передают выбранный товар вместе с количеством и ценой из формы подбора.

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

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

Работает ли механизм в веб-клиенте и мобильном клиенте?

Да, оповещения о выборе и событие ОбработкаВыбора работают во всех клиентах управляемого приложения. Не работают модальные методы (ОткрытьФормуМодально, Предупреждение без обработчика) при отключённой модальности — их нужно заменять асинхронными аналогами с описанием оповещения.

Итог

Что важно запомнить

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