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