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

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

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

Анализ проблемы: почему стандартный механизм перестает работать

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

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

Основной способ вернуть значение из формы выбора — это вызов метода ОповеститьОВыборе(). Этот метод посылает сигнал владельцу формы о том, что выбор совершен. Проанализируем ситуацию, когда мы используем динамический список. Чаще всего выбор происходит при двойном клике по строке или нажатии кнопки «Выбрать».

Для реализации этого нам нужно создать обработчик события Выбор у таблицы формы (динамического списка). Посмотрим на пример кода:


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

Этот метод инициирует событие ОбработкаВыбора у владельца формы. Однако здесь кроется важный нюанс, который мы разберем в следующем пункте.

Шаг 2. Настройка доступности поля Ссылка в динамическом списке

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

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

  1. Откроем настройки формы и найдем элемент Список (наш Динамический список).
  2. Перейдем в свойства поля Ссылка внутри этого списка.
  3. Установим флаг Использовать всегда.

После этого поле Ссылка будет всегда доступно в ТекущиеДанные на стороне клиента, даже если оно не отображается пользователю.

Шаг 3. Корректное указание владельца при открытии формы

Проанализируем ситуацию с вызовом формы. Метод ОткрытьФорму принимает несколько параметров, и второй параметр — Владелец — является критически важным для возврата значения. Рассмотрим два варианта:

Вариант А: Владелец — элемент формы (Поле ввода)

Если мы передаем конкретный элемент, платформа автоматически поймет, что результат выбора нужно поместить именно в это поле.


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

Вариант Б: Владелец — сама Форма

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

Шаг 4. Установка режима выбора в свойствах формы

Разберем еще одну деталь, которую часто упускают программисты. У самой формы (объекта «Форма») есть свойство РежимВыбора. Если вы создаете форму «с нуля», убедитесь, что этот флаг установлен в Истина. Это меняет поведение формы на уровне платформы: например, нажатие Enter на строке списка будет инициировать выбор, а не открытие формы элемента.

Также полезно передавать параметр ЗакрыватьПриВыборе. Рассмотрим, как это сделать программно при открытии:


ПараметрыВыбора = Новый Структура;
ПараметрыВыбора.Вставить("ЗакрыватьПриВыборе", Истина);
ПараметрыВыбора.Вставить("РежимВыбора", Истина);
ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыВыбора, Элемент);

Шаг 5. Современный асинхронный подход (Закрыть с параметром)

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

Посмотрим, как это выглядит. В вызывающей форме:


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

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

В самой форме выбора при этом достаточно вызвать:


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

Шаг 6. Работа с множественным выбором

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

  1. У элемента формы Список установите свойство МножественныйВыбор = Истина.
  2. В коде возврата используйте коллекцию выделенных строк.

&НаКлиенте
Процедура КомандаОк(Команда)
    МассивРезультата = Новый Массив;
    Для Каждого СсылкаИзСписка Из Элементы.Список.ВыделенныеСтроки Цикл
        МассивРезультата.Добавить(СсылкаИзСписка);
    КонецЦикла;
    
    ОповеститьОВыборе(МассивРезультата);
КонецПроцедуры

Итоги и рекомендации

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

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

← На главную