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

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

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

Для эффективной работы с динамическими списками в 1С 8.3 нам предстоит освоить два основных метода: управление отбором через объект КомпоновщикНастроекДинамическогоСписка и использование параметров запроса, на котором построен динамический список. Выбор конкретного метода будет зависеть от сложности требуемого отбора и от того, насколько глубоко мы хотим контролировать источник данных списка.

Подход 1: Использование КомпоновщикаНастроекДинамическогоСписка

Динамический список в управляемых формах 1С 8.3 тесно связан с Системой Компоновки Данных (СКД). Фактически, динамический список является визуальным представлением данных, которые формируются на основе настроек СКД. Объект КомпоновщикНастроекДинамическогоСписка предоставляет нам прямой доступ к этим настройкам, позволяя программно добавлять, изменять или удалять элементы отбора.

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

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

  1. Получаем доступ к настройкам отбора:

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

  2. Создаем новый элемент отбора:

    Мы добавляем новый элемент в коллекцию Элементы. Каждый элемент отбора представлен объектом типа ЭлементОтбораКомпоновкиДанных.

    
    ЭлементОтбора = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    
  3. Определяем левое значение отбора:

    ЛевоеЗначение – это поле, по которому мы будем производить отбор. Мы указываем его как новый объект ПолеКомпоновкиДанных, передавая в конструктор строковое имя поля.

    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ответственный");
  4. Устанавливаем вид сравнения:

    ВидСравнения определяет, как будут сравниваться левое и правое значения. Для простого равенства используем ВидСравненияКомпоновкиДанных.Равно.

    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

    Существует множество других видов сравнения, таких как Больше, Меньше, БольшеИлиРавно, МеньшеИлиРавно, НеРавно, ВСписке, НеВСписке, Содержит, НеСодержит, НачинаетсяС, ОканчиваетсяНа, Между, НеМежду, Заполнено, НеЗаполнено и другие. Выбор нужного вида сравнения позволяет нам создавать очень гибкие условия отбора, соответствующие пользовательским требованиям.

  5. Определяем правое значение отбора:

    ПравоеЗначение – это то значение, с которым будет сравниваться поле. В нашем случае это может быть ТекущийПользователь или любое другое конкретное значение.

    
    ЭлементОтбора.ПравоеЗначение = ТекущийПользователь; // Или другое необходимое значение, например, конкретная ссылка
    
  6. Активируем элемент отбора:

    Чтобы отбор вступил в силу, необходимо установить свойство Использование в Истина.

    ЭлементОтбора.Использование = Истина;
  7. Обновляем динамический список:

    После всех изменений настроек компоновщика, чтобы список перечитал данные с учетом нового отбора, обязательно вызываем метод Обновить() у динамического списка.

    Список.Обновить();

Полный пример кода для установки простого отбора:


&НаСервере
Процедура УстановитьОтборПоОтветственномуНаСервере()

    // Проверяем, что динамический список инициализирован
    Если Список = Неопределено Тогда
        Возврат;
    КонецЕсли;

    // Очистим предыдущие отборы, если они есть, чтобы не дублировать
    // или чтобы новый отбор не конфликтовал с существующими.
    // Если нужно добавить отбор к существующим, этот шаг можно пропустить.
    Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Очистить();

    // Создаем новый элемент отбора
    ЭлементОтбора = Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));

    // Указываем поле, по которому будем отбирать
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Ответственный");

    // Указываем вид сравнения (например, "Равно")
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;

    // Указываем значение, с которым будем сравнивать
    // Например, можно получить текущего пользователя
    ЭлементОтбора.ПравоеЗначение = Пользователи.ТекущийПользователь();

    // Активируем элемент отбора
    ЭлементОтбора.Использование = Истина;

    // Важно: если нужен пользовательский режим, его тоже можно установить
    // ЭлементОтбора.РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновкиДанных.НеОтображать;
    // Или РежимОтображенияЭлементаНастройкиКомпоновкиДанных.ОтображатьВсегда

    // Обновляем динамический список, чтобы применить отбор
    Список.Обновить();

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

Мы можем также установить сложный отбор, используя группы отбора. Для этого вместо добавления ЭлементОтбораКомпоновкиДанных непосредственно в коллекцию Элементы отбора, мы можем добавить ГруппаЭлементовОтбораКомпоновкиДанных и уже в нее добавлять отдельные элементы. Это позволяет нам создавать отборы с условиями "И", "ИЛИ" и произвольными группировками.


&НаСервере
Процедура УстановитьСложныйОтборНаСервере()
    
    Если Список = Неопределено Тогда
        Возврат;
    КонецЕсли;

    Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Очистить();

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

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

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

    Список.Обновить();

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

