Как преобразовать дату в формат «День недели Число» в запросе и СКД 1С?

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

При разработке отчетов в 1С (особенно кросс-таблиц и диаграмм в Системе компоновки данных) часто возникает задача нестандартного отображения дат. Например, вместо классического представления 20.05.2019 00:00:00 требуется вывести лаконичное и понятное пользователю наименование: «Понедельник 20» или «Среда 22».

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

Выясняем причину: почему запрос выдает ошибку?

Разберем типичную ошибку, которую часто совершают начинающие разработчики. Попытка написать в запросе конструкцию вида:


ВЫБОР 
    КОГДА ДЕНЬНЕДЕЛИ(Дата) = 1 ТОГДА "Понедельник " + ПРЕДСТАВЛЕНИЕ(ДЕНЬ(Дата)) 
КОНЕЦ

неизбежно приведет к ошибке выполнения запроса. Проанализируем, почему так происходит:

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

Ниже мы рассмотрим три основных и наиболее эффективных способа решения этой задачи.

Решение 1. Оптимальный вариант для СКД (Формат оформления)

Если ваша задача — вывести данные в отчет СКД (как и было у автора темы), то пытаться преобразовать дату в строку внутри запроса — это грубая методологическая ошибка. Если вы преобразуете дату в строку в запросе, вы потеряете возможность правильной сортировки колонок. Строки будут сортироваться по алфавиту (например, «Вторник 2» окажется выше, чем «Понедельник 10»), что полностью сломает хронологический порядок отчета.

Рассмотрим, как решить задачу правильно по шагам с помощью механизмов самой СКД.

Шаг 1. Приведение даты к началу дня в запросе

Если в вашем регистре или документе даты содержат время (часы, минуты, секунды), то при выводе их в колонки таблицы вы получите «1001 колонку» (по одной колонке на каждую секунду). Чтобы этого избежать, сначала приведем дату к началу дня непосредственно в запросе:


ВЫБРАТЬ
    НАЧАЛОПЕРИОДА(Продажи.Дата, ДЕНЬ) КАК ДатаДень,
    Продажи.Количество КАК Количество
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Теперь все наши даты будут иметь вид ГГГГ-ММ-ДД 00:00:00, что позволит СКД корректно сгруппировать данные по дням.

Шаг 2. Настройка формата в СКД

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

  1. Откройте схему компоновки данных (СКД) на вкладке «Наборы данных».
  2. Найдите ваше поле ДатаДень.
  3. В колонке «Оформление» нажмите на кнопку выбора (три точки).
  4. В появившемся окне параметров оформления найдите свойство «Формат» и нажмите на кнопку его настройки.
  5. В поле «Форматная строка» введите выражение: ДФ='dddd d' (или выберите соответствующий конструктор).

Разберем подробнее, как работают параметры форматной строки для дат:

Таким образом, форматная строка ДФ='dddd d' преобразует дату 20.05.2019 00:00:00 в красивое представление «Понедельник 20». При этом под капотом поле останется полноценной датой, и хронологический порядок сортировки в отчете не нарушится.

Решение 2. Использование выражения представления в СКД

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

Разберем, как это настроить:

  1. Перейдите на вкладку «Наборы данных» схемы СКД.
  2. Найдите поле ДатаДень и обратите внимание на колонку «Выражение представления».
  3. Впишите туда код на встроенном языке 1С:

Формат(ДатаДень, "ДФ='dddd d'")

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

Решение 3. Формирование строки непосредственно в запросе (без СКД)

Проанализируем ситуацию, когда вам действительно необходимо получить готовую строку вида «Понедельник 20» прямо из текста запроса (например, при передаче данных через API, выгрузке во внешние файлы или при работе вне контекста СКД).

Поскольку функции форматирования и прямого преобразования типов в запросах отсутствуют, нам придется использовать громоздкую, но абсолютно рабочую конструкцию ВЫБОР КОГДА. Нам потребуется отдельно вычислить текстовое представление дня недели и отдельно — текстовое представление числа месяца, после чего сложить их.

