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

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

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

Понимание механизма отборов в динамическом списке

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

  1. Настройки (Settings): пользовательские настройки (включая условное оформление), которые могут быть изменены через меню "Настроить список".
  2. Фиксированные настройки (FixedSettings): программно заданные условия, которые пользователь не может изменить или удалить через стандартный интерфейс. Это наиболее подходящее место для реализации жестких фильтров по периоду.
  3. Пользовательские настройки (UserSettings): настройки, вынесенные непосредственно на форму для быстрого доступа.

Рассмотрим по шагам, как добавить элементы отбора в ФиксированныеНастройки.

Способ 1: Программное добавление элементов отбора

Представим ситуацию: на форме есть реквизиты ПериодНачало и ПериодКонец. Нам необходимо, чтобы при их изменении динамический список Список фильтровал записи по полю Дата. Разберем алгоритм реализации:

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


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

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

Способ 2: Использование параметров запроса

Если ваш динамический список построен на произвольном запросе, мы можем пойти другим путем — использовать параметры самого запроса. Это зачастую работает быстрее, так как условие ГДЕ внедряется непосредственно в SQL-запрос. Выясним, как это реализовать.

Допустим, в тексте запроса динамического списка прописано условие:
ГДЕ Таблица.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания

Тогда программный код для обновления списка будет выглядеть следующим образом:


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

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

Разбор типичных ошибок и нюансов

Рассмотрим подробнее несколько важных моментов, с которыми сталкиваются программисты:

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

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

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

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

← На главную