К статье
Практический материал

Разработка и Конфигурация · 11 мин

Запрос 1С с условием по дате: синтаксис и практические примеры

Как задать условие ГДЕ по дате в запросе 1С: операторы сравнения, параметры, функции ДОБАВИТЬКДАТЕ и НАЧАЛОПЕРИОДА, типичные ошибки с пустой датой.

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

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

Ниже разобраны основные приёмы: простое сравнение с датой, выборка за период, работа с пустой датой, функции работы с датой в запросе и типичные ошибки. Все примеры применимы в консоли запросов, в СКД и в коде модулей.

Простое сравнение даты с параметром

Базовый вариант условия — сравнение поля даты с параметром запроса. Операторы сравнения стандартные: равно (=), больше (>), меньше (<), больше или равно (>=), меньше или равно (<=), не равно (<>).

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| РеализацияТоваровУслуг.Ссылка КАК Документ,

| РеализацияТоваровУслуг.Дата КАК Дата

|ИЗ

| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг

|ГДЕ

| РеализацияТоваровУслуг.Дата >= &ДатаОтбора";

Запрос.УстановитьПараметр("ДатаОтбора", Дата(2026, 1, 1));

Параметр передаётся через метод УстановитьПараметр до выполнения запроса. Тип значения параметра должен соответствовать типу поля — для даты передаётся значение типа Дата. Если передать строку вида "01.01.2026", сравнение не сработает корректно: язык запросов не приводит строку к дате автоматически.

Важный нюанс: тип «Дата» в 1С всегда содержит время с точностью до секунды. Условие Дата = &ДатаОтбора с параметром Дата(2026,1,1) найдёт только документы, проведённые ровно в 00:00:00 первого января. Для отбора «за день» нужен диапазон, а не равенство.

Выборка документов за период

Самая частая практическая задача — получить документы за произвольный период: день, месяц, произвольный интервал. Условие строится из двух границ через логическое И.

"ГДЕ

| Документ.Дата >= &НачалоПериода

| И Документ.Дата <= &КонецПериода"

Нижняя граница обычно передаётся как начало дня — НачалоДня(Период) в коде перед установкой параметра. С верхней границей есть тонкость: если передать КонецДня(Период), получится значение 23:59:59, и документы, проведённые в последнюю секунду дня, в выборку попадут. Однако надёжнее использовать встроенную функцию запроса КОНЕЦПЕРИОДА:

"ГДЕ

| Документ.Дата МЕЖДУ &НачалоПериода И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)"

Оператор МЕЖДУ ... И ... включает обе границы и делает текст короче. Функция КОНЕЦПЕРИОДА принимает дату и тип периода (СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД) и возвращает конец соответствующего интервала. Симметричная функция НАЧАЛОПЕРИОДА округляет дату вниз до начала периода.

Порядок действий для отбора за период
  1. 1
    Определите границы периода в коде: начало через НачалоДня() или НачалоМесяца()
  2. 2
    В тексте запроса напишите условие ГДЕ Дата МЕЖДУ &НачалоПериода И КОНЕЦПЕРИОДА(&КонецПериода, ДЕНЬ)
  3. 3
    Передайте оба параметра через УстановитьПараметр до вызова Выполнить()
  4. 4
    Выполните запрос в консоли и сверьте количество строк с ожидаемым по журналу документов

Отбор за текущий день, месяц, год

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

"ГДЕ

| Документ.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, МЕСЯЦ)

| И КОНЕЦПЕРИОДА(&Дата, МЕСЯЦ)"

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

Условия по дате в виртуальных таблицах регистров

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

"ВЫБРАТЬ

| Остатки.Номенклатура,

| Остатки.КоличествоОстаток

|ИЗ

| РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, Склад = &Склад) КАК Остатки"

Для таблицы оборотов период задаётся двумя параметрами:

"ИЗ

| РегистрНакопления.Продажи.Обороты(&НачалоПериода, &КонецПериода, , ) КАК Обороты"

Признак типичной ошибки — условие по полю Период в секции ГДЕ при обращении к виртуальной таблице остатков. Такой запрос работает медленно и может возвращать некорректные данные, потому что виртуальная таблица уже рассчитана на другую границу.

Работа с пустой датой и составными типами

Пустая дата в 1С — это значение 01.01.0001 00:00:00, а не NULL. В запросе её можно задать литералом ДАТАВРЕМЯ(1, 1, 1). Типичная задача — найти документы, где реквизит даты не заполнен:

"ГДЕ

| Документ.ДатаОплаты = ДАТАВРЕМЯ(1, 1, 1)"

Литерал ДАТАВРЕМЯ(год, месяц, день, часы, минуты, секунды) позволяет задать конкретную дату прямо в тексте запроса без параметра. Это удобно в консоли запросов при отладке: ДАТАВРЕМЯ(2026, 3, 15) эквивалентно 15.03.2026 00:00:00.

Если поле имеет составной тип и может содержать NULL (например, в результате левого соединения), проверку на пустую дату нужно дополнять проверкой ЕСТЬ NULL, иначе строки с NULL выпадут из обоих условий — и из «равно пустой дате», и из «не равно».

Типичные ошибки
01
Сравнение Дата = &Дата без учёта времени — находятся только документы ровно в 00:00:00
02
Передача строки вместо даты в УстановитьПараметр — сравнение не срабатывает
03
Условие по Периоду в ГДЕ для виртуальной таблицы вместо параметров — падение производительности
04
Проверка только на ДАТАВРЕМЯ(1,1,1) при возможном NULL — часть строк теряется
05
Использование КонецДня() вместо КОНЕЦПЕРИОДА в сложных отчётах СКД, где параметр переопределяется

