В процессе разработки отчетов и обработок часто возникает необходимость объединить несколько полей запроса в одну строку. Например, нам может потребоваться вывести полное наименование контрагента вместе с его ИНН или собрать адрес из нескольких составляющих. Несмотря на кажущуюся простоту, задача конкатенации в языке запросов 1С имеет ряд нюансов, связанных с типизацией данных и особенностями работы СУБД.
В этой статье мы подробно разберем, как соединять строки, почему стандартная функция ВЫРАЗИТЬ может выдавать ошибку и какие современные инструменты предоставляет платформа для решения этой задачи.
Начнем с самого простого случая. Если в нашем распоряжении есть поля, которые уже имеют строковый тип (например, Наименование или Артикул), мы можем использовать обычный оператор «+». Проанализируем простейший пример:
ВЫБРАТЬ
Номенклатура.Артикул + " " + Номенклатура.Наименование КАК ПолноеНаименование
ИЗ
Справочник.Номенклатура КАК Номенклатура
В данном случае мы объединяем три элемента: строковое поле артикула, строку-разделитель (пробел) и строковое поле наименования. Результатом будет одна объединенная строка. Важно помнить: в языке запросов 1С строковые литералы всегда заключаются в двойные кавычки.
Частая ошибка начинающих разработчиков — попытка сложить ссылочные поля напрямую или использовать ВЫРАЗИТЬ(Ссылка КАК СТРОКА). Разберем ситуацию: у нас есть документ «Заказ поставщику», и мы хотим вывести в одном поле договор и партнера.
Если мы напишем Заказ.Договор + Заказ.Партнер, система выдаст ошибку «Несовместимые типы», так как ссылки не являются строками. Попытка использовать ВЫРАЗИТЬ(Заказ.Договор КАК СТРОКА(100)) также закончится неудачей, потому что в языке запросов 1С приведение ссылочного типа к строковому через ВЫРАЗИТЬ не поддерживается СУБД. Для детального разбора проблемы несовместимости типов и приведения представлений ссылок подойдёт методика сопоставления строк и представлений ссылок в запросе.
Для решения этой проблемы необходимо обращаться к строковым реквизитам ссылочных объектов. Рассмотрим правильный подход:
ВЫБРАТЬ
ЗаказПоставщику.Договор.Наименование + " (партнер: " + ЗаказПоставщику.Партнер.Наименование + ")" КАК ИнформацияОДоговоре
ИЗ
Документ.ЗаказПоставщику КАК ЗаказПоставщику
Здесь мы извлекаем текстовое представление (реквизит Наименование) из каждой ссылки. Теперь операнды имеют тип Строка, и их сложение проходит успешно.
Один из самых коварных моментов при конкатенации — работа с неопределенными значениями. Если хотя бы одно из полей в цепочке сложения имеет значение NULL, результатом всего выражения также будет NULL. Это особенность работы SQL, на которой базируется язык запросов.
Чтобы избежать «исчезновения» данных в отчете, проанализируем ситуацию и применим функцию ЕСТЬNULL. Разберем пример сборки строки адреса:
ВЫБРАТЬ
ЕСТЬNULL(Адреса.Город, "") + ", " + ЕСТЬNULL(Адреса.Улица, "") + " " + ЕСТЬNULL(Адреса.Дом, "") КАК ПолныйАдрес
ИЗ
РегистрСведений.КонтактнаяИнформация КАК Адреса
Используя ЕСТЬNULL(Поле, ""), мы гарантируем, что вместо отсутствующего значения будет подставлена пустая строка, и конкатенация не прервется.
В 1С существуют строки ограниченной длины (например, Строка(150)) и неограниченной длины. Складывать строки неограниченной длины напрямую в запросе нельзя — это вызовет ошибку на уровне базы данных.
Если вам нужно объединить такие поля, их необходимо сначала «обрезать» до фиксированного размера. Здесь нам на помощь приходит функция ВЫРАЗИТЬ. Посмотрим на пример:
ВЫБРАТЬ
ВЫРАЗИТЬ(Текст1 КАК СТРОКА(1000)) + ВЫРАЗИТЬ(Текст2 КАК СТРОКА(1000)) КАК ОбъединенныйТекст
ИЗ
Справочник.ДлинныеОписания
Указав конкретную длину (например, 1000 символов), мы превращаем строку неограниченной длины в совместимый для сложения тип.
Разберем современное решение, которое появилось в платформе версии 8.3.20. Теперь в языке запросов доступна полноценная функция СТРОКА(). Она позволяет преобразовывать в текст примитивные типы данных: числа, даты и булевы значения.
Ранее для вывода числа вместе с текстом приходилось использовать сложные обходные пути. Теперь мы можем сделать так:
ВЫБРАТЬ
"Заказ №" + СТРОКА(Заказ.Номер) + " от " + СТРОКА(Заказ.Дата) КАК ПредставлениеДокумента
ИЗ
Документ.ЗаказПоставщику КАК Заказ
Важное уточнение: функция СТРОКА() по-прежнему не работает для ссылок напрямую. Попытка написать СТРОКА(Заказ.Ссылка) не вернет наименование документа. Она предназначена только для преобразования простых типов.
Если ваша задача — создать отчет, то часто эффективнее перенести логику объединения строк из самого запроса в настройки СКД. Выясним, почему это выгодно:
Формат(), СокрЛП() и НСтр()..Наименование.Для реализации этого в СКД перейдите на закладку Вычисляемые поля и в колонке Выражение укажите формулу, аналогичную коду на языке 1С:
Представление(Контрагент) + " ИНН: " + Контрагент.ИНН
Подведем итог нашему исследованию. Для успешной конкатенации строк в запросе 1С придерживайтесь следующих правил:
+ только для строковых типов..Наименование, .Код).ЕСТЬNULL, чтобы избежать пустых результатов.ВЫРАЗИТЬ(... КАК СТРОКА(N)) для строк неограниченной длины.СТРОКА() для чисел и дат.Следуя этим рекомендациям, вы сможете создавать гибкие и отказоустойчивые запросы для любых нужд вашего бизнес-приложения. Для отладки и проверки таких конструкций запросов и выражений СКД подойдёт инженерная консоль запросов для 1С.