Разработка и Конфигурация · 10 мин
Как в запросе 1С прописать дату
Как прописать дату в запросе 1С: литерал ДАТАВРЕМЯ, параметры, НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, сравнение дат, типичные ошибки и примеры кода.
Дата — один из самых часто используемых типов в запросах 1С: по ней фильтруют документы, строят отчёты за период, отбирают актуальные записи регистров сведений. При этом у начинающих разработчиков именно работа с датами вызывает больше всего ошибок: запрос «не видит» документы за нужный день, сравнение дат даёт неожиданный результат, а границы периода захватывают лишние записи.
Причина почти всегда одна — непонимание того, как платформа хранит и сравнивает даты. В 1С дата всегда содержит время с точностью до секунды, поэтому «31.12.2026» и «31.12.2026 23:59:59» — разные значения, и документ, проведённый в 14:30, не попадёт в условие «Дата = 31.12.2026 00:00:00».
Ниже разобраны все основные способы задать дату в тексте запроса: жёстко прописанный литерал, параметр, функции работы с периодами, а также типичные ошибки и способы проверить результат до того, как запрос уйдёт в рабочую базу.
Литерал ДАТАВРЕМЯ: дата прямо в тексте запроса
Самый простой способ указать дату — встроить её в текст запроса с помощью литерала ДАТАВРЕМЯ. Формат: год, месяц, день, а затем необязательные часы, минуты и секунды. Если время не указано, оно равно 00:00:00.
ВЫБРАТЬ
Продажи.Номенклатура,
Продажи.СуммаОборот
ИЗ
РегистрНакопления.Продажи.Обороты(
ДАТАВРЕМЯ(2026, 1, 1),
ДАТАВРЕМЯ(2026, 12, 31, 23, 59, 59)) КАК Продажи
Литерал уместен, когда дата действительно постоянна: например, в запросе, который навсегда привязан к дате перехода на новый учёт, или в отладочном коде. Во всех остальных случаях жёстко зашитая дата — источник проблем: отчёт за «текущий месяц» придётся переписывать каждый месяц, а консольный запрос из инструкции перестанет работать через год.
Параметры запроса: правильный способ передать дату
Штатный механизм — параметры, обозначаемые символом &. В тексте запроса пишется &НачалоПериода, а значение присваивается перед выполнением через метод УстановитьПараметр.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Реализация.Ссылка,
| Реализация.Дата
|ИЗ
| Документ.РеализацияТоваровУслуг КАК Реализация
|ГДЕ
| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода";
Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ТекущаяДатаСеанса()));
Запрос.УстановитьПараметр("КонецПериода", КонецДня(ТекущаяДатаСеанса()));
Результат = Запрос.Выполнить();
Обратите внимание на функции встроенного языка НачалоДня() и КонецДня() — они выполняются вне запроса и возвращают границы суток. Именно так корректно задавать интервал «за один день»: с 00:00:00 по 23:59:59. Если передать просто ТекущаяДатаСеанса() в оба параметра, условие МЕЖДУ превратится в сравнение с одной секундой, и запрос почти наверняка вернёт пустой результат.
Функции НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА
Язык запросов имеет собственные функции округления дат: НАЧАЛОПЕРИОДА(Дата, Период) и КОНЕЦПЕРИОДА(Дата, Период). В качестве периода указывается ключевое слово: СЕКУНДА, МИНУТА, ЧАС, ДЕНЬ, НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД, ДЕКАДА, ПОЛУГОДИЕ.
ВЫБРАТЬ
НАЧАЛОПЕРИОДА(Поступление.Дата, МЕСЯЦ) КАК Месяц,
СУММА(Поступление.Сумма) КАК Сумма
ИЗ
Документ.ПоступлениеТоваровУслуг КАК Поступление
ГДЕ
Поступление.Дата >= НАЧАЛОПЕРИОДА(&ТекущаяДата, КВАРТАЛ)
СГРУППИРОВАТЬ ПО
НАЧАЛОПЕРИОДА(Поступление.Дата, МЕСЯЦ)
Эти функции незаменимы в двух случаях. Первый — группировка по периодам в отчётах: вместо выгрузки дат и обработки в коде вы группируете прямо в запросе. Второй — нормализация даты для сравнения: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&НужнаяДата, ДЕНЬ) сравнивает документы по дню, игнорируя время.
Учтите, что применение функции к полю в условии отбора мешает оптимизатору использовать индекс по этому полю. На больших таблицах документов сравнение НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) = &Дата может выполняться заметно дольше, чем диапазон Дата МЕЖДУ &Начало И &Конец с заранее вычисленными границами.
Сравнение вариантов
Подходит для отладки и постоянных дат; не подходит для отчётов с изменяемым периодом.
Универсальный способ; требует вычислить границы (НачалоДня/КонецДня) в коде до выполнения.
Удобно для группировок и сравнения по дню; может замедлить запрос на больших таблицах из-за потери индекса.
Сравнение дат и типичные ловушки со временем
Главная ловушка — равенство дат. Поскольку дата хранит время, условие Документ.Дата = &Дата сработает, только если секунды совпадут до единицы. Почти всегда вместо равенства нужен диапазон: МЕЖДУ &НачалоДня И &КонецДня или пара условий >= &Начало И < &СледующийДень.
Вторая ловушка — виртуальные таблицы регистров. У таблицы «Остатки» параметр — это момент, на который считаются остатки; у «Оборотов» — начало и конец периода. Если в оборотах указать конец периода как КонецДня(Дата), всё корректно, но для остатков часто нужен момент «после» конца дня, иначе документы последней секунды могут учитываться не так, как ожидает пользователь. Проверяйте поведение на граничных документах.
Третья ловушка — пустая дата. В 1С пустая дата равна ДАТАВРЕМЯ(1, 1, 1, 0, 0, 0). Если реквизит не заполнен, сравнение Дата >= &Начало не отберёт такую запись, а Дата = &ПустаяДата отберёт только при передаче именно значения 01.01.0001. Для явной проверки используйте условие Дата = ДАТАВРЕМЯ(1, 1, 1) или Дата ЕСТЬ NULL для необязательных соединений.
Дата в консоли запросов и в СКД
В консоли запросов (типовой или из инструментов разработчика) параметры даты задаются в отдельной таблице параметров: тип «Дата», флажок времени при необходимости. Это удобный способ отладить условие до переноса в код: сначала добейтесь правильного результата в консоли, затем переносите текст в модуль.
В системе компоновки данных параметры периода обычно оформляются как &НачалоПериода и &КонецПериода с типом «Дата» и составом «Дата и время» — иначе пользователь не сможет указать время, и конец периода снова упрётся в 00:00:00. Для стандартных периодов в СКД есть служебные параметры &СтандартныйПериод и выражения вида &СтандартныйПериод.ДатаНачала, которые упрощают настройку отчётов.
- 1Откройте консоль запросов и задайте параметры периода вручную с явным временем.
- 2Проверьте граничные документы: первый документ первого дня и последний документ последнего дня должны попасть в выборку.
- 3Сравните количество записей с отбором в списке документов за тот же период.
- 4Перенесите текст в код, заменив литералы на параметры и добавив УстановитьПараметр для каждого.
- 5Выполните запрос в отладчике и проверьте значения параметров перед Выполнить().
Проверка результата и границы самостоятельной работы
Надёжный способ убедиться, что даты заданы правильно, — контрольный документ на границе периода. Создайте (в копии базы) документ, проведённый ровно в 00:00:00 первого дня и в 23:59:59 последнего, и проверьте, что оба попадают в выборку. Если граничные документы теряются — проблема в вычислении границ, а не в данных.
Для сложных случаев — срезы последних на дату, остатки на момент времени с учётом документов-границ — используйте момент времени (МоментВремени, границы через Новый Граница) вместо простой даты. Это уже задача, где ошибка влияет на отчётность, поэтому перед изменением рабочих запросов делайте копию базы и сверяйте итоги с прежней версией отчёта.
Как проверить результат
Попадает в выборку
Отсутствует — начало периода задано неверно
Попадает в выборку
Отсутствует — конец периода равен началу дня
Совпадает с отбором в списке документов
Меньше или больше — проверьте условия и NULL-параметры
Что важно запомнить
Дата в 1С всегда содержит время. В запросах используйте литерал ДАТАВРЕМЯ только для постоянных дат, в остальных случаях — параметры с границами НачалоДня/КонецДня. Для сравнения по дню и группировок применяйте НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА, а корректность проверяйте на граничных документах.
Частые вопросы
Как задать текущую дату прямо в тексте запроса?
В языке запросов нет функции «текущая дата». Передайте её параметром: в коде вычислите ТекущаяДатаСеанса() и установите через УстановитьПараметр, а в тексте используйте &ТекущаяДата.
Как сравнить только дату без времени?
Два рабочих способа: диапазон Дата МЕЖДУ &НачалоДня И &КонецДня (границы вычислены в коде) либо условие НАЧАЛОПЕРИОДА(Дата, ДЕНЬ) = НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ). Первый быстрее на больших таблицах, второй нагляднее.
Почему запрос с условием по дате возвращает пустой результат?
Чаще всего параметр не установлен (равен NULL), либо конец периода передан как начало дня, либо даты сравниваются на точное равенство с разным временем. Проверьте значения параметров в отладчике перед Выполнить().
Как написать пустую дату в запросе?
Литералом ДАТАВРЕМЯ(1, 1, 1) — это 01.01.0001 00:00:00, значение пустой даты в 1С. Условие Реквизит.Дата = ДАТАВРЕМЯ(1, 1, 1) отберёт все записи с незаполненной датой.
Чем отличаются ТекущаяДата() и ТекущаяДатаСеанса()?
ТекущаяДата() на клиенте возвращает время компьютера пользователя, ТекущаяДатаСеанса() — время сервера 1С. В клиент-серверном режиме они могут различаться, поэтому в серверном коде и для параметров запросов используйте ТекущаяДатаСеанса().
Как получить остатки на конкретную дату включительно?
Передайте в параметр виртуальной таблицы Остатки конец дня — КонецДня(Дата). Если нужен учёт документа, проведённого ровно в этот момент, используйте границу: Новый Граница(МоментВремени, ВидГраницы.Включая).