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

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

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

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

Почему возникает проблема «одинакового списка» во всех строках?

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

Если мы напрямую обращаемся к свойству элемента СписокВыбора и перезаписываем его, изменения применяются ко всему шаблону колонки целиком. В результате:

  1. Во всех строках начинает отображаться один и тот же список выбора.
  2. Если для колонки включен жесткий РежимВыбораИзСписка, в неактивных строках могут пропасть текстовые представления значений, так как платформа не найдет текущие значения строк в обновленном списке выбора. Вместо понятного текста пользователь увидит пустые ячейки или «битые» идентификаторы.

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

---

Способ 1. Использование метода ПоказатьВыборИзСписка (Рекомендуемый асинхронный метод)

Этот способ является наиболее надежным и современным для управляемых форм 1С. Мы полностью отказываемся от стандартного выпадающего списка элемента управления и перехватываем процесс выбора. Список формируется и показывается программно в момент клика по кнопке выбора.

Разберем по шагам настройку элементов формы:

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

Рассмотрим пример кода для модуля управляемой формы:


&НаКлиенте
Процедура ТЧПоле3НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    
    // 1. Отменяем стандартное системное открытие окон выбора
    СтандартнаяОбработка = Ложь; 
    
    // 2. Получаем данные текущей строки табличной части
    ТекДанные = Элементы.ТЧ.ТекущиеДанные;
    Если ТекДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // 3. Динамически формируем список выбора в зависимости от значения во второй колонке
    СписокВариантов = Новый СписокЗначений;
    
    Если ТекДанные.Поле2 = 1 Тогда
        СписокВариантов.Добавить("Значение_1_1", "Вариант А");
        СписокВариантов.Добавить("Значение_1_2", "Вариант Б");
    ИначеЕсли ТекДанные.Поле2 = 2 Тогда
        СписокВариантов.Добавить("Значение_2_1", "Вариант В");
        СписокВариантов.Добавить("Значение_2_2", "Вариант Г");
    КонецЕсли;
    
    // 4. Описываем обработчик оповещения для обработки выбора пользователя (требование асинхронности)
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораИзСписка", ЭтотОбъект);
    
    // 5. Выводим список выбора на экран непосредственно под редактируемым элементом
    ПоказатьВыборИзСписка(Оповещение, СписокВариантов, Элемент);
    
КонецПроцедуры

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

Преимущества метода: Абсолютная независимость строк друг от друга. Неактивные строки никак не затрагиваются, их текстовые представления не "ломаются". Метод работает полностью асинхронно и соответствует всем современным стандартам разработки фирмы «1С».

---

Способ 2. Обновление списка в событии ПриАктивизацииСтроки

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

Посмотрим на пример реализации данного подхода:


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

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

---

Способ 3. Бескодовый метод через механизм «Связи параметров выбора»

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

Выполним следующую настройку в конфигураторе:

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

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

---

Оптимизация: Получение динамического списка с сервера без контекста

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


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

&НаСервереБезКонтекста
Функция ПолучитьСписокВыбораНаСервере(ЗначениеПоля2)
    
    Список = Новый СписокЗначений;
    
    // Выполняем легкий запрос к базе данных
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	Номенклатура.Ссылка КАК Ссылка,
        |	Номенклатура.Наименование КАК Наименование
        |ИЗ
        |	Справочник.Номенклатура КАК Номенклатура
        |ГДЕ
        |	Номенклатура.Родитель = &Родитель";
    
    Запрос.УстановитьПараметр("Родитель", ЗначениеПоля2);
    Выборка = Запрос.Выполнить().Выбрать();
    
    Пока Выборка.Следующий() Цикл
        Список.Добавить(Выборка.Ссылка, Выборка.Наименование);
    КонецЦикла;
    
    Возврат Список;
    
КонецФункции

Использование директивы &НаСервереБезКонтекста гарантирует, что при вызове серверной функции на сервер не будет отправляться "тяжелый" XML-пакет с состоянием всех реквизитов формы. Это существенно ускоряет работу программы, особенно при работе пользователей через медленное интернет-соединение или веб-клиент.

← На главную