Как преобразовать число или дату в строку в запросе 1С?

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

При разработке отчетов и выборок в 1С часто возникает задача получить составное строковое представление периода (например, соединить месяц и год в виде «02.2017» или «2. 2017»). Попытка решить эту задачу непосредственно в тексте запроса с помощью функции ПРЕДСТАВЛЕНИЕ приводит к синтаксической ошибке. Разберем причины такого поведения платформы, проанализируем ограничения языка запросов и рассмотрим правильные варианты решения задачи.

Почему возникает синтаксическая ошибка в запросе?

Выясним причину, по которой конструкция ПРЕДСТАВЛЕНИЕ(...) + ". " + ПРЕДСТАВЛЕНИЕ(...) вызывает ошибку:

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

Вариант 1. Форматирование результата при выводе (рекомендуемый способ)

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

Рассмотрим, как отформатировать дату при обходе выборки результата запроса с помощью метода Формат:


Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
    // Преобразование даты в формат "ММ.гггг" (например, "02.2017")
    ПериодСтрокой = Формат(Выборка.Период, "ДФ=ММ.гггг");
    
    // Преобразование даты в формат "М. гггг" (например, "2. 2017")
    ПериодСПробелом = Формат(Выборка.Период, "ДФ=''М. гггг''");
КонецЦикла;

Если в запросе были выбраны отдельные числа для месяца и года, их можно объединить во встроенном языке оператором сложения строк:

СтроковоеПредставление = Строка(Выборка.Месяц) + ". " + Строка(Выборка.Год);

Вариант 2. Настройка вывода в Системе компоновки данных (СКД)

Если отчет строится на базе СКД, модифицировать текст запроса строковыми преобразованиями также не нужно. Рассмотрим два способа настройки представления полей:

  1. Выражение представления на вкладке «Наборы данных»:

    Для поля Период в колонке Выражение представления укажем:

    Формат(Период, "ДФ=''М. гггг''")

    При таком подходе значение останется датой (что сохраняет корректную сортировку и группировку), но пользователю будет выводиться требуемая строка.

  2. Вычисляемые поля:

    На вкладке Вычисляемые поля можно добавить новое поле и задать в колонке Выражение:

    Строка(Месяц) + ". " + Строка(Год)

Вариант 3. Извлечение символов с помощью функции ПОДСТРОКА в запросе

Если по техническим требованиям строковое поле обязательно должно формироваться непосредственно на уровне SQL-запроса, можно использовать манипуляции со строковыми константами и функцией ПОДСТРОКА.

Посмотрим на пример получения двухзначного номера месяца строкой из даты:


ВЫБРАТЬ
    ПОДСТРОКА("010203040506070809101112", (МЕСЯЦ(Продажи.Период) - 1) * 2 + 1, 2) КАК МесяцСтрокой
ИЗ
    РегистрНакопления.Продажи КАК Продажи

Аналогично для получения цифры от 0 до 9 по числовому значению используется сдвиг позиции по строке "0123456789":

ПОДСТРОКА("0123456789", ЧисловоеПоле + 1, 1)

Вариант 4. Использование временной таблицы соответствий

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

Разберем по шагам реализацию этого механизма:


// 1. Формируем таблицу сопоставления чисел и строк
ТаблицаСоответствий = Новый ТаблицаЗначений;
ТаблицаСоответствий.Колонки.Добавить("ЧислоМесяца", Новый ОписаниеТипов("Число"));
ТаблицаСоответствий.Колонки.Добавить("СтрокаМесяца", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(10)));

Для Номер = 1 По 12 Цикл
    СтрокаТЗ = ТаблицаСоответствий.Добавить();
    СтрокаТЗ.ЧислоМесяца = Номер;
    СтрокаТЗ.СтрокаМесяца = Формат(Номер, "ЧЦ=2; ЧВН=");
КонецЦикла;

// 2. Передаем таблицу в запрос и связываем с основными данными
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    Т.ЧислоМесяца КАК ЧислоМесяца,
    |    Т.СтрокаМесяца КАК СтрокаМесяца
    |ПОМЕСТИТЬ ВТ_Соответствия
    |ИЗ
    |    &ТаблицаСоответствий КАК Т
    |;
    |
    |////////////////////////////////////////////////////////////////////////////////
    |ВЫБРАТЬ
    |    ВТ_Соответствия.СтрокаМесяца КАК МесяцСтрокой,
    |    Продажи.СуммаОборот КАК Сумма
    |ИЗ
    |    РегистрНакопления.Продажи.Обороты КАК Продажи
    |    ЛЕВОЕ СОЕДИНЕНИЕ ВТ_Соответствия КАК ВТ_Соответствия
    |        ПО (МЕСЯЦ(Продажи.Период) = ВТ_Соответствия.ЧислоМесяца)";

Запрос.УстановитьПараметр("ТаблицаСоответствий", ТаблицаСоответствий);
Результат = Запрос.Выполнить();

Итог: Прямая конкатенация представлений в запросе не поддерживается платформой 1С. Оптимальным решением является передача исходных типизированных данных (чисел и дат) на уровень клиентского кода или СКД с последующим форматированием функцией Формат.

← На главную