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

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

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

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

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

Наиболее надёжный вариант в реальной разработке — параметр запроса. Он не требует изменения текста запроса при смене периода, защищает от ошибок форматирования и позволяет платформе корректно оптимизировать выполнение. Литералы удобны для отладки и жёстко заданных условий, например отсечки данных до момента миграции.

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

Литерал ДАТАВРЕМЯ: когда дата зашита в текст запроса

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

Пример условия с литералом:

ВЫБРАТЬ

РеализацияТоваровУслуг.Ссылка

ИЗ

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

ГДЕ

РеализацияТоваровУслуг.Дата >= ДАТАВРЕМЯ(2026, 1, 1)

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

Параметр запроса: основной рабочий способ

Параметр объявляется в тексте запроса через амперсанд, а значение присваивается методом УстановитьПараметр до вызова Выполнить(). Тип значения определяется автоматически по переданному значению встроенного языка.

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

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

"ВЫБРАТЬ

| ПоступлениеТоваров.Ссылка,

| ПоступлениеТоваров.Дата

|ИЗ

| Документ.ПоступлениеТоваров КАК ПоступлениеТоваров

|ГДЕ

| ПоступлениеТоваров.Дата МЕЖДУ &НачалоПериода И &КонецПериода";

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

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

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

Обратите внимание на функции НачалоДня() и КонецДня() встроенного языка. Если пользователь выбрал на форме дату без времени, в переменной окажется полночь, и условие «МЕЖДУ &Начало И &Конец» захватит только одну секунду конечного дня. КонецДня() возвращает 23:59:59, что закрывает весь день целиком.

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

Типичные ошибки
01
Сравнение Дата = &Дата вместо диапазона: документы со временем больше 00:00:00 не попадают в выборку
02
Передача конца периода без КонецДня(): теряется весь последний день
03
Передача даты строкой: параметр получает тип Строка, сравнение с датой даёт пустой результат или ошибку
04
Преобразование даты в строку ради подстановки в текст запроса: ломается при смене региональных настроек и открывает риск инъекции

Функции периода внутри текста запроса

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

  • НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) — возвращает 00:00:00 указанного дня. Вторым аргументом могут быть НЕДЕЛЯ, МЕСЯЦ, КВАРТАЛ, ГОД.
  • КОНЕЦПЕРИОДА(&Дата, ДЕНЬ) — возвращает 23:59:59 указанного дня.
  • ДОБАВИТЬКДАТЕ(&Дата, МЕСЯЦ, 3) — сдвигает дату на заданное число единиц, допустимы и отрицательные значения.
  • РАЗНОСТЬДАТ(Дата1, Дата2, ДЕНЬ) — вычисляет разницу между датами.
ГДЕ

Реализация.Дата МЕЖДУ НАЧАЛОПЕРИОДА(&Период, МЕСЯЦ)

И КОНЕЦПЕРИОДА(&Период, МЕСЯЦ)

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

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

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

ВЫБРАТЬ

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

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

ИЗ

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

Здесь есть принципиальная особенность: параметр &ДатаОстатков работает как граница «строго раньше». Чтобы получить остатки на конец дня, передайте КонецДня(Дата) + 1 секунда или используйте объект Граница с видом «Включая». Иначе движения последней секунды дня не попадут в расчёт.

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

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

Для периодических регистров сведений СрезПоследних(&Дата, ) вернёт записи, актуальные на указанный момент. Тот же нюанс с включением границы действует и здесь.

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

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

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

Присутствуют документы за конечную дату

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

Документы последнего дня отсутствуют — проверьте КонецДня и границы

Остатки на дату в отчёте и в стандартном отчёте конфигурации
Норма

Значения совпадают

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

Расхождение на движения конца дня — граница передана без ВидГраницы.Включая

Тип параметра
Норма

Параметру присвоено значение типа Дата

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

Передана строка — сравнение не работает или падает с ошибкой

Пустая дата и проверка на незаполненность

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

ГДЕ

Заказ.ДатаОтгрузки = ДАТАВРЕМЯ(1, 1, 1)

Из встроенного языка пустую дату передают значением '00010101' (дата без явного значения) или просто Неопределено — но Неопределено даст NULL-подобное поведение не везде, поэтому надёжнее явная пустая дата. Если параметр может быть не задан, обрабатывайте это ветвлением текста запроса или условием (&Дата = ДАТАВРЕМЯ(1,1,1) ИЛИ Таблица.Дата >= &Дата).

Маршрут решения

Как выбрать способ задания даты

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

Даты в консоли запросов и динамических списках

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

В динамических списках и СКД дату обычно передают через параметры компоновки: стандартный период раскладывается на параметры НачалоПериода и КонецПериода автоматически, если в тексте запроса использованы именно такие имена. Для произвольных имён параметры придётся связывать вручную в настройках схемы компоновки.

Отдельный случай — отбор по периоду в запросе динамического списка с основной таблицей документа. Здесь платформа умеет строить эффективный план, если условие задано простым сравнением с параметром, без функций над полем даты.

При отладке запроса с датами сначала выполните его в консоли запросов с теми же значениями параметров, что передаёт код. Половина проблем «запрос не видит данные» — это несовпадение времени: в коде КонецДня, а в консоли введена полночь.
ПЗ
Практическое замечание

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

Как выбрать документы только за сегодня?

Передайте два параметра: НачалоДня(ТекущаяДатаСеанса()) и КонецДня(ТекущаяДатаСеанса()) и используйте условие МЕЖДУ. Либо в тексте запроса напишите НАЧАЛОПЕРИОДА(&ТекущаяДата, ДЕНЬ) и КОНЕЦПЕРИОДА(&ТекущаяДата, ДЕНЬ). Сравнение на равенство не подойдёт из-за времени в дате документов.

Можно ли передать дату строкой в параметр?

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

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

Чаще всего потому, что функция применена к полю таблицы: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) = &Дата отключает индекс по дате. Перепишите условие как диапазон МЕЖДУ с функциями над параметром — тогда индекс будет использоваться.

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

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

Чем отличается ТекущаяДата() от ТекущаяДатаСеанса() в параметрах запроса?

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

Как задать в запросе относительную дату, например «минус 30 дней»?

Используйте ДОБАВИТЬКДАТЕ(&ТекущаяДата, ДЕНЬ, -30) прямо в тексте запроса или вычислите значение в коде: НачалоДня(ТекущаяДатаСеанса() - 30 * 86400), где 86400 — число секунд в сутках. Первый вариант нагляднее и не зависит от арифметики в коде.

Итог

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

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