Посмотрим на пример реализации такого запроса:


ВЫБРАТЬ
    ВЫБОР
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 1 ТОГДА "Понедельник "
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 2 ТОГДА "Вторник "
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 3 ТОГДА "Среда "
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 4 ТОГДА "Четверг "
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 5 ТОГДА "Пятница "
        КОГДА ДЕНЬНЕДЕЛИ(Продажи.Дата) = 6 ТОГДА "Суббота "
        ИНАЧЕ "Воскресенье "
    КОНЕЦ +
    ВЫБОР
        КОГДА ДЕНЬ(Продажи.Дата) = 1 ТОГДА "1"
        КОГДА ДЕНЬ(Продажи.Дата) = 2 ТОГДА "2"
        КОГДА ДЕНЬ(Продажи.Дата) = 3 ТОГДА "3"
        КОГДА ДЕНЬ(Продажи.Дата) = 4 ТОГДА "4"
        КОГДА ДЕНЬ(Продажи.Дата) = 5 ТОГДА "5"
        КОГДА ДЕНЬ(Продажи.Дата) = 6 ТОГДА "6"
        КОГДА ДЕНЬ(Продажи.Дата) = 7 ТОГДА "7"
        КОГДА ДЕНЬ(Продажи.Дата) = 8 ТОГДА "8"
        КОГДА ДЕНЬ(Продажи.Дата) = 9 ТОГДА "9"
        КОГДА ДЕНЬ(Продажи.Дата) = 10 ТОГДА "10"
        КОГДА ДЕНЬ(Продажи.Дата) = 11 ТОГДА "11"
        КОГДА ДЕНЬ(Продажи.Дата) = 12 ТОГДА "12"
        КОГДА ДЕНЬ(Продажи.Дата) = 13 ТОГДА "13"
        КОГДА ДЕНЬ(Продажи.Дата) = 14 ТОГДА "14"
        КОГДА ДЕНЬ(Продажи.Дата) = 15 ТОГДА "15"
        КОГДА ДЕНЬ(Продажи.Дата) = 16 ТОГДА "16"
        КОГДА ДЕНЬ(Продажи.Дата) = 17 ТОГДА "17"
        КОГДА ДЕНЬ(Продажи.Дата) = 18 ТОГДА "18"
        КОГДА ДЕНЬ(Продажи.Дата) = 19 ТОГДА "19"
        КОГДА ДЕНЬ(Продажи.Дата) = 20 ТОГДА "20"
        КОГДА ДЕНЬ(Продажи.Дата) = 21 ТОГДА "21"
        КОГДА ДЕНЬ(Продажи.Дата) = 22 ТОГДА "22"
        КОГДА ДЕНЬ(Продажи.Дата) = 23 ТОГДА "23"
        КОГДА ДЕНЬ(Продажи.Дата) = 24 ТОГДА "24"
        КОГДА ДЕНЬ(Продажи.Дата) = 25 ТОГДА "25"
        КОГДА ДЕНЬ(Продажи.Дата) = 26 ТОГДА "26"
        КОГДА ДЕНЬ(Продажи.Дата) = 27 ТОГДА "27"
        КОГДА ДЕНЬ(Продажи.Дата) = 28 ТОГДА "28"
        КОГДА ДЕНЬ(Продажи.Дата) = 29 ТОГДА "29"
        КОГДА ДЕНЬ(Продажи.Дата) = 30 ТОГДА "30"
        ИНАЧЕ "31"
    КОНЕЦ КАК ДеньНеделиИЧислоСтрокой
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Данный код полностью работоспособен, не вызывает ошибок СУБД и возвращает строковое поле в точном соответствии с вашими требованиями. Однако используйте этот метод осознанно и только тогда, когда решить задачу средствами вывода (СКД или программным обходом выборки) действительно невозможно.

← На главную