Изменение и отмена отбора через КомпоновщикНастроек

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

  1. Изменение существующего отбора:

    Чтобы изменить уже установленный отбор, нам сначала нужно его найти в коллекции Список.КомпоновщикНастроек.Настройки.Отбор.Элементы. Мы можем перебрать эту коллекцию и найти элемент по ЛевоеЗначение или другим критериям. После того как элемент найден, мы можем изменить его ПравоеЗначение, ВидСравнения или другие свойства.

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

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

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

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

    
    &НаСервере
    Процедура ОчиститьВсеОтборыНаСервере()
        
        Если Список = Неопределено Тогда
            Возврат;
        КонецЕсли;
    
        Список.КомпоновщикНастроек.Настройки.Отбор.Элементы.Очистить();
        Список.Обновить();
    
    КонецПроцедуры
    

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

Подход 2: Использование параметров запроса динамического списка

Второй подход к программной установке отбора основывается на прямом управлении параметрами запроса, на котором построен динамический список. Этот метод особенно полезен, когда:

Для реализации этого подхода нам предстоит выполнить следующие шаги:

  1. Определяем параметр в запросе:

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

    
    ВЫБРАТЬ
        Документ.Ссылка,
        Документ.Номер,
        Документ.Дата,
        Документ.Ответственный
    ИЗ
        Документ.МойДокумент КАК Документ
    ГДЕ
        Документ.Ответственный = &Ответственный
    

    Знак & перед именем параметра (&Ответственный) указывает, что это именно параметр запроса, значение которого будет подставлено извне.

  2. Устанавливаем значение параметра программно:

    После того как параметр определен в запросе, мы можем установить его значение программно, используя коллекцию Параметры динамического списка и метод УстановитьЗначениеПараметра().

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

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

    Если нам нужно установить несколько параметров, мы просто повторяем вызов УстановитьЗначениеПараметра() для каждого из них. Например, для отбора по периоду:

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

Управление параметрами запроса

Изменение или сброс отбора, установленного через параметры запроса, также выполняется через коллекцию Список.Параметры.

  1. Изменение значения параметра:

    Чтобы изменить значение параметра на лету, мы снова вызываем УстановитьЗначениеПараметра() с новым значением.

    
    &НаСервере
    Процедура ИзменитьПараметрОтветственныйНаСервере(НовыйОтветственный)
        
        Если Список = Неопределено Тогда
            Возврат;
        КонецЕсли;
    
        Если Список.Параметры.ЕстьПараметр("Ответственный") Тогда
            Список.Параметры.УстановитьЗначениеПараметра("Ответственный", НовыйОтветственный);
        КонецЕсли;
    
        Список.Обновить();
    
    КонецПроцедуры
    
  2. Сброс (отключение) параметра:

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

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

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

Важные нюансы и рекомендации

Независимо от выбранного подхода, мы всегда должны помнить о некоторых общих принципах и рекомендациях:

  1. Всегда вызывайте Список.Обновить(): Как уже упоминалось, после любых программных изменений настроек отбора или параметров запроса динамического списка, мы обязаны вызвать метод Список.Обновить(). Это командует платформе перечитать данные списка с учетом новых условий. Если этого не сделать, список продолжит отображать данные по старым правилам.
  2. Проверяйте доступность полей: При работе с КомпоновщикНастроек убедитесь, что поле, по которому вы устанавливаете отбор, действительно присутствует в доступных полях динамического списка. Если поле отсутствует в схеме компоновки данных списка, попытка установить по нему отбор приведет к ошибке.
  3. Учитывайте права доступа и RLS: Программно установленные отборы не отменяют и не обходят ограничения прав доступа на уровне записей (RLS). Если у пользователя нет прав на просмотр некоторых данных, они не будут показаны, даже если программный отбор предполагает их включение. Это важно учитывать при разработке логики отображения данных.
  4. Производительность: Сложные отборы или большое количество элементов отбора могут влиять на производительность динамического списка, особенно на больших объемах данных. Всегда стремитесь к максимально эффективным условиям отбора. При использовании параметров запроса, убедитесь, что индексы в базе данных настроены для полей, участвующих в условиях ГДЕ.
  5. Отладка: Если отбор не работает как ожидалось, мы можем использовать стандартные средства отладки 1С. Для КомпоновщикаНастроек можно посмотреть его содержимое в отладчике, чтобы убедиться, что элементы отбора созданы и активированы правильно. Для параметров запроса, мы можем проверить значения, которые им присваиваются. Также полезно бывает временно вывести текст запроса динамического списка (если это возможно) и убедиться, что параметры подставились корректно.

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

← На главную