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

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

В практике разработки на платформе 1С часто возникает задача добавить в форму списка документов возможность фильтрации не по стандартной дате документа, а по произвольному реквизиту, например, ДатаЗаказа или ДатаОтгрузки. Если для стандартной даты существует встроенная кнопка «Установить интервал дат», то для кастомных реквизитов логику выбора периода и применения отбора приходится писать вручную. Разберем по шагам, как реализовать этот функционал в обычном приложении, используя встроенные инструменты платформы.

Шаг 1: Вызов диалога выбора периода

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

Проанализируем следующий код:


Процедура ВыбПериодНажатие(Элемент)
    НастройкаПериода = Новый НастройкаПериода;
    
    // Устанавливаем текущие значения в диалог, чтобы пользователь видел текущий фильтр
    НастройкаПериода.УстановитьПериод(НачДата, ?(КонДата='0001-01-01', КонДата, КонецДня(КонДата)));
    
    // Настраиваем поведение диалога
    НастройкаПериода.РедактироватьКакИнтервал = Истина;
    НастройкаПериода.РедактироватьКакПериод = Истина;
    НастройкаПериода.ВариантНастройки = ВариантНастройкиПериода.Период;
    
    // Открываем модальное окно выбора
    Если НастройкаПериода.Редактировать() Тогда
        НачДата = НастройкаПериода.ПолучитьДатуНачала();
        КонДата = НастройкаПериода.ПолучитьДатуОкончания();
        
        // После получения дат необходимо вызвать процедуру применения отбора
        ОбновитьОтборНаСписке();
    КонецЕсли;
КонецПроцедуры

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

Шаг 2: Программная установка отбора в списке

После того как мы получили границы периода, нам нужно применить их к динамическому списку документов. Обычная ошибка начинающих разработчиков заключается в попытке присвоить интервал в свойство Значение. Однако для вида сравнения Интервал в 1С предусмотрены специальные свойства: ЗначениеС (нижняя граница) и ЗначениеПо (верхняя граница).

Выясним, как правильно настроить объект Отбор для вашего списка документов (например, ДокументСписок):


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

Важный момент: Мы использовали ВидСравнения.ИнтервалВключаяГраницы. В платформе 1С существует несколько вариантов интервалов (включая начало, включая окончание или без границ). Для бухгалтерских и управленческих задач чаще всего требуется именно включение обеих границ периода.

Шаг 3: Оптимизация и тонкая настройка

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

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

Альтернативный подход: Использование СтандартныйПериод

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

Посмотрим на пример реализации с этим объектом:


// 1. Создаем реквизит формы "ВыбранныйПериод" с типом СтандартныйПериод
// 2. Код вызова диалога:
Диалог = Новый РедакторСтандартногоПериода;
Диалог.Период = ВыбранныйПериод;

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

Проанализировав ситуацию, мы видим, что использование СтандартныйПериод упрощает код и делает интерфейс более привычным для современного пользователя 1С. Однако классический метод с НастройкаПериода остается полностью рабочим и часто встречается в типовых конфигурациях на обычных формах (например, УПП 1.3 или УТ 10.3).

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

← На главную