В разработке на платформе 1С часто возникают ситуации, когда стандартных возможностей формы выбора справочника становится недостаточно. Нам может потребоваться сложный произвольный запрос в динамическом списке, передача дополнительных параметров для фильтрации или специфическая логика отображения данных. Однако при создании собственной формы выбора разработчики часто сталкиваются с тем, что форма открывается, данные отображаются, но при выборе элемента в вызывающее поле ничего не возвращается. Разберем подробно, почему так происходит и как реализовать корректный возврат значения.
Когда мы переопределяем событие НачалоВыбора у элемента формы, мы устанавливаем СтандартнаяОбработка = Ложь. Это необходимо, чтобы платформа не открывала форму выбора по умолчанию. Однако вместе с отменой стандартного открытия мы берем на себя ответственность за весь цикл выбора: от инициализации формы до передачи результата обратно в поле ввода. Если просто вызвать ОткрытьФорму, платформа не всегда понимает, куда именно нужно вернуть результат, особенно если форма является произвольной, а не назначена основной формой выбора в метаданных.
Для того чтобы система знала, кто ожидает результат выбора, необходимо правильно указать владельца при открытии. Рассмотрим пример кода в вызывающей форме. Проанализируем два подхода: автоматический возврат и ручную обработку.
Вариант А: Автоматический возврат в элемент формы
Если мы передаем в качестве владельца сам элемент (поле ввода), платформа попытается автоматически подставить выбранное значение в этот реквизит.
&НаКлиенте
Процедура ТЧКонтрагентНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Передаем Элемент в качестве владельца (третий параметр)
ПараметрыФормы = Новый Структура("РежимВыбора", Истина);
ОткрытьФорму("Справочник.Контрагенты.Форма.МояПроизвольнаяФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Вариант Б: Ручная обработка через событие ОбработкаВыбора
Если нам нужно выполнить дополнительную логику после выбора (например, заполнить сразу несколько полей), в качестве владельца передается сама форма (ЭтаФорма).
&НаКлиенте
Процедура КонтрагентНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Владелец - ЭтаФорма. Результат придет в ОбработкаВыбора
ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаВыбора", , ЭтаФорма);
КонецПроцедуры
&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
// Здесь мы вручную присваиваем значение
Объект.Контрагент = ВыбранноеЗначение;
КонецПроцедуры
В самой форме выбора, особенно если она создана как «произвольная», платформе нужно явно приказать вернуть значение. Чаще всего это делается в событии Выбор или ПриДвойномКлике таблицы, которая отображает данные (динамического списка).
Разберем, как использовать метод ОповеститьОВыборе. Выясним причину частой ошибки «Поле объекта не обнаружено (Ссылка)». Она возникает, если поле, которое вы пытаетесь вернуть, не выведено на форму или не помечено для обязательного считывания.
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
// Отменяем стандартное открытие карточки объекта
СтандартнаяОбработка = Ложь;
// Получаем данные текущей строки
ТекущиеДанные = Элементы.Список.ТекущиеДанные;
Если ТекущиеДанные <> Неопределено Тогда
// Оповещаем владельца о сделанном выборе
ОповеститьОВыборе(ТекущиеДанные.Ссылка);
КонецЕсли;
КонецПроцедуры
Проанализируем важный технический нюанс. Если вы используете произвольный запрос в динамическом списке и не вывели колонку Ссылка в таблицу на форме, обращение ТекущиеДанные.Ссылка вызовет ошибку. Чтобы этого избежать, не обязательно загромождать интерфейс лишними колонками. Рассмотрим свойство «Использовать всегда».
Ссылка (или любого другого идентификатора) установите флаг «Использовать всегда».Теперь платформа будет всегда подтягивать данные этого поля из базы, даже если оно скрыто от пользователя, и вы сможете обращаться к нему в коде.
В современной разработке (особенно для веб-клиента и мобильных приложений) рекомендуется использовать асинхронный подход. Рассмотрим, как это выглядит с применением ОписаниеОповещения. Это гарантирует, что код будет выполнен корректно даже в условиях блокирующих окон.
&НаКлиенте
Процедура ОткрытьФормуВыбора(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеВыбораДанных", ЭтаФорма);
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("ЗакрыватьПриВыборе", Истина);
ПараметрыОткрытия.Вставить("РежимВыбора", Истина);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыОткрытия, ЭтаФорма, , , , Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораДанных(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт
Если ВыбранноеЗначение <> Неопределено Тогда
Объект.Товар = ВыбранноеЗначение;
КонецЕсли;
КонецПроцедуры
Посмотрим на свойства самой формы выбора, которые влияют на результат:
РежимВыбора = Истина. Без этого двойной клик может восприниматься системой как команда на открытие карточки, а не на выбор элемента.Ложь, форма после вызова ОповеститьОВыборе останется висеть на экране. Это удобно для множественного подбора, но часто путает разработчиков, ожидающих закрытия окна.Важный совет: При использовании произвольного запроса всегда проверяйте, чтобы в параметрах ОткрытьФорму не передавались конфликтующие стандартные отборы. Платформа пытается применить их автоматически, что на динамических списках со сложными JOIN может привести к пустым результатам или ошибкам исполнения SQL-запроса. В таких случаях параметры лучше передавать в своей структуре и обрабатывать их вручную в ПриСозданииНаСервере формы выбора, устанавливая параметры запроса динамического списка.
Подведем итог: для корректного возврата значения из нестандартной формы выбора необходимо:
ОповеститьОВыборе().Соблюдение этих шагов гарантирует стабильную работу интерфейса вашей конфигурации.