Функции для вычислений с датами в запросе

Язык запросов позволяет не только сравнивать даты, но и вычислять смещённые границы. Функция ДОБАВИТЬКДАТЕ(Дата, Тип, Количество) сдвигает дату на заданное число секунд, дней, месяцев и т.д. Например, отбор документов за последние 30 дней от переданной даты:

"ГДЕ

| Документ.Дата >= ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -30)"

Функция РАЗНОСТЬДАТ(Дата1, Дата2, Тип) возвращает разницу между датами в указанных единицах. С её помощью можно, например, отобрать заказы, просроченные более чем на неделю:

"ГДЕ

| РАЗНОСТЬДАТ(Заказ.ДатаОтгрузки, &ТекущаяДата, ДЕНЬ) > 7"

Дополнительно доступны функции извлечения частей даты: ГОД(), МЕСЯЦ(), ДЕНЬ(), ЧАС(), МИНУТА(), СЕКУНДА(), ДЕНЬНЕДЕЛИ(). Условие ГДЕ МЕСЯЦ(Документ.Дата) = 3 выберет все мартовские документы за все годы — это удобно для аналитики, но не заменяет отбор по периоду, когда нужен конкретный интервал.

Сравнение способов задать границы периода

Параметры + МЕЖДУ

Универсальный вариант для документов и физических таблиц; границы контролируются из кода

КОНЕЦПЕРИОДА / НАЧАЛОПЕРИОДА в запросе

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

Параметры виртуальной таблицы

Единственно правильный способ для регистров; даёт максимальную производительность

ДОБАВИТЬКДАТЕ

Для скользящих интервалов: последние N дней, дата минус месяц и т.п.

Отбор по дате в СКД и динамических списках

В системе компоновки данных условие по дате обычно выносится в настройки отчёта, а в запросе остаются только параметры виртуальных таблиц. Стандартный подход — объявить параметры &НачалоПериода и &КонецПериода, а пользовательский отбор по дате документа добавлять через закладку «Отбор» схемы компоновки. Тогда СКД сама подставит условие в итоговый запрос.

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

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

Контрольные точки

Как проверить результат

Количество строк в выборке
Норма

Совпадает с числом документов за период в журнале

Тревожный признак

Пусто или меньше ожидаемого — проверьте границы и время

Документы первого и последнего дня
Норма

Присутствуют в выборке полностью

Тревожный признак

Пропадают документы конца дня — замените границу на КОНЕЦПЕРИОДА

Скорость выполнения на большой базе
Норма

Запрос отрабатывает за секунды

Тревожный признак

Долгое выполнение — отбор в ГДЕ вместо параметров виртуальной таблицы

Итог

Что важно запомнить

Дата в 1С содержит время, поэтому отбор «за дату» строится диапазоном, а не равенством. Для физических таблиц используйте МЕЖДУ с КОНЕЦПЕРИОДА, для виртуальных таблиц регистров — параметры самой таблицы. Пустая дата — это ДАТАВРЕМЯ(1,1,1), а не NULL. Проверяйте результат сопоставлением с журналом документов.

Частые вопросы

Почему запрос с условием Дата = &Дата не находит документы, хотя они есть?

Потому что тип «Дата» включает время. Параметр Дата(2026,1,1) — это 01.01.2026 00:00:00, а документы проведены в течение дня. Замените равенство на диапазон: Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И КОНЕЦПЕРИОДА(&Дата, ДЕНЬ).

Как задать дату прямо в тексте запроса без параметра?

Используйте литерал ДАТАВРЕМЯ(год, месяц, день, часы, минуты, секунды). Например, ДАТАВРЕМЯ(2026, 6, 30, 23, 59, 59). Часы, минуты и секунды можно опустить — тогда получится начало дня.

Чем отличается КонецДня() в коде от КОНЕЦПЕРИОДА в запросе?

Результат для дня одинаков — 23:59:59. Разница в удобстве: КОНЕЦПЕРИОДА вычисляет границу внутри запроса для любого типа периода (месяц, квартал, год), что особенно полезно в СКД, где текст запроса изменять нельзя, а параметр один.

Как отобрать записи регистра сведений на конкретную дату?

Используйте виртуальную таблицу СрезПоследних или СрезПервых с параметром периода: РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ). Это даст актуальные значения на указанный момент без ручной фильтрации по дате.

Можно ли сравнивать дату с NULL в запросе?

Сравнение с NULL через = или <> всегда даёт ложь. Используйте конструкцию «Поле ЕСТЬ NULL» или «Поле ЕСТЬ НЕ NULL». Если поле может содержать и NULL, и пустую дату, проверяйте оба условия через ИЛИ.

Как получить документы за прошлый месяц автоматически?

Передайте в параметр текущую дату и используйте ДОБАВИТЬКДАТЕ: НАЧАЛОПЕРИОДА(ДОБАВИТЬКДАТЕ(&ТекущаяДата, МЕСЯЦ, -1), МЕСЯЦ) как нижнюю границу и КОНЕЦПЕРИОДА(ДОБАВИТЬКДАТЕ(&ТекущаяДата, МЕСЯЦ, -1), МЕСЯЦ) как верхнюю.