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

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

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

Как использовать ВЫРАЗИТЬ КАК ДАТА в запросе 1С: синтаксис, приведение строк и чисел к дате, отсечение времени, работа с ДАТАВРЕМЯ, типичные ошибки и проверка результата.

В языке запросов 1С оператор ВЫРАЗИТЬ позволяет привести значение поля к нужному типу данных прямо в тексте запроса. Одна из самых частых задач — выразить значение как дату: например, чтобы отсечь время у реквизита типа «Дата и время», преобразовать строку или число в дату для сравнения, либо сузить составной тип поля до конкретного типа для корректного соединения таблиц.

Конструкция выглядит так: ВЫРАЗИТЬ(Поле КАК ДАТА). При этом важно понимать, что в запросах 1С тип «Дата» всегда содержит и время — фактически это момент времени с точностью до секунды. Поэтому «выразить как дату» чаще всего означает не смену типа хранения, а приведение значения к виду, удобному для сравнения и группировки, или отсечение времени через функцию НАЧАЛОПЕРИОДА.

Ниже разобраны рабочие сценарии: базовый синтаксис, приведение строк и чисел, отсечение времени, использование в условиях и соединениях, а также ограничения и типичные ошибки, из-за которых запрос возвращает NULL или падает с ошибкой.

Базовый синтаксис ВЫРАЗИТЬ КАК ДАТА

Общая форма оператора приведения типа в запросе:

ВЫБРАТЬ

ВЫРАЗИТЬ(РеализацияТоваров.Дата КАК ДАТА) КАК ДатаДокумента

ИЗ

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

Для поля, которое уже имеет тип «Дата», такое приведение формально ничего не меняет — значение остаётся тем же моментом времени. Практический смысл ВЫРАЗИТЬ.. КАК ДАТА появляется в трёх случаях: когда поле имеет составной тип и нужно оставить только даты, когда значение хранится в другом типе (строка, число) и требуется попытка приведения, и когда приведение используется как часть более сложного выражения.

Если значение невозможно привести к дате штатным способом, результатом будет NULL либо пустая дата (01.01.0001 00:00:00), в зависимости от контекста. Это нужно учитывать при построении условий отбора.

Отсечение времени: дата без времени

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

Правильный инструмент для этого — функция НАЧАЛОПЕРИОДА, а не ВЫРАЗИТЬ:

ВЫБРАТЬ

НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) КАК День,

СУММА(Продажи.СуммаОборот) КАК Сумма

ИЗ

РегистрНакопления.Продажи.Обороты КАК Продажи

СГРУППИРОВАТЬ ПО

НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ)

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

Сравнение документов за один день

Типичный отбор «все документы за конкретную дату» корректно пишется через диапазон, а не через равенство:

ГДЕ

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

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

Типичные ошибки
01
Сравнение даты документа с параметром через равенство — время не совпадает, и запрос возвращает пустой результат. Используйте диапазон НАЧАЛОПЕРИОДА–КОНЕЦПЕРИОДА.
02
Ожидание, что ВЫРАЗИТЬ(Строка КАК ДАТА) разберёт произвольный текст вроде «15 марта» — такое приведение не работает, строку нужно предварительно разбирать функциями ПОДСТРОКА и собирать через ДАТАВРЕМЯ.
03
Приведение к ДАТА поля составного типа без отбора — числовые и строковые значения превращаются в NULL или пустую дату и искажают соединения.

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

Когда дата хранится в строковом реквизите (такое встречается в регистрах сведений обмена, при загрузке из внешних источников), прямое ВЫРАЗИТЬ(Строка КАК ДАТА) обычно не даёт результата. Надёжный способ — собрать дату из частей строки функцией ДАТАВРЕМЯ, которая принимает шесть числовых аргументов: год, месяц, день, час, минута, секунда.

Для строки формата «ГГГГММДДччммсс» преобразование выглядит так:

ВЫБРАТЬ

ДАТАВРЕМЯ(

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 1, 4) КАК ЧИСЛО(4)),

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 5, 2) КАК ЧИСЛО(2)),

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 7, 2) КАК ЧИСЛО(2)),

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 9, 2) КАК ЧИСЛО(2)),

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 11, 2) КАК ЧИСЛО(2)),

ВЫРАЗИТЬ(ПОДСТРОКА(Данные.СтрокаДаты, 13, 2) КАК ЧИСЛО(2))

) КАК ДатаИзСтроки

ИЗ

РегистрСведений.ДанныеОбмена КАК Данные

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

Литерал даты прямо в запросе

Если нужна конкретная константная дата, используйте литерал ДАТАВРЕМЯ:

ГДЕ Документ.Дата >= ДАТАВРЕМЯ(2026, 1, 1, 0, 0, 0)

Это быстрее и читабельнее, чем передача параметра, когда дата зашита в текст запроса осознанно. Для параметризуемых отчётов, разумеется, предпочтительнее параметры.

bsl
ВЫБРАТЬ
	НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) КАК День,
	СУММА(Продажи.СуммаОборот) КАК Сумма
ИЗ
	РегистрНакопления.Продажи.Обороты(, , День, ) КАК Продажи
СГРУППИРОВАТЬ ПО
	НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ)
УПОРЯДОЧИТЬ ПО
	День

Приведение составных типов и работа с NULL

