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

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

ВЫРАЗИТЬ КАК ДАТА в запросе 1С: синтаксис, примеры и ошибки

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

Функция ВЫРАЗИТЬ в языке запросов 1С приводит значение поля к заданному типу. Когда речь идёт о дате, она решает две практические задачи: уточняет составной тип, чтобы запрос работал быстрее и корректно соединялся, и преобразует строковое представление даты в настоящий тип Дата, с которым можно сравнивать, группировать и вычислять разности.

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

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

Синтаксис ВЫРАЗИТЬ КАК ДАТА и базовый пример

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

ВЫБРАТЬ

ВЫРАЗИТЬ(Документы.ПериодСтрокой КАК ДАТА) КАК ДатаДокумента

ИЗ

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

ГДЕ

ВЫРАЗИТЬ(Документы.ПериодСтрокой КАК ДАТА) >= &НачалоПериода

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

Обратите внимание: если поле уже имеет тип Дата, применение ВЫРАЗИТЬ к нему не даст никакого эффекта, но и не навредит. Лишние приведения типов в больших запросах лучше убирать — они затрудняют чтение и иногда мешают оптимизатору.

Уточнение составного типа поля

Составной тип — главный повод использовать ВЫРАЗИТЬ КАК ДАТА. Если реквизит объявлен как «Дата или Строка», то при соединении такой таблицы с другой по этому полю СУБД вынуждена учитывать оба типа, что резко увеличивает стоимость запроса. Приведение к одному типу позволяет использовать индексы и обычные планы выполнения.

ВЫБРАТЬ

ВЫРАЗИТЬ(Регистр.ПериодСоставной КАК ДАТА) КАК Период,

СУММА(Регистр.Сумма) КАК Сумма

ИЗ

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

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

ВЫРАЗИТЬ(Регистр.ПериодСоставной КАК ДАТА)

Тот же приём работает в условиях соединения: ПО ВЫРАЗИТЬ(Таб1.Поле КАК ДАТА) = Таб2.Дата. Без приведения такое соединение по составному полю может вернуть неполный результат или выполняться на порядок медленнее на больших таблицах.

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

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

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

ВЫБРАТЬ

ВЫРАЗИТЬ(Данные.ДатаСтрокой КАК ДАТА) КАК ДатаЗначения

ИЗ

РегистрСведений.ЗагруженныеДанные КАК Данные

ГДЕ

ВЫРАЗИТЬ(Данные.ДатаСтрокой КАК ДАТА) <> ДАТАВРЕМЯ(1, 1, 1)

Условие <> ДАТАВРЕМЯ(1, 1, 1) отсекает строки, которые не удалось преобразовать. Это простой и надёжный способ отделить корректные данные от «мусора» при загрузках из внешних источников.

Если строка имеет формат «ДД.ММ.ГГГГ» и ВЫРАЗИТЬ её не распознаёт, придётся собирать дату из частей через ПОДСТРОКА и ДАТАВРЕМЯ. Это громоздко, поэтому правильное решение на уровне архитектуры — хранить даты в реквизитах типа Дата, а не Строка, и преобразовывать данные один раз при загрузке средствами встроенного языка.

Типичные ошибки
01
Ожидать ошибку выполнения при некорректной строке — запрос отработает молча и вернёт пустую дату, исказив отбор
02
Пытаться указать точность: ВЫРАЗИТЬ(Поле КАК ДАТА(10)) — это синтаксическая ошибка, у типа ДАТА нет параметров
03
Сравнивать строковое поле с параметром типа Дата без приведения — сравнение строки и даты не сработает как ожидается
04
Приводить к дате поле, которое уже имеет тип Дата, в каждом соединении — лишний код без выигрыша

ВЫРАЗИТЬ и ДАТАВРЕМЯ: когда что использовать

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

Для параметров запроса передавать значение типа Дата из кода предпочтительнее, чем собирать литерал ДАТАВРЕМЯ в тексте. Параметры безопаснее (исключают проблемы с форматами) и позволяют СУБД кэшировать план запроса. Литералы ДАТАВРЕМЯ уместны для фиксированных границ вроде пустой даты или технологических констант.

Сравнение подходов

ВЫРАЗИТЬ(Поле КАК ДАТА)

Приведение существующего значения: уточнение составного типа, преобразование строки. Не создаёт дату из чисел

ДАТАВРЕМЯ(2026,1,15)

Литерал конкретной даты для сравнений и границ. Не применим к полям таблиц

Параметр типа Дата

