Как программно установить отбор по дате в динамическом списке 1С, чтобы он работал быстро и был виден пользователю?

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

В процессе разработки на платформе 1С:Предприятие 8.3 часто возникает ситуация, когда в динамическом списке (например, в журнале документов «Чеки ККМ» в конфигурации «Розница») накапливается огромное количество данных. Если открывать такой список без предварительной фильтрации, система пытается считать все записи, что приводит к длительному ожиданию. Пользователи часто жалуются на «зависание» формы при открытии.

Рассмотрим, как правильно установить отбор по дате программно в момент создания формы, чтобы данные отсекались на уровне запроса к СУБД, а интерфейс оставался отзывчивым и понятным для пользователя.

Почему стандартные методы иногда не работают?

Разберем типичную ошибку. Часто разработчики пытаются установить период через свойство формы Элементы.Список.Период уже после того, как форма открыта. Проблема заключается в том, что если данные уже начали считываться, применение фильтра постфактум не отменяет первичную нагрузку на базу данных. Кроме того, установка простого равенства дат ВидСравнения.Равно часто не находит записей, так как в 1С тип Дата всегда содержит время (часы, минуты, секунды), и точное совпадение с «началом дня» случается редко.

Способ 1. Использование встроенного механизма периода (для визуального отображения)

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


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

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

Способ 2. Программное добавление элемента отбора в Компоновщик настроек

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

Рассмотрим наиболее надежный вариант добавления отбора через коллекцию Отбор.Элементы. Чтобы избежать проблем со временем в датах, будем использовать вид сравнения БольшеИлиРавно.


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

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

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

Способ 3. Использование фиксированных настроек (максимальная производительность)

Если ваша задача — жестко ограничить данные (например, запретить видеть документы прошлых периодов в конкретном АРМ), следует использовать ФиксированныеНастройки. Посмотрим на пример, как это реализовать. Такие настройки накладываются поверх всех пользовательских фильтров и не могут быть изменены пользователем в интерфейсе.


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

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

Важные нюансы при работе в расширениях

Проанализируем ситуацию, когда разработка ведется в расширении (как в исходном вопросе). При использовании обработчиков &После("ПриСозданииНаСервере") нужно быть осторожным. Если в основной конфигурации уже прописана логика восстановления настроек пользователя, ваш программный код может выполниться, но затем система «накроет» его сохраненными ранее настройками конкретного пользователя.

Совет: Чтобы ваш отбор гарантированно применился, попробуйте принудительно очистить пользовательские настройки отбора перед установкой своих или используйте именно ФиксированныеНастройки.

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

  1. Использовать НачалоДня() для исключения ошибок сравнения из-за времени.
  2. Применять вид сравнения БольшеИлиРавно или Интервал.
  3. Управлять коллекцией Список.Отбор для обеспечения видимости фильтра пользователю.
  4. Использовать ФиксированныеНастройки для оптимизации скорости открытия формы на огромных массивах данных.

Соблюдение этих правил позволит сделать работу пользователей в системе комфортной, а открытие журналов документов — мгновенным.

← На главную