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

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

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

Понимание структуры динамического списка

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

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

Разберем по шагам процесс установки отбора

Для корректной установки фильтра мы должны выполнить последовательность действий. Проанализируем типичный пример кода для установки отбора:


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

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

В данном примере мы использовали объект ПолеКомпоновкиДанных. Это критически важно, так как коллекция Отбор работает именно с этим типом данных. Мы также применили свойство Использование. Это позволяет нам гибко управлять фильтром: если ЗначениеОтбора не заполнено, фильтр автоматически отключается, не ограничивая список.

Работа с группами отборов

Иногда задача усложняется: нам нужно установить условие «ИЛИ» (например, показать документы либо одного контрагента, либо другого). Рассмотрим подробнее, как работать с группами. Разберем ситуацию, когда нам нужно объединить несколько условий в одну логическую структуру:

  1. Создаем группу элементов отбора через ГруппаЭлементовОтбораКомпоновкиДанных.
  2. Устанавливаем тип группы: ГруппаТипаИЛИ, ГруппаТипаИ или ГруппаТипаНЕ.
  3. Добавляем внутрь этой группы конкретные элементы ЭлементОтбораКомпоновкиДанных.

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


ГруппаИЛИ = Список.КомпоновкаДанных.Настройки.Отбор.Элементы.Добавить(Тип("ГруппаЭлементовОтбораКомпоновкиДанных"));
ГруппаИЛИ.ТипГруппы = ТипГруппыЭлементовОтбораКомпоновкиДанных.ГруппаИЛИ;

НовыйОтбор = ГруппаИЛИ.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("СуммаДокумента");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.Больше;
НовыйОтбор.ПравоеЗначение = 100000;

Настройка программного условного оформления

Помимо фильтрации, часто требуется визуально выделить строки. Например, подсветить красным цветом просроченные платежи. Это реализуется через УсловноеОформление. В динамических списках оно также живет внутри настроек компоновки данных.

Проанализируем алгоритм создания оформления:

  1. Добавляем новый элемент в коллекцию УсловноеОформление.Элементы.
  2. Определяем Оформление (что менять: цвет, шрифт, текст).
  3. Определяем Условие (когда применять).
  4. Определяем Оформляемые поля (какие колонки красить).

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

// Настраиваем цвет фона
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("ЦветФона", WebЦвета.СветлоЗеленый);

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

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

Оптимизация производительности

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

Также обратим внимание на использование Произвольного запроса. Если вы используете собственный текст запроса, убедитесь, что в нем присутствует секция {ГДЕ}. Это специальный тег СКД, который указывает системе, в какое место запроса нужно подставлять ваши программные отборы. Без этого тега платформа может обернуть весь ваш запрос во вложенный, что негативно скажется на производительности SQL.

Рассмотрим пример правильного написания запроса:


ВЫБРАТЬ
    Док.Ссылка,
    Док.Дата,
    Док.Номер,
    Док.Контрагент
ИЗ
    Документ.РеализацияТоваровУслуг КАК Док
{ГДЕ
    Док.Ссылка.*,
    Док.Контрагент.*}

Использование конструкции .* позволяет системе динамически расширять доступные поля для отборов, включая реквизиты объектов (например, Контрагент.ИНН).

Типичные ошибки и советы

В процессе совместной работы над кодом часто встречаются следующие ошибки, которые мы сейчас разберем:

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

← На главную