Как правильно настроить отбор по дате при открытии формы списка в 1С

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

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

Почему стандартный отбор по дате не работает?

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

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

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

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

Разберем по шагам, как сформировать такие настройки в коде команды открытия формы:


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

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

Способ 2. Программная установка отбора в «ПриСозданииНаСервере»

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

Сначала в коде вызова (например, в обработке):


&НаКлиенте
Процедура ОткрытьСПараметром(Команда)
    ПараметрыОткрытия = Новый Структура("ДатаДляФильтра", ТекущаяДата());
    ОткрытьФорму("Документ.ПеремещениеТоваров.Форма.ФормаСписка", ПараметрыОткрытия);
КонецПроцедуры

Затем в модуле формы списка документов ПеремещениеТоваров пропишем логику установки фильтра:


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

Важный нюанс: при таком способе отбор добавляется в пользовательские настройки. Если вы хотите, чтобы пользователь видел эти фильтры и мог их изменить, установите режим отображения элемента отбора в значение БыстрыйДоступ. Для быстрого поиска других типовых функций работы с интерфейсом и списками подойдёт справочник по методам БСП с примерами использования.

Способ 3. Использование стандартного параметра «Период»

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


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

Этот метод самый лаконичный, но у него есть особенность: он устанавливает период для всей формы списка целиком (аналог кнопки «Установить период»). Если в динамическом списке используется сложный произвольный запрос, убедитесь, что в нем включена стандартная функция «Период».

Дополнительные рекомендации по производительности и индексации

При работе с большими базами данных (сотни тысяч документов) просто написать код отбора недостаточно. Проанализируем критические моменты, которые влияют на скорость открытия формы:

  1. Индексирование полей: Все поля, которые вы используете в отборах (например, ваш кастомный «Статус» или «Склад»), должны иметь свойство «Индексировать» в конфигураторе. Стандартные реквизиты, такие как Дата, Проведен и ПометкаУдаления, индексируются платформой автоматически.
  2. Ключ назначения использования: Если вы открываете одну и ту же форму списка с разными программными отборами в разных местах программы, используйте параметр КлючНазначенияИспользования. Это предотвратит ситуацию, когда 1С пытается восстановить настройки колонок и фильтров от предыдущего (другого) открытия формы, что может привести к конфликтам.
  3. Минимизация обращений к серверу: Всегда старайтесь подготовить структуру ФиксированныеНастройки на клиенте (как показано в Способе 1), чтобы форма открылась сразу с нужным результатом, без дополнительных серверных вызовов в ПриСозданииНаСервере.

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

← На главную