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

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

Как установить дату в запросе 1С

Как установить дату в запросе 1С: передача через параметр, функция ДАТАВРЕМЯ, текущая дата, границы периода и типовые ошибки. Примеры кода и проверка результата.

Дата — один из самых частых параметров в запросах 1С: отбор документов за период, остатки на конец дня, срез последних на указанный момент. При этом ошибки с датами дают самые коварные последствия: запрос выполняется без сообщений об ошибке, но возвращает неполные или лишние данные, потому что дата сравнивалась с точностью до секунды, а разработчик ожидал сравнение по дню.

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

Ниже разобраны все три способа с примерами кода, работа с границами периода, передача даты из СКД и типичные ошибки, из-за которых запрос «теряет» документы на границе дня.

Способы задать дату в запросе: что выбрать

Параметр запроса — универсальный вариант, когда значение приходит извне: из реквизита формы, из другого запроса, из настроек отчёта. Параметр объявляется в тексте запроса символом «&» и заполняется методом УстановитьПараметр перед выполнением. Тип значения определяется автоматически по переданному значению, поэтому важно передавать именно тип «Дата», а не строку.

Литерал ДАТАВРЕМЯ удобен, когда дата известна заранее и не меняется — например, в запросах для разовой обработки или в условиях виртуальных таблиц при отладке. Формат: ДАТАВРЕМЯ(Год, Месяц, День, Часы, Минуты, Секунды), время можно опустить, тогда оно будет равно 00:00:00.

Функции языка запросов (НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ДОБАВИТЬКДАТЕ, РАЗНОСТЬДАТ) применяют, когда дату нужно вычислить на стороне СУБД: округлить до начала месяца, сдвинуть на квартал, получить конец дня от переданного параметра. Это снимает часть вычислений с кода и делает текст запроса самодостаточным.

Сравнение способов

Параметр запроса

Подходит для значений из формы, кода или СКД. Гибко, но требует контроля типа передаваемого значения.

Литерал ДАТАВРЕМЯ

Подходит для фиксированных дат и отладки. Не подходит для пользовательских отборов — дату придётся править в тексте.

Функции запроса

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

Установка даты через параметр запроса

Основной рабочий сценарий выглядит так: в тексте запроса пишется условие с параметром, затем параметру присваивается значение типа «Дата».

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

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

"ВЫБРАТЬ

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

| Реализация.Дата КАК Дата

|ИЗ

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

|ГДЕ

| Реализация.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачала));

Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаОкончания));

Результат = Запрос.Выполнить().Выгрузить();

Обратите внимание на две детали. Первая: функции НачалоДня() и КонецДня() встроенного языка приводят дату к 00:00:00 и 23:59:59 соответственно — без них документы, проведённые в середине дня на границе периода, могут не попасть в выборку. Вторая: если переменная ДатаНачала не заполнена, в параметр уйдёт пустая дата 01.01.0001, и запрос молча вернёт пустой результат или лишние строки.

Проверять заполненность параметра стоит до выполнения запроса. Простой приём — добавить в условие альтернативу: ГДЕ (&НачалоПериода = ДАТАВРЕМЯ(1,1,1) ИЛИ Реализация.Дата >= &НачалоПериода). Тогда пустой параметр означает «без ограничения снизу», что удобно в универсальных отчётах.

Литерал ДАТАВРЕМЯ прямо в тексте запроса

Когда дата фиксирована, её можно записать конструкцией ДАТАВРЕМЯ без параметров. Это читаемо и не требует кода вокруг запроса:

"ВЫБРАТЬ

| Заказ.Ссылка КАК Заказ

|ИЗ

| Документ.ЗаказПокупателя КАК Заказ

|ГДЕ

| Заказ.Дата >= ДАТАВРЕМЯ(2026, 1, 1)

| И Заказ.Дата < ДАТАВРЕМЯ(2026, 2, 1)"

Здесь использован приём «больше или равно началу и строго меньше следующей границы» вместо МЕЖДУ. Он надёжнее, потому что не зависит от точности до секунд: верхняя граница — первое мгновение следующего периода, и ничего не теряется и не задваивается при стыковке периодов.

Литерал поддерживает сокращённую форму: ДАТАВРЕМЯ(2026, 1, 1) равнозначно полуночи указанного дня. Но помнить об этой полуночи важно: условие Дата = ДАТАВРЕМЯ(2026, 1, 15) найдёт только документы, проведённые ровно в 00:00:00, а таких в реальной базе почти нет.

Типичные ошибки
01
Сравнение Дата = &Дата без приведения к началу дня — в выборку не попадают документы, проведённые после 00:00:00.
02
Использование МЕЖДУ с КонецДня() и последующая стыковка периодов — документ в 23:59:59 теоретически может попасть в оба смежных интервала при неаккуратных границах.
03
Передача в параметр строки "15.01.2026" вместо значения типа Дата — ошибка типов или неверный результат сравнения.
04
Пустая дата в параметре без обработки — отбор фактически отключается или обрезает данные, и это замечают только по расхождению итогов.

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

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

"ГДЕ

| Продажи.Период >= НАЧАЛОПЕРИОДА(&ПроизвольнаяДата, МЕСЯЦ)

| И Продажи.Период <= КОНЕЦПЕРИОДА(&ПроизвольнаяДата, МЕСЯЦ)"

Функция ДОБАВИТЬКДАТЕ(Дата, ТипПериода, Количество) сдвигает дату вперёд или назад: ДОБАВИТЬКДАТЕ(&Дата, ДЕНЬ, -7) вернёт дату неделю назад. Количество может быть отрицательным — это штатное поведение, а не ошибка.

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

Текущая дата и дата сеанса в запросе

