Почему при программной установке периода в ДокументСписок отображаются только проведенные документы?

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

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

Разберем детально, почему возникает иллюзия фильтрации по признаку проведения, как работает системное перечисление ВидСравнения и как правильно настраивать фильтрацию по диапазону дат в коде модулей.

В чем заключается корень проблемы

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


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

На первый взгляд код выглядит полностью корректным: получено начало дня (00:00:00), конец дня (23:59:59) и задан интервал. Однако именно в значении ВидСравнения.Интервал кроется критическая ошибка.

Рассмотрим, как платформа 1С транслирует различные виды сравнения в условия базы данных (SQL):

  1. ВидСравнения.Интервал — строгое математическое неравенство (открытый интервал). Проверяется условие: Дата > ЗначениеС И Дата < ЗначениеПо. Обе границы диапазона полностью исключаются из выборки.
  2. ВидСравнения.ИнтервалВключаяГраницы — нестрогое неравенство (закрытый интервал/отрезок). Проверяется условие: Дата >= ЗначениеС И Дата <= ЗначениеПо. Документы, попавшие ровно на граничные секунды, остаются в выборке.
  3. ВидСравнения.ИнтервалВключаяНачало — полуинтервал: Дата >= ЗначениеС И Дата < ЗначениеПо.
  4. ВидСравнения.ИнтервалВключаяОкончание — полуинтервал: Дата > ЗначениеС И Дата <= ЗначениеПо.

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

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

  1. Непроведенные документы: создаются пользователями вручную с указанием только даты без времени, загружаются из внешних источников или создаются обработками. По умолчанию платформа и разработчики записывают такие документы с временем начала суток — ровно 00:00:00.
  2. Проведенные документы: при оперативном проведении или автопозиционировании получают реальное время (например, 14:35:12) или сдвигаются системой вглубь секунды.

Когда устанавливается условие ВидСравнения.Интервал со ЗначениеС = 12.10.2017 00:00:00, платформа формирует запрос: «выбрать документы, где дата строго больше 12.10.2017 00:00:00». Все непроведенные документы, записанные ровно на полночь, моментально отсекаются условием. Проведенные же документы, имеющие время больше полуночи, благополучно отображаются в списке. Это создает ложное впечатление, что в списке активен скрытый отбор по реквизиту Проведен.

Правильная реализация программной установки периода

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


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

Альтернативный вариант: метод Установить()

В платформе 1С объект элемента отбора поддерживает метод Установить(). Однако при работе с интервалами важно помнить: стандартная передача одиночного значения переключает вид сравнения в ВидСравнения.Равно. Для задания диапазона через свойства объекта рекомендуется явное присвоение ЗначениеС, ЗначениеПо и ВидСравнения.ИнтервалВключаяГраницы.

Если требуется привязать стандартную панель выбора периода к элементу управления НастройкаПериода, используем следующий подход:


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

Стандартный диалог командной панели «Установить интервал» всегда по умолчанию использует именно ИнтервалВключаяГраницы, поэтому интерактивная настройка никогда не теряет документы на границах суток.

← На главную