При разработке отчетов и обработок часто возникает задача сформировать человекочитаемое представление данных, например, объединить стаж из трех числовых колонок (лет, месяцев, дней) в единую строку вида «13 лет 4 месяца 5 дней». Разработчики нередко пытаются выполнить эту операцию сложением прямо в тексте запроса, используя оператор +, однако сталкиваются с ошибками выполнения. Разберем, почему запрос не может склеить число и строку, и рассмотрим правильные варианты реализации данной задачи.
Проанализируем ограничения языка запросов платформы 1С:Предприятие:
+ в запросе применяется исключительно к операндам строкового типа фиксированной длины. Складывать строку с числом или датой напрямую в запросе запрещено синтаксисом.Строка() или Формат().ВЫРАЗИТЬ: Оператор ВЫРАЗИТЬ(Поле КАК Строка(Длина)) предназначен исключительно для ограничения длины строк неограниченной длины или для приведения ссылочных типов. При попытке применить ВЫРАЗИТЬ к числовому полю платформа выдаст синтаксическую ошибку.Таким образом, сформировать итоговую строку со склейкой чисел и текста непосредственно в тексте запроса невозможно. Рассмотрим работающие способы решения этой задачи.
Самый распространенный и универсальный подход — получить из базы данных исходные числовые поля, а итоговую строку собрать средствами встроенного языка 1С при обработке выборки.
Посмотрим на пример текста запроса, в котором мы выбираем только исходные числовые значения:
ВЫБРАТЬ
СтраховойСтаж.КолвоЛет КАК КолвоЛет,
СтраховойСтаж.РазмерМесяцев КАК РазмерМесяцев,
СтраховойСтаж.РазмерДней КАК РазмерДней
ИЗ
РегистрСведений.СтраховойСтаж КАК СтраховойСтаж
Теперь разберем, как сформировать итоговую строку при обработке результата. Для форматирования строк отлично подходит функция СтрШаблон:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ПредставлениеСтажа = СтрШаблон("%1 лет %2 месяцев %3 дней",
Выборка.КолвоЛет,
Выборка.РазмерМесяцев,
Выборка.РазмерДней);
КонецЦикла;
Если необходимо исключить появление пробелов-разделителей в числах больше 999, используем функцию Формат с параметром ЧГ=0:
СтрокаЛет = Формат(Выборка.КолвоЛет, "ЧГ=0");
СтрокаМесяцев = Формат(Выборка.РазмерМесяцев, "ЧГ=0");
СтрокаДней = Формат(Выборка.РазмерДней, "ЧГ=0");
ПредставлениеСтажа = СтрокаЛет + " лет " + СтрокаМесяцев + " месяцев " + СтрокаДней + " дней";
Если задача решается в рамках отчета, оптимально перенести конкатенацию на уровень Системы компоновки данных. В отличие от языка запросов, язык выражений СКД поддерживает функции преобразования типов и форматирования.
Разберем по шагам настройку вычисляемого поля в схеме компоновки данных:
КолвоЛет, РазмерМесяцев, РазмерДней.ПредставлениеСтажа).
Строка(КолвоЛет) + " лет " + Строка(РазмерМесяцев) + " месяцев " + Строка(РазмерДней) + " дней"
Также можно воспользоваться функцией Формат прямо в выражении СКД:
Формат(КолвоЛет, "ЧГ=0") + " лет " + Формат(РазмерМесяцев, "ЧГ=0") + " месяцев " + Формат(РазмерДней, "ЧГ=0") + " дней"
Кроме того, в выражениях полей СКД можно вызывать экспортные функции общих модулей конфигурации, передавая им числовые параметры для корректного склонения слов (например, 1 год, 2 года, 5 лет).
Если вам все же требуется склеить поля строкового типа непосредственно в запросе, помните о правиле обработки значений NULL. Если хотя бы одно строковое поле в выражении сложения содержит значение NULL, результат всей операции конкатенации будет равен NULL.
Для предотвращения подобных ситуаций всегда оборачивайте строковые поля в функцию ЕСТЬNULL:
ВЫБРАТЬ
ЕСТЬNULL(Таблица.Префикс, "") + " " + ЕСТЬNULL(Таблица.Номер, "") КАК ПолныйНомер
ИЗ
Документ.РеализацияТоваровУслуг КАК Таблица