Как реализовать выпадающий список в колонке таблицы на управляемых формах 1С?

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

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

Способ 1. Настройка через свойства элемента формы (статический список)

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

  1. РежимВыбораИзСписка: Установите это свойство в значение Истина. Это заблокирует свободный ввод текста и заставит систему сразу открывать список при нажатии на поле.
  2. КнопкаСпискаВыбора: Установите в значение Да, чтобы в поле появилась характерная кнопка со стрелкой вниз.
  3. СписокВыбора: Сюда необходимо загрузить доступные варианты.

Разберем пример программной реализации в обработчике ПриСозданииНаСервере. Это решение предпочтительнее, так как оно позволяет централизованно управлять списком:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Формируем список значений
    СписокПалет = Новый СписокЗначений;
    СписокПалет.Добавить("Европалета", "Европалета (800х1200)");
    СписокПалет.Добавить("Финпалета", "Финпалета (1000х1200)");
    СписокПалет.Добавить("Индустриальная", "Индустриальная (1200х1200)");
    
    // Загружаем список в элемент формы (колонку таблицы)
    Элементы.ТоварыПалета.СписокВыбора.ЗагрузитьЗначения(СписокПалет.ВыгрузитьЗначения());
    
КонецПроцедуры

Обратите внимание, что вместо ТоварыПалета нужно подставить имя вашего элемента формы (колонки). Этот метод хорош тем, что платформа сама берет на себя всю работу по подстановке выбранного значения в реквизит строки.

Способ 2. Динамическое заполнение через обработчик «НачалоВыбора»

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

Выясним причину, по которой стандартная обработка может мешать. Если мы хотим полностью контролировать процесс появления списка, нам нужно установить параметр СтандартнаяОбработка = Ложь. Однако есть более элегантный способ — использование параметра ДанныеВыбора.


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

Важный нюанс: Если вы используете ДанныеВыбора, платформа ожидает, что типы значений в списке соответствуют типу реквизита колонки. Если в колонке хранится Строка, то и в Значение элемента списка должна быть строка.

Способ 3. Решение проблемы «зависшего» значения

Часто разработчики сталкиваются с проблемой: пользователь выбирает значение из списка, но оно появляется в ячейке только после того, как курсор покидает поле (после потери фокуса). Это происходит из-за того, что активный режим редактирования текста «перекрывает» программно установленное значение.

Чтобы исправить это поведение, проанализируем свойство ОбновлениеТекстаРедактирования. Посмотрим на примере, как принудительно обновить отображение:

  1. В палитре свойств элемента формы (колонки) найдите ОбновлениеТекстаРедактирования.
  2. Установите его в значение При изменении.

Если это не помогает, можно применить программный «костыль», который принудительно обновляет данные через событие ОбработкаВыбора:


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

Способ 4. Работа с индивидуальными списками в каждой строке

Бывают ситуации, когда для одной строки таблицы список палет один, а для другой — другой. В этом случае заполнение Элементы.ТоварыПалета.СписокВыбора в ПриСозданииНаСервере не подойдет, так как список выбора у колонки — один на всю таблицу.

Рассмотрим, как решить эту задачу через событие ПриАктивизацииСтроки или динамическое наполнение СписокВыбора самого элемента управления в момент клика:


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

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

Рекомендации по типам данных

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

Всегда проверяйте соответствие типов:

Таким образом, мы рассмотрели основные методы реализации выпадающих списков. Использование свойств РежимВыбораИзСписка и СписокВыбора является наиболее "чистым" с точки зрения архитектуры 1С и обеспечивает лучшую производительность управляемого приложения.

← На главную