Как в запросе 1С вывести дату без времени и объединить ее с номером документа?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов или печатных форм часто возникает задача вывести пользователю данные в удобном читаемом виде. Это важный этап, упрощающий быстрый анализ данных при написании запросов в 1С. Одна из распространенных потребностей — объединить номер документа и его дату в одну строку, например: "№ 001 от 01.01.2023". Однако, если попытаться сделать это "в лоб" внутри запроса 1С, результат часто разочаровывает: дата преобразуется в строку вместе со временем (например, "01.01.2023 00:00:00"), что выглядит неаккуратно.

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

Суть проблемы: почему появляется время?

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


// Пример, который выдаст лишнее время
"" + Документ.Номер + " от " + Документ.Дата

Вернет результат вида: "00001 от 01.01.2023 00:00:00".

Чтобы избавиться от "хвоста" времени, нам необходимо явно управлять преобразованием типов. Рассмотрим доступные инструменты.

Способ 1. Использование функции СТРОКА (Платформа 8.3.20 и выше)

Начиная с версии платформы 8.3.20, в языке запросов появилась функция СТРОКА() (или STRING()). Она позволяет преобразовывать примитивные типы в строку. Это самый лаконичный способ, если вы уверены, что конфигурация будет запускаться на современной платформе.

Чтобы получить только дату, мы можем скомбинировать преобразование в строку и взятие подстроки (первых 10 символов, где хранится дата "ДД.ММ.ГГГГ").

Пример кода для запроса:


ВЫБРАТЬ
    "" + Документ.Номер + " от " + ПОДСТРОКА(СТРОКА(Документ.Дата), 1, 10) КАК НомерДата
ИЗ
    Документ.РеализацияТоваровУслуг КАК Документ

Разберем, что здесь происходит:

  1. СТРОКА(Документ.Дата) — превращает дату в строку. В зависимости от региональных настроек сеанса, это обычно "ДД.ММ.ГГГГ ЧЧ:ММ:СС".
  2. ПОДСТРОКА(..., 1, 10) — отрезает первые 10 символов, оставляя только дату.

Важное предупреждение: Функция СТРОКА зависит от региональных настроек информационной базы и сеанса пользователя. Если на сервере формат даты настроен как "MM/dd/yyyy" или "yyyy-MM-dd", жесткая обрезка первых 10 символов может вернуть некорректный результат.

Способ 2. Использование функции ФОРМАТ (Платформа 8.3.25 и выше)

В самых новых версиях платформы (начиная с 8.3.25) разработчики добавили функцию ФОРМАТ() непосредственно в язык запросов. Это наиболее правильный и безопасный способ, аналогичный одноименной функции встроенного языка. Для тестирования таких функций удобно использовать специальную консоль запросов для управляемых форм. Для этой задачи есть инструментарий разработчика с консолью запросов и СКД.

Пример решения:


ВЫБРАТЬ
    "" + Документ.Номер + " от " + ФОРМАТ(Документ.Дата, "ДФ=dd.MM.yyyy") КАК НомерДата
ИЗ
    Документ.РеализацияТоваровУслуг КАК Документ

Преимущества:

Способ 3. Универсальный метод для старых платформ ("Математический")

Если вам приходится работать с платформами старее 8.3.20, функции СТРОКА и ФОРМАТ в запросе недоступны. В этом случае программисты используют проверенный временем прием, хотя существуют и более современные методы объединения строк. Идея заключается в том, чтобы разобрать дату на части и "вырезать" нужные цифры из заранее подготовленных строк.

Рассмотрим алгоритм:

  1. Берем строку со всеми возможными днями (от 01 до 31).
  2. Вычисляем позицию нужного нам дня с помощью формулы ДЕНЬ(Дата) * 2 - 1.
  3. Аналогично поступаем для месяца и года.
  4. Склеиваем все части через точки.

Код запроса будет выглядеть так:


ВЫБРАТЬ
    "" + Документ.Номер + " от " + 
    ПОДСТРОКА("01020304050607080910111213141516171819202122232425262728293031", ДЕНЬ(Документ.Дата) * 2 - 1, 2) + "." + 
    ПОДСТРОКА("010203040506070809101112", МЕСЯЦ(Документ.Дата) * 2 - 1, 2) + "." + 
    ПОДСТРОКА("20202021202220232024202520262027202820292030", (ГОД(Документ.Дата) - 2020) * 4 + 1, 4) 
    КАК НомерДата
ИЗ
    Документ.РеализацияТоваровУслуг КАК Документ

Способ 4. Методологически верный (Обработка результата, а не запроса)

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

Почему стоит избегать склейки строк в запросе:

  1. Проблемы с сортировкой. Поле НомерДата становится строкой, и хронология может нарушиться.
  2. Сложность кода. Запрос становится трудночитаемым.
  3. Производительность. Лишние вычисления на стороне SQL-сервера.

Решение через СКД (Система Компоновки Данных)

Если вы делаете отчет на СКД, значительно расширить возможности оформления поможет внешний отчет «Пользовательская СКД». В стандартном же варианте действуйте так:

  1. В запросе выбирайте чистые поля: Ссылка, Номер, Дата.
  2. Для поля Дата задайте "Оформление" -> "Формат": ДФ=dd.MM.yyyy.
  3. Или используйте Пользовательское поле: Строка(Номер) + " от " + Формат(Дата, "ДФ=dd.MM.yyyy").

Решение через постобработку выборки

Если вы обрабатываете выборку в коде, форматируйте данные в цикле обхода:


Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    ТекстДляВывода = "" + Выборка.Номер + " от " + Формат(Выборка.Дата, "ДФ=dd.MM.yyyy");
КонецЦикла;

Резюме

Подводя итог, выберем лучший метод для вашей ситуации:

← На главную