При разработке отчетов и обработок в среде «1С:Предприятие» одной из распространенных задач является выборка записей регистра сведений за определенный интервал времени. Нередко разработчики сталкиваются с ситуацией, когда регистр содержит измерение типа «Дата», однако условие фильтрации вида ГДЕ Дата МЕЖДУ &ДатаНачала И &ДатаОкончания не возвращает ожидаемые строки за последний день интервала либо вовсе вызывает ошибку компиляции запроса. При этом обходные конструкции вроде усечения даты до начала дня могут неожиданно давать результат, маскируя истинную причину проблемы и порождая скрытые угрозы для производительности системы.
Для правильного построения выборки необходимо детально разобрать механику хранения дат на платформе 1С, синтаксические правила объявления параметров в языке запросов и особенности работы операторов сравнения диапазонов.
Первая потенциальная ошибка кроется в оформлении параметров в тексте запроса. Знак амперсанда (&) служит лексическим маркером, указывающим транслятору запросов платформы на то, что за ним следует имя подставляемого параметра. Согласно стандартам разработки платформы 1С:
&ДатаОкончания).& ДатаОкончания), синтаксический анализатор языка запросов воспринимает амперсанд как некорректный одиночный символ либо генерирует исключение разбора структуры запроса («Синтаксическая ошибка»).Запрос.УстановитьПараметр("ИмяПараметра", Значение) имя указывается в виде строкового литерала уже без амперсанда.Вторая и наиболее частая причина отсутствия записей в выборке связана с тем, как в платформе «1С:Предприятие 8» устроен примитивный тип Дата. В отличие от некоторых классических СУБД, где дата и время могут быть разделены на независимые типы (например, DATE и TIME), в 1С тип Дата всегда представляет собой непрерывный момент времени григорианского календаря с точностью до секунды (содержит год, месяц, день, часы, минуты и секунды).
Когда пользователь выбирает дату в поле ввода на форме или программист инициализирует дату без явного указания времени (например, передает значение '2026-05-10'), временная составляющая автоматически приравнивается к нулевой отметке суток — 00:00:00.
Оператор языка запросов МЕЖДУ (эквивалент BETWEEN) проверяет вхождение значения в закрытый интервал и полностью эквивалентен двум условиям, объединенным логическим «И»:
ПроверяемоеПоле >= &ДатаНачала И ПроверяемоеПоле <= &ДатаОкончания
Если в регистре сведений измерение содержит время создания или фиксации записи (к примеру, 10.05.2026 14:30:15), а в качестве параметра &ДатаОкончания передана дата 10.05.2026 00:00:00, то условие:
'2026-05-10 14:30:15' <= '2026-05-10 00:00:00'
возвращает логическую ложь (Ложь). В результате все записи, созданные в течение завершающего дня периода начиная с первой секунды (00:00:01), автоматически отсекаются условием и не попадают в результат запроса.
Иногда разработчики пытаются обойти проблему сопоставлением приведенных дат, используя выражение:
ГДЕ НАЧАЛОПЕРИОДА(Таблица.Дата, ДЕНЬ) = &День
Такое условие действительно начинает находить записи, поскольку функция НАЧАЛОПЕРИОДА отсекает временную часть у поля таблицы, превращая 10.05.2026 14:30:15 в 10.05.2026 00:00:00, что совпадает со значением переданного параметра. Однако данный прием категорически не рекомендуется использовать в реальных высоконагруженных системах по следующим причинам:
НАЧАЛОПЕРИОДА(Таблица.Дата, ...)) оптимизатор СУБД теряет возможность выполнить быстрый поиск по индексу (Index Seek) и переходит к сканированию всей таблицы или всего диапазона индекса (Table/Index Scan), применяя функцию к каждой строке. Это приводит к резкому падению производительности при росте объема регистра.Если запрос по регистру сведений не находит данные по условию периода, выполните следующую последовательность проверок:
& и именами параметров в блоке ГДЕ.ДФ='dd.MM.yyyy HH:mm:ss'). Убедитесь, присутствуют ли в записях ненулевые значения времени.Запрос.Выполнить(). В окне «Вычисление выражений» (Shift+F9) проверьте точные значения параметров, переданных через Запрос.УстановитьПараметр(). Обратите внимание на значение времени в конечной границе.Существует три надежных способа корректно отобрать данные за интервал дат с учетом времени.
Наиболее распространенным и каноническим подходом в 1С является приведение даты окончания к последней секунде суток непосредственно в программном коде перед передачей в запрос. Для этого применяется функция встроенного языка КонецДня().
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Регистр.СтроковоеИзмерение КАК СтроковоеИзмерение,
| Регистр.Дата КАК Дата,
| Регистр.ЧисловойРесурс КАК ЧисловойРесурс
|ИЗ
| РегистрСведений.НашРегистр КАК Регистр
|ГДЕ
| Регистр.Дата МЕЖДУ &ДатаНачала И &ДатаОкончания";
// Приведение границ: начало дня для старта и 23:59:59 для окончания
Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ДатаНачала));
Запрос.УстановитьПараметр("ДатаОкончания", КонецДня(ДатаОкончания));
РезультатЗапроса = Запрос.Выполнить();
Функция КонецДня('2026-05-10') возвращает дату со временем 10.05.2026 23:59:59. В таком случае условие МЕЖДУ захватывает абсолютно все события и записи, созданные на протяжении десятого мая.
Если значение параметра &ДатаОкончания поступает в неизменном виде (например, из настроек компоновщика данных или внешнего источника) и изменить код модуля невозможно, сдвиг границы можно выполнить средствами самого языка запросов с помощью функции КОНЕЦПЕРИОДА:
ВЫБРАТЬ
Регистр.СтроковоеИзмерение КАК СтроковоеИзмерение,
Регистр.Дата КАК Дата,
Регистр.ЧисловойРесурс КАК ЧисловойРесурс
ИЗ
РегистрСведений.НашРегистр КАК Регистр
ГДЕ
Регистр.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&ДатаНачала, ДЕНЬ)
И КОНЕЦПЕРИОДА(&ДатаОкончания, ДЕНЬ)
Важное отличие: Функция КОНЕЦПЕРИОДА в данном примере применяется к параметру (константе для плана выполнения), а не к полю таблицы базы данных. СУБД вычисляет значение КОНЕЦПЕРИОДА(&ДатаОкончания, ДЕНЬ) ровно один раз перед стартом сканирования, поэтому индекс по полю Дата сохраняет свою работоспособность и поиск выполняется оптимально.
В архитектуре высоконагруженных баз данных и систем с повышенной точностью времени популярна практика использования полуоткрытого интервала [>=, <). В этом случае дата окончания смещается на начало следующих суток, а условие строится через строгое «меньше»:
ВЫБРАТЬ
Регистр.СтроковоеИзмерение КАК СтроковоеИзмерение,
Регистр.Дата КАК Дата,
Регистр.ЧисловойРесурс КАК ЧисловойРесурс
ИЗ
РегистрСведений.НашРегистр КАК Регистр
ГДЕ
Регистр.Дата >= &ДатаНачала
И Регистр.Дата < &ДатаСледующегоДня
В модуле параметр передается как НачалоДня(ДатаОкончания) + 86400 (добавление одних суток в секундах). Данный вариант исключает теоретические коллизии с миллисекундами при прямых запросах к СУБД (например, в Microsoft SQL Server при типе данных datetime отметка 23:59:59.997 может округляться до следующих суток), однако в рамках стандартной функциональности 1С Способ 1 и Способ 2 являются общепринятыми эталонами.
23:59:59 с помощью КонецДня() в коде или КОНЕЦПЕРИОДА(..., ДЕНЬ) в тексте запроса.ГДЕ, если по этим полям построен индекс. Любые преобразования дат выполняйте только над входными параметрами.