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

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

При разработке интерфейсов в «1С:Предприятие 8» часто возникает задача предоставить пользователю возможность выбора нескольких значений из списка в одно поле. Например, в поле «Цвета» необходимо выбрать сразу несколько вариантов: «Красный», «Синий», «Зеленый». По умолчанию стандартное поведение платформы при выборе значения из выпадающего списка заменяет предыдущую запись новой. В этой статье мы подробно разберем, как обойти это ограничение и реализовать добавление выбранных значений через запятую (или другой разделитель) без стирания ранее введенных данных.

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

Решение 1. Программное сложение строк в обработчике события выбора

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

Давайте разберем по шагам, как это реализовать на управляемой форме:

  1. Создайте реквизит формы с типом Строка. Назовем его, например, ОсмотрРегулярно.
  2. Перетащите этот реквизит на форму, чтобы создалось поле ввода.
  3. В свойствах созданного поля ввода найдите категорию Использование и установите флаг у свойства РежимВыбораИзСписка в значение Истина.
  4. Заполните список выбора этого поля (свойство СписокВыбора) необходимыми значениями (например: "Красный", "Синий", "Зеленый").
  5. Создайте на клиенте обработчик события ОбработкаВыбора для нашего поля ввода.

Теперь напишем код обработчика события. Нам необходимо отключить стандартную обработку системы, проверить, заполнено ли уже наше поле ввода, и добавить новое значение через запятую.


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

Проанализируем этот код подробнее. Ключевым моментом здесь является строка СтандартнаяОбработка = Ложь;. Именно она сообщает платформе, что мы берем управление процессом выбора на себя. Если этого не сделать, платформа после выполнения нашей процедуры все равно запишет в поле только одно последнее выбранное значение, проигнорировав все наши программные сложения.

Обратите внимание на использование тернарного оператора ?(). Он позволяет лаконично проверить, пустая ли строка в реквизите ОсмотрРегулярно. Если она не пустая, переменной СтрокаЗапятая присваивается значение ", ", иначе — пустая строка "". Это гарантирует, что в самом начале строки у нас не появится лишняя запятая.

Решение 2. Современный механизм множественного выбора в поле ввода (для платформы 8.3.23 и выше)

Если ваша конфигурация работает на версии платформы «1С:Предприятие» 8.3.23 или новее, вам больше не нужно писать программный код для склеивания строк. Фирма «1С» реализовала полноценный штатный механизм под названием «Множественный выбор в поле ввода».

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

Давайте настроим этот механизм:

  1. Создайте реквизит формы с типом СписокЗначений (а не Строка, как в предыдущем примере). Тип типа данных списка должен соответствовать типу выбираемых значений (например, Строка или ссылка на справочник).
  2. Перенесите этот реквизит на форму. Платформа автоматически создаст поле ввода, связанное со списком значений.
  3. В свойствах поля ввода на форме найдите свойство РежимВыбораИзСписка и установите его в значение Истина.
  4. Заполните список выбора элемента формы нужными значениями.

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

Решение 3. Интерактивный выбор с помощью метода «ОтметитьЭлементы»

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

Рассмотрим пример реализации через команду на форме. Предположим, у нас есть кнопка выбора и текстовое поле ВыбранныеЦвета, куда мы хотим поместить результат.


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

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

Этот метод очень дружелюбен к пользователю: перед ним открывается полноценное окно, где можно быстро отметить галочками нужные позиции, нажать кнопку «ОК», после чего система автоматически сформирует красивую строку. В качестве готового решения для подобного сценария подойдёт универсальная форма для ввода нескольких значений различных типов.

Решение 4. Множественный подбор из справочника

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

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


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

После того как пользователь выделит несколько элементов в справочнике (зажав клавишу Ctrl или Shift) и нажмет кнопку выбора, на исходной форме сработает событие ОбработкаВыбора. В параметре ВыбранноеЗначение придет не одно значение, а Массив ссылок. Нам останется только обойти этот массив программно:


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

Важный архитектурный совет: как правильно хранить такие данные?

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

Как делать правильно?

Для временного отображения информации на форме текстовая строка через запятую подходит отлично. Но в самой базе данных информацию о множественном выборе рекомендуется хранить одним из следующих способов:

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

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

← На главную