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