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