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

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

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

Механизм передачи контекста в управляемую форму

Для начала проанализируем ситуацию: почему первый список фильтруется автоматически? Когда в метаданных измерения регистра сведений указано свойство Ведущее, платформа при переходе из формы владельца в список регистра передает специальный параметр Отбор. Этот параметр представляет собой структуру, где ключом является имя измерения, а значением — ссылка на объект-владелец.

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

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

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

  1. Проверим наличие ключа Отбор в параметрах формы.
  2. Обойдем структуру переданного отбора.
  3. Для каждого элемента создадим новый элемент отбора в компоновщике настроек второго списка.

Рассмотрим пример кода, который реализует эту логику:


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

Обратите внимание на использование ФиксированныеНастройки. Если установить отбор в обычные Настройки, пользователь сможет изменить или удалить его через меню «Настроить список». Использование фиксированных настроек гарантирует, что второй список всегда будет жестко связан с контекстом открытия формы.

Решение 2: Копирование настроек между списками

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Получаем текущие настройки основного списка
    ТекущиеНастройки = Список1.КомпоновщикНастроек.ПолучитьФиксированныеНастройки();
    
    // Загружаем их во второй список
    Список2.КомпоновщикНастроек.ЗагрузитьФиксированныеНастройки(ТекущиеНастройки);
    
КонецПроцедуры

Важный нюанс: этот метод сработает корректно только в том случае, если поля, по которым установлен отбор в Список1, присутствуют в схеме компоновки данных Список2.

Решение 3: Динамическая синхронизация при изменении отборов

Рассмотрим ситуацию, когда пользователю разрешено менять отборы в первом списке, и мы хотим, чтобы второй список мгновенно на это реагировал. Использовать событие ПриАктивацииСтроки для этих целей не рекомендуется, так как это приведет к избыточным серверным вызовам при обычном перемещении курсора по таблице.

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


&НаСервере
Процедура ПриОбновленииСоставаПользовательскихНастроекНаСервере(Узел)
    
    // Синхронизируем пользовательские настройки отбора
    // Данный подход позволяет второму списку "следовать" за фильтрами первого
    Отбор1 = Список1.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;
    Отбор2 = Список2.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;
    
    // Здесь можно реализовать логику копирования конкретных элементов
    // или полной замены коллекции настроек
    
КонецПроцедуры

Почему не стоит использовать запросы для получения значения?

Проанализируем предложение получать значение ведущего измерения через запрос к первой строке списка. Это плохая практика по нескольким причинам:

Подведение итогов

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

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

← На главную