Частая задача — отобрать данные «на сегодня». В языке запросов есть функция ТекущаяДатаСеанса() (в версиях платформы, где она поддерживается), которая вычисляется на сервере в момент выполнения. Альтернатива, работающая везде, — передать текущую дату обычным параметром:

Запрос.УстановитьПараметр("Сейчас", ТекущаяДатаСеанса());

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

Для отбора «за сегодня» не забудьте про границы дня: отбор Период >= НАЧАЛОПЕРИОДА(&Сейчас, ДЕНЬ) корректен, а сравнение Период = &Сейчас почти никогда ничего не найдёт, потому что &Сейчас содержит время с точностью до секунды.

Дата в параметрах виртуальных таблиц и границы

Виртуальные таблицы регистров (Остатки, Обороты, СрезПоследних, СрезПервых) принимают период как параметр в скобках после имени таблицы. Здесь дата задаётся тем же параметром запроса, но с важным нюансом для остатков и срезов.

"ВЫБРАТЬ

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

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

|ИЗ

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

Параметр &Период в таблице Остатки включает движения ровно на указанный момент. Если передать КонецДня(Дата), документ в 23:59:59 учтётся, но документ в ту же секунду с бо́льшим значением момента времени — уже пограничный случай. Для строгого контроля используется объект Граница: он объединяет дату и вид границы (Включая/Исключая) либо конкретный момент времени документа.

ГраницаОстатков = Новый Граница(Документ.МоментВремени(), ВидГраницы.Включая);

Запрос.УстановитьПараметр("Период", ГраницаОстатков);

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

Порядок действий для остатков на дату
  1. 1
    Определите, на какой момент нужны остатки: конец дня, произвольное время или момент конкретного документа.
  2. 2
    Для конца дня передайте параметр КонецДня(НужнаяДата); для момента документа — объект Граница с МоментВремени().
  3. 3
    Укажите параметр в скобках виртуальной таблицы: Остатки(&Период, ...).
  4. 4
    Выполните запрос и сверьте итог со стандартным отчётом по остаткам на ту же дату.
  5. 5
    Если итоги расходятся, проверьте границу (включая/исключая) и часовой пояс сеанса.

Дата в запросах СКД и консоли запросов

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

Стандартный период в СКД автоматически приводит дату окончания к концу дня — это отличается от ручного запроса, где про КонецДня() легко забыть. Если вы переносите запрос из СКД в программный код, сохраните это поведение явно.

При отладке в консоли запросов дату параметра удобно проверять до выполнения: выведите значение параметра и его тип. Тип «Строка» вместо «Дата» — верный признак того, что отбор работать не будет. Также проверяйте часовой пояс: в клиент-серверном режиме дата сеанса может отличаться от даты на машине пользователя, и «сегодня» в отчёте окажется вчерашним днём.

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

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

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

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

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

Меньше — вероятно, потеряны документы на границах дня из-за сравнения с временем

Тип параметра в консоли запросов
Норма

Дата

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

Строка или Неопределено — сравнение даст ошибку или пустой результат

Остатки на дату из запроса
Норма

Совпадают со стандартным отчётом по регистру

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

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

Повторный запуск отчёта
Норма

Результат идентичен при неизменных данных

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

Результат «плавает» — где-то используется незафиксированная текущая дата

Единообразие важнее выбора конкретного приёма. Если во всех запросах конфигурации период задаётся парой «>= начала и < начала следующего дня», придерживайтесь этого шаблона везде: смешение МЕЖДУ, КонецДня() и строгих неравенств в одном проекте — главный источник расхождений в отчётах, которые трудно отловить.
ПЗ
Практическое замечание
Итог

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

Дату в запрос передают параметром типа «Дата» или задают литералом ДАТАВРЕМЯ. Для отбора за день приводите границы через НачалоДня/КонецДня или НАЧАЛОПЕРИОДА/КОНЕЦПЕРИОДА, для остатков на момент документа используйте объект Граница. Пустые даты и строки вместо дат — главные причины молчаливо неверных результатов.

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

Как задать пустую дату в запросе 1С?

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

Почему запрос не находит документы за указанный день?

Почти всегда причина во времени: реквизит Дата документа хранит значение с точностью до секунды, а в условии задана полночь. Условие Дата = &Дата найдёт только документы в 00:00:00. Используйте диапазон: Дата >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И Дата <= КОНЕЦПЕРИОДА(&Дата, ДЕНЬ).

Как получить в запросе только дату без времени?

Примените НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) — функция обнулит время, вернув полночь соответствующего дня. Это удобно для группировки документов по дням: ГРУППИРОВАТЬ ПО НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ).

Чем отличается передача даты параметром от ДАТАВРЕМЯ в тексте?

Функционально — ничем, оба дают значение типа «Дата». Параметр позволяет менять значение без правки текста запроса и обязателен для пользовательских отборов. Литерал уместен для фиксированных дат в разовых обработках и при отладке.

Как задать период «с начала месяца по произвольную дату»?

Передайте одну дату параметром и вычислите границы в запросе: Период >= НАЧАЛОПЕРИОДА(&Дата, МЕСЯЦ) И Период <= КОНЕЦПЕРИОДА(&Дата, ДЕНЬ). Второй параметр не понадобится, а риск рассинхрона двух параметров исчезнет.

Работает ли ТекущаяДата() внутри запроса?

Встроенная функция ТекущаяДата() — это функция языка 1С, а не языка запросов, поэтому в тексте запроса она недоступна. Варианты: передать значение параметром (Запрос.УстановитьПараметр("Сейчас", ТекущаяДатаСеанса())) или использовать функцию запроса ТекущаяДатаСеанса() в версиях платформы, где она поддерживается.