Реквизиты составного типа (например, «Дата или строка») и поля, которые могут содержать NULL после левого соединения, требуют аккуратного обращения. Приведение ВЫРАЗИТЬ(Поле КАК ДАТА) для значений других типов вернёт пустую дату, а для NULL — оставит NULL. Это влияет на сравнения: условие Поле = &Дата для NULL-значений не выполнится никогда, потому что любое сравнение с NULL даёт «неизвестно».

Для подстановки значения по умолчанию вместо NULL используйте ЕСТЬNULL:

ВЫБРАТЬ

ЕСТЬNULL(ВЫРАЗИТЬ(Данные.ДатаОплаты КАК ДАТА), ДАТАВРЕМЯ(1, 1, 1)) КАК ДатаОплаты

ИЗ

РегистрСведений.СтатусыОплаты КАК Данные

Такой приём позволяет единообразно обрабатывать «не заполнено»: пустая дата 01.01.0001 легко отфильтровывается и наглядно отображается в отчётах. Альтернатива — конструкция ВЫБОР КОГДА Поле ЕСТЬ NULL ТОГДА.. ИНАЧЕ.. КОНЕЦ, если логика замены сложнее одного значения.

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

Как выбрать действие

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

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

Приведение к дате часто нужно при соединении таблиц, где ключ связывания хранится по-разному: в одной таблице — полноценная дата с временем, в другой — дата начала дня. Соединение по «очищенному» значению выглядит так:

ВЫБРАТЬ

Продажи.Номенклатура КАК Номенклатура,

Продажи.Количество КАК Количество

ИЗ

РегистрНакопления.Продажи КАК Продажи

ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныДня КАК Цены

ПО НАЧАЛОПЕРИОДА(Продажи.Период, ДЕНЬ) = Цены.Дата

И Продажи.Номенклатура = Цены.Номенклатура

Учтите, что выражения в условии соединения не дают СУБД использовать индексы по исходным полям, поэтому на больших таблицах такой запрос может работать заметно медленнее. Если объёмы велики, лучше заранее подготовить временную таблицу с уже вычисленным полем дня и проиндексировать его, либо пересмотреть структуру хранения.

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

Проверка результата и ограничения

После написания запроса проверьте результат в консоли запросов: убедитесь, что тип колонки — «Дата», время отсечено там, где требовалось, а в данных нет неожиданных пустых дат 01.01.0001 и NULL. Наличие большого числа пустых дат — признак того, что исходные значения не привелись и их нужно обрабатывать отдельно.

Основные ограничения, которые стоит держать в голове: ВЫРАЗИТЬ не парсит произвольные текстовые представления дат; ДАТАВРЕМЯ требует корректных числовых аргументов и упадёт с ошибкой на невалидных значениях (например, месяц 13); а приведение к дате не меняет физическое хранение данных — это вычисление на лету при каждом выполнении запроса.

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

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

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

Отображается тип «Дата», значения читаемы

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

Тип «Строка» или «Число» — приведение не применилось

Время в значениях после НАЧАЛОПЕРИОДА(…, ДЕНЬ)
Норма

Все значения имеют время 00:00:00

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

Время сохранилось — функция не применена или применена не к тому полю

Количество пустых дат 01.01.0001 и NULL
Норма

Единичные значения там, где данные реально не заполнены

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

Массовые пустые даты — исходные строки не соответствуют ожидаемому формату

Скорость выполнения на рабочем объёме данных
Норма

Запрос выполняется за приемлемое время

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

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

FAQ

Чем ВЫРАЗИТЬ(Поле КАК ДАТА) отличается от НАЧАЛОПЕРИОДА(Поле, ДЕНЬ)?

ВЫРАЗИТЬ меняет тип значения, но сохраняет время внутри даты. НАЧАЛОПЕРИОДА возвращает дату, сдвинутую к началу указанного периода: для дня это 00:00:00. Для сравнения «по дню» и группировок нужна именно НАЧАЛОПЕРИОДА.

Можно ли преобразовать строку «15.03.2026» в дату прямо в запросе?

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

Почему условие Документ.Дата = &Дата не находит документы?

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

Что вернёт ВЫРАЗИТЬ, если значение нельзя привести к дате?

Для значений несовместимых типов результатом будет пустая дата (01.01.0001 00:00:00), а для NULL останется NULL. Поэтому после приведения стоит проверять результат и при необходимости подставлять значение по умолчанию через ЕСТЬNULL.

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

Через литерал ДАТАВРЕМЯ(год, месяц, день, час, минута, секунда), например ДАТАВРЕМЯ(2026, 1, 1, 0, 0, 0). Все шесть аргументов обязательны, значения должны образовывать корректную дату.

Влияет ли приведение типов на производительность запроса?

Да, если выражения используются в условиях соединения или отбора по большим таблицам: СУБД не сможет применить индексы по исходным полям. На больших объёмах выносите вычисленные значения во временные таблицы с индексацией или передавайте подготовленные параметры.

Итог

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

ВЫРАЗИТЬ(Поле КАК ДАТА) приводит тип, но не отсекает время — для работы по дням применяйте НАЧАЛОПЕРИОДА и КОНЕЦПЕРИОДА. Строки преобразуйте разбором через ПОДСТРОКА и сборкой ДАТАВРЕМЯ, NULL обрабатывайте через ЕСТЬNULL, а сравнение дат всегда выполняйте диапазоном, а не равенством.