При разработке и доработке конфигураций на обычных формах (1С:Предприятие 8.2 / 8.3) разработчики часто сталкиваются с нестандартным поведением динамических списков документов (объект ДокументСписок). Типичная ситуация: после программной установки отбора по дате в табличном поле перестают отображаться непроведенные документы за выбранный период, в то время как проведенные остаются на экране. При этом интерактивная установка периода через стандартную кнопку командной панели показывает абсолютно все документы корректно.
Разберем детально, почему возникает иллюзия фильтрации по признаку проведения, как работает системное перечисление ВидСравнения и как правильно настраивать фильтрацию по диапазону дат в коде модулей.
Проанализируем типовой фрагмент кода, который часто пишется разработчиками для фильтрации списка за произвольный интервал:
Процедура УстановитьИнтервал()
ЭлементОтбора = Список.Отбор.Дата;
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.ЗначениеС = НачалоДня(ДатаПериода);
ЭлементОтбора.ЗначениеПо = КонецДня(ДатаПериода);
ЭлементОтбора.ВидСравнения = ВидСравнения.Интервал;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
На первый взгляд код выглядит полностью корректным: получено начало дня (00:00:00), конец дня (23:59:59) и задан интервал. Однако именно в значении ВидСравнения.Интервал кроется критическая ошибка.
Рассмотрим, как платформа 1С транслирует различные виды сравнения в условия базы данных (SQL):
Дата > ЗначениеС И Дата < ЗначениеПо. Обе границы диапазона полностью исключаются из выборки.Дата >= ЗначениеС И Дата <= ЗначениеПо. Документы, попавшие ровно на граничные секунды, остаются в выборке.Дата >= ЗначениеС И Дата < ЗначениеПо.Дата > ЗначениеС И Дата <= ЗначениеПо.Выясним причину, по которой поведение фильтра кажется связанным с проведением документов. В типовых и доработанных конфигурациях время документов распределяется следующим образом:
00:00:00.14:35:12) или сдвигаются системой вглубь секунды.Когда устанавливается условие ВидСравнения.Интервал со ЗначениеС = 12.10.2017 00:00:00, платформа формирует запрос: «выбрать документы, где дата строго больше 12.10.2017 00:00:00». Все непроведенные документы, записанные ровно на полночь, моментально отсекаются условием. Проведенные же документы, имеющие время больше полуночи, благополучно отображаются в списке. Это создает ложное впечатление, что в списке активен скрытый отбор по реквизиту Проведен.
Для корректного отображения всех документов диапазона необходимо всегда использовать нестрогое сравнение с включением обеих границ. Посмотрим на исправленный и безопасный вариант процедуры:
Процедура УстановитьИнтервал(ДатаНачала, ДатаОкончания)
ЭлементОтбора = СписокРейсов.Отбор.Дата;
// Временно отключаем отбор на время инициализации параметров
ЭлементОтбора.Использование = Ложь;
ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
ЭлементОтбора.ЗначениеС = НачалоДня(ДатаНачала);
ЭлементОтбора.ЗначениеПо = КонецДня(ДатаОкончания);
// Включаем готовый отбор
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
В платформе 1С объект элемента отбора поддерживает метод Установить(). Однако при работе с интервалами важно помнить: стандартная передача одиночного значения переключает вид сравнения в ВидСравнения.Равно. Для задания диапазона через свойства объекта рекомендуется явное присвоение ЗначениеС, ЗначениеПо и ВидСравнения.ИнтервалВключаяГраницы.
Если требуется привязать стандартную панель выбора периода к элементу управления НастройкаПериода, используем следующий подход:
Процедура УстановитьПериодЧерезНастройку(НачПериода, КонПериода)
Настройка = Новый НастройкаПериода;
Настройка.ВариантУстановкиПериода = ВариантУстановкиПериода.ПроизвольныйПериод;
Настройка.ДатаНачала = НачалоДня(НачПериода);
Настройка.ДатаОкончания = КонецДня(КонПериода);
// Применяем границы к отбору списка
ЭлементОтбора = ЭлементыФормы.Список.Значение.Отбор.Дата;
ЭлементОтбора.ВидСравнения = ВидСравнения.ИнтервалВключаяГраницы;
ЭлементОтбора.ЗначениеС = Настройка.ДатаНачала;
ЭлементОтбора.ЗначениеПо = Настройка.ДатаОкончания;
ЭлементОтбора.Использование = Истина;
КонецПроцедуры
Стандартный диалог командной панели «Установить интервал» всегда по умолчанию использует именно ИнтервалВключаяГраницы, поэтому интерактивная настройка никогда не теряет документы на границах суток.