Передача даты из кода через Запрос.УстановитьПараметр. Оптимален для отборов по периоду

НАЧАЛОПЕРИОДА(Поле, ДЕНЬ)

Усечение даты-времени до начала периода. Используется вместе с ВЫРАЗИТЬ, а не вместо него

Работа с датой-временем и отсечение времени

Тип Дата в 1С включает время, и это источник классической ошибки: отбор Дата = &Дата не найдёт документы, если у параметра время 00:00:00, а у документов — фактическое время проведения. ВЫРАЗИТЬ эту проблему не решает, так как не усекает значение.

Правильный шаблон отбора за день выглядит так:

ГДЕ

Документ.Дата >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ)

И Документ.Дата <= КОНЕЦПЕРИОДА(&Дата, ДЕНЬ)

Альтернатива — полуинтервал >= НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ) И < ДОБАВИТЬКДАТЕ(НАЧАЛОПЕРИОДА(&Дата, ДЕНЬ), ДЕНЬ, 1). Оба варианта корректны; полуинтервал предпочтителен там, где важна точность до секунды и исключение пограничных совпадений.

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

Порядок действий при преобразовании строки в дату
  1. 1
    Определите фактический формат строки в данных: выведите несколько значений в консоли запросов
  2. 2
    Примените ВЫРАЗИТЬ(Поле КАК ДАТА) и добавьте в выборку исходное поле рядом для сравнения
  3. 3
    Найдите строки, где результат равен ДАТАВРЕМЯ(1,1,1), — это непреобразованные значения
  4. 4
    Если нераспознанных строк много, корректируйте данные при загрузке, а не в каждом запросе
  5. 5
    Только после очистки данных используйте поле в отборах и соединениях

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

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

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

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

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

Значения после приведения
Норма

Реальные даты, соответствующие исходным строкам

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

Массовые значения 01.01.0001 — строки не распознаны

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

Совпадает с ожидаемым объёмом после отбора

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

Резкое сокращение — условие отсекает валидные данные

Соединение по приведённому полю
Норма

Все ожидаемые пары найдены

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

Потери строк — типы в соединении всё ещё различаются

Время выполнения запроса
Норма

Сопоставимо с запросом по однотипному полю

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

Замедление в разы — приведение выполняется над всей таблицей без индекса

Ограничения и альтернативные решения

ВЫРАЗИТЬ КАК ДАТА не работает с NULL: если поле содержит NULL (например, после левого соединения), результат тоже будет NULL, а не пустая дата. Для замены NULL используйте ЕСТЬNULL: ЕСТЬNULL(ВЫРАЗИТЬ(Поле КАК ДАТА), ДАТАВРЕМЯ(1,1,1)).

В иерархических и разрезных сценариях помните, что в СКД приведение типов часто удобнее делать на уровне вычисляемых полей или ресурсов, а не в тексте запроса. А если единственная цель — получить дату без времени в отчёте, проще использовать периодичность регистра или функции периодов СКД, чем приведение типов.

Наконец, если составной тип в метаданных больше не нужен бизнес-логике, рассмотрите сужение типа реквизита в конфигураторе. Это устраняет проблему в корне: все запросы, отчёты и движения начинают работать с однотипным полем без ВЫРАЗИТЬ. Перед изменением типа обязательно проверьте существующие данные — значения несовместимых типов будут очищены при реструктуризации.

Итог

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

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

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

Почему ВЫРАЗИТЬ КАК ДАТА возвращает 01.01.0001?

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

Можно ли указать формат даты в функции ВЫРАЗИТЬ?

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

Как убрать время из даты в запросе?

Функцией НАЧАЛОПЕРИОДА: НАЧАЛОПЕРИОДА(Документ.Дата, ДЕНЬ) вернёт дату с нулевым временем. ВЫРАЗИТЬ для этого не подходит — она меняет тип, а не усекает значение.

Чем отличается ВЫРАЗИТЬ КАК ДАТА от приведения в коде?

В запросе приведение выполняется на стороне СУБД над каждой строкой выборки. В коде функция работает с одним значением. Для одиночных значений и параметров используйте код, для массовой обработки полей таблиц — запрос.

Работает ли ВЫРАЗИТЬ КАК ДАТА с NULL?

Нет, NULL остаётся NULL. Чтобы заменить его пустой датой, оберните выражение в ЕСТЬNULL: ЕСТЬNULL(ВЫРАЗИТЬ(Поле КАК ДАТА), ДАТАВРЕМЯ(1,1,1)).

Влияет ли ВЫРАЗИТЬ на скорость запроса?

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