Как реализовать зависимый выбор в подчиненном справочнике внутри табличной части документа

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

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

Постановка задачи и архитектура данных

Прежде чем переходить к настройке интерфейса, проанализируем структуру наших метаданных. У нас есть два справочника:

  1. КатегорииБилетов — родительский справочник (владелец).
  2. КатегорииКлиентов — подчиненный справочник. В его настройках на закладке «Владельцы» должен быть указан справочник КатегорииБилетов.

В документе (например, «Билет») создана табличная часть, содержащая два реквизита: КатегорияБилета (тип СправочникСсылка.КатегорииБилетов) и КатегорияКлиента (тип СправочникСсылка.КатегорииКлиентов). Наша цель — сделать так, чтобы при нажатии на кнопку выбора в колонке «Категория клиента» пользователь видел только те элементы, которые принадлежат выбранной в этой же строке «Категории билета».

Способ 1: Использование механизма «Связи параметров выбора»

Это самый эффективный и предпочтительный метод, так как он реализуется на уровне свойств реквизитов без написания кода. Платформа 1С берет на себя всю работу по фильтрации списка.

Рассмотрим по шагам, как это настроить:

  1. Откроем в конфигураторе дерево метаданных и найдем наш документ.
  2. Перейдем в состав табличной части и выберем реквизит КатегорияКлиента.
  3. В палитре свойств найдем категорию «Представление» и пункт «Связи параметров выбора».
  4. Нажмем на кнопку выбора (три точки). В открывшемся окне создадим новую связь:
    • В поле «Элемент связи» выберем реквизит этой же табличной части — Объект.ИмяВашейТабличнойЧасти.КатегорияБилета.
    • В поле «Параметр выбора» система автоматически предложит варианты. Нам нужно выбрать Отбор.Владелец.
  5. Сохраним изменения.

Теперь, когда пользователь будет выбирать клиента, система автоматически передаст в форму выбора идентификатор владельца, и список будет отфильтрован «из коробки».

Способ 2: Программная очистка зависимых значений

Проанализируем важный нюанс юзабилити. Если пользователь сначала выбрал «Категорию билета» (например, «VIP») и соответствующую «Категорию клиента», а затем решил изменить билет на «Эконом», то ранее выбранный клиент останется в строке, хотя он уже не соответствует новому владельцу. Это логическая ошибка данных.

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


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

Этот простой обработчик гарантирует актуальность данных в каждой строке вашей таблицы.

Способ 3: Программная установка отбора в событии «НачалоВыбора»

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

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


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

Работа с «Историей выбора» и удобство интерфейса

Выясним причину, по которой пользователи иногда жалуются на «странные» значения в списке выбора. В 1С по умолчанию включена функция «История выбора». Если пользователь ранее выбирал клиента из категории «Эконом», этот клиент может отобразиться в подсказке (быстром выборе), даже если сейчас в строке выбрана категория «VIP».

Чтобы избежать путаницы, рекомендуем выполнить следующие настройки для элемента формы КатегорияКлиента:

Альтернативный подход: Использование регистров сведений

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

В такой ситуации профессиональная разработка предполагает использование Регистра сведений (например, СоответствиеКатегорий). В нем создаются две записи: КатегорияБилета и КатегорияКлиента. Тогда при выборе в документе мы будем программно опрашивать этот регистр через запрос в событии НачалоВыбора и формировать массив доступных ссылок для отбора.

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

← На главную