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

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

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

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

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

Для корректного решения нам необходимо:

  1. Подавить стандартную обработку добавления строки или выбора значения.
  2. Программно открыть форму выбора с флагом множественного выбора.
  3. Обработать массив результатов в специальном обработчике, обходя его в цикле и добавляя новые строки в объект вручную.

Шаг 1. Перехват события добавления строки

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

Проанализируем пример кода для этого события. Обратите внимание на использование параметра Отказ = Истина, который отменяет стандартное создание новой пустой строки:


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

Шаг 2. Обработка выбранных данных

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

Рассмотрим, как правильно организовать цикл по добавлению строк в табличную часть Объект.Дисциплины:


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

КонецПроцедуры

Особенности работы с составными типами данных

Если реквизит вашей табличной части имеет составной тип (например, это может быть и "Дисциплина", и "Период обучения"), ситуация немного усложняется. Нам нужно сначала спросить пользователя, справочник какого типа он хочет открыть. Для этого удобно использовать метод ПоказатьВыборИзСписка.

Разберем пример с выбором типа перед открытием формы:


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

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

Почему данные не отображаются в таблице?

Иногда возникает ситуация, когда отладчик показывает, что строки в Объект.Дисциплины добавились, но на экране пользователя таблица остается пустой. Выясним причину этого явления.

Во-первых, проверьте свойство ПутьКДанным элемента формы "Таблица". Она должна быть связана именно с Объект.Дисциплины. Если таблица на форме связана с каким-то другим реквизитом формы (например, временным списком), то изменения в Объект.Дисциплины не отразятся на экране.

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

ОбновитьОтображениеДанных();

В-третьих, убедитесь, что у вас не установлены никакие Отборы на уровне элемента формы "Таблица". Если включен отбор, новые строки могут просто не соответствовать его условиям и будут скрыты сразу после добавления.

Режим "Подбор" или "Множественный выбор"?

Проанализируем разницу в подходах. То, что мы реализовали выше — это множественный выбор. Пользователь открывает форму, выделяет несколько строк через Ctrl или Shift, нажимает "Выбрать", форма закрывается, и данные попадают в документ.

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

ПараметрыФормы.Вставить("ЗакрыватьПриВыборе", Ложь);

В этом случае форма справочника останется открытой, а событие ОбработкаВыбора будет срабатывать каждый раз, когда пользователь нажимает кнопку выбора или дважды кликает по элементу. Это значительно ускоряет работу при больших объемах вводимых данных.

Итоги

Мы рассмотрели, как правильно организовать множественный выбор в 1С. Основной секрет успеха заключается в использовании правильных событий (ПередНачаломДобавления для открытия и ОбработкаВыбора для заполнения) и корректной обработке массива возвращаемых значений. Не забывайте также про флаг Модифицированность, чтобы система предложила пользователю сохранить документ после внесения таких изменений.

← На главную