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

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

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

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

1. Почему код отбора не отслеживается по точкам останова

Проанализируем частую проблему: точка останова в событии ПриАктивизацииСтроки срабатывает, но при пошаговом выполнении (F11) отладчик не заходит в процедуры установки отбора. Посмотрим на типовой код такого события:


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

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

Выясним, зачем используется такая схема: при быстром перемещении стрелками по списку событие ПриАктивизацииСтроки вызывается для каждой промежуточной строки. Использование обработчика ожидания предотвращает заспамливание сервера лишними запросами отборов. Чтобы отладить логику связки, необходимо найти глобальным поиском по модулю формы имя процедуры, переданное в первом параметре — например, УстановитьЭлементыОтбораЗБ — и поставить точку останова непосредственно внутри неё.

2. Способы связывания таблиц в управляемых формах

В зависимости от того, какими типами данных представлены таблицы на форме (динамический список или табличная часть/таблица значений), применяются разные механизмы отбора.

Способ А: Отбор для табличной части или Таблицы Значений на форме

Если нижняя таблица отображает данные табличной части или реквизита формы типа ТаблицаЗначений, для фильтрации применяется свойство элемента формы ОтборСтрок.

Разберем по шагам, как это реализуется в коде процедур формы:

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

Способ Б: Отбор для Динамического Списка

Если нижняя таблица связана с динамическим списком, установку фильтров рекомендуется выполнять через ФиксированныеНастройки компоновщика настроек, чтобы пользователь случайно не сбросил системный отбор.

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


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

Если запрос динамического списка содержит параметризованное условие (например, ГДЕ Таблица.Владелец = &Владелец), отбор устанавливается еще проще через коллекцию параметров:


СписокПодчиненный.Параметры.УстановитьЗначениеПараметра("Владелец", ТекущиеДанные.Ссылка);

Способ В: Декларативная связь без написания кода

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

  1. Откроем форму в редакторе и выделим подчиненную таблицу (или реквизит выборки).
  2. В палитре свойств найдем категорию Использование и свойство Связи параметров выбора.
  3. Укажем связь ключевого поля подчиненной таблицы с полем Элементы.ВерхняяТаблица.ТекущиеДанные.Ссылка.

В этом случае платформа автоматически синхронизирует выборку при смене текущей строки в верхней таблице.

← На главную