При разработке отчетов на базе Системы компоновки данных (СКД) программисты часто сталкиваются с необходимостью объединения нескольких строковых значений в одно поле. Например, нужно собрать полный адрес из города и номера отделения или объединить фамилию, имя и отчество сотрудника. Несмотря на кажущуюся простоту, в 1С существует несколько способов решения этой задачи, каждый из которых имеет свои особенности и ограничения. В этой статье мы подробно разберем все доступные варианты, проанализируем возможные ошибки и выясним, какой метод лучше выбрать в той или иной ситуации.
Самый очевидный способ — попытаться объединить строки прямо в языке запросов. Однако здесь начинающих разработчиков часто подстерегает ошибка «Несовместимые типы». Рассмотрим ситуацию: если мы попытаемся сложить два поля, которые являются ссылками (например, справочник «Города» и справочник «Склады»), система выдаст ошибку, так как ссылки складывать нельзя.
Для корректного объединения в запросе нам необходимо обращаться к строковым реквизитам объектов, чаще всего это Наименование или Представление. Разберем пример правильного написания кода в конструкторе запроса:
ВЫБРАТЬ
ВЫРАЗИТЬ(ЗаказПокупателя.ГородПолучатель.Наименование КАК СТРОКА(300)) + " " +
ВЫРАЗИТЬ(ЗаказПокупателя.ОтделениеПолучатель.Наименование КАК СТРОКА(300)) КАК Адрес
ИЗ
Документ.ЗаказПокупателя КАК ЗаказПокупателя
Важный нюанс: при работе в клиент-серверном варианте (MS SQL Server) использование функции ВЫРАЗИТЬ(... КАК СТРОКА) может привести к неожиданному результату. SQL Server дополняет строку пробелами до указанной длины. Если вы укажете СТРОКА(300), то получите строку из 300 символов, где после названия города будет идти множество пробелов, и только потом — название отделения. Чтобы избежать этого в запросе, старайтесь использовать поля, которые уже имеют строковый тип и не требуют явного приведения через ВЫРАЗИТЬ.
Если объединение строк в запросе вызывает сложности или приводит к проблемам с пробелами, на помощь приходит механизм вычисляемых полей. Это наиболее гибкий и рекомендуемый способ в СКД. Перейдем на закладку «Вычисляемые поля» и добавим новое поле.
Проанализируем выражение, которое можно написать в колонке «Выражение»:
Строка(ГородПолучатель) + " " + Строка(ОтделениеПолучатель)
Почему этот способ лучше? Функция Строка() в контексте вычисляемых полей СКД работает аналогично получению представления объекта. Она автоматически преобразует ссылку, число или дату в понятный пользователю текст. Более того, здесь мы можем использовать стандартные функции языка выражений СКД, такие как СократитьЛП() (или TrimAll()), чтобы гарантированно избавиться от лишних пробелов.
При конкатенации строк (особенно в запросе) критически важно учитывать наличие пустых значений (NULL). В языке SQL и языке запросов 1С действует правило: если вы складываете строку с NULL, результатом будет NULL. Это означает, что если в заказе не указано отделение, то все поле «Адрес» станет пустым, даже если город заполнен.
Чтобы избежать этой ситуации, мы должны использовать функцию ЕСТЬNULL(). Разберем правильную конструкцию:
ЕСТЬNULL(ЗаказПокупателя.ГородПолучатель.Наименование, "") + " " +
ЕСТЬNULL(ЗаказПокупателя.ОтделениеПолучатель.Наименование, "")
В вычисляемых полях СКД проблема NULL стоит не так остро, но использование конструкции ВЫБОР позволяет сделать вывод более эстетичным. Например, добавлять разделитель (запятую или пробел) только в том случае, если оба поля заполнены:
Представление(Город) + ВЫБОР КОГДА НомерОтделения <> "" ТОГДА ", " + Строка(НомерОтделения) ИНАЧЕ "" КОНЕЦ
Иногда задача стоит иначе: нужно объединить значения не из разных колонок, а из разных строк внутри одной группировки. Например, вывести в одной ячейке через запятую все товары, входящие в заказ. Для этого в СКД существует мощная функция СоединитьСтроки().
Рассмотрим порядок действий для реализации этой задачи:
Номенклатура.Наименование).СоединитьСтроки(Номенклатура.Наименование, ", ").Эта функция также поддерживает отбор и сортировку внутри себя, что делает её незаменимым инструментом для формирования сложных текстовых представлений в отчетах. Для практического примера реализации можно использовать руководство по сбору значений колонки из нескольких строк в СКД.
Бывают случаи, когда логика объединения строк слишком сложна для обычного выражения (например, сложное форматирование адреса по ФИАС или склонение ФИО). В СКД мы можем вызвать любую экспортную функцию из общего модуля. Рассмотрим, как это сделать:
Функция СформироватьПолныйАдрес(Город, Отделение) Экспорт
// Сложная логика обработки
Возврат "г. " + СократитьЛП(Город) + ", отд. №" + СократитьЛП(Отделение);
КонецФункции
ИмяОбщегоМодуля.СформироватьПолныйАдрес(Город, Отделение).Проанализируем ситуацию, когда конкатенация строк в одну может быть избыточной. Если ваша цель — просто визуально отобразить два значения в одной колонке (одно под другим или рядом), в СКД предусмотрен стандартный механизм настроек.
В настройках отчета (закладка «Выбранные поля») мы можем создать группу полей:
Город и НомерОтделения.Этот способ часто предпочтительнее, так как он сохраняет типизацию данных и позволяет пользователю легче настраивать оформление каждого поля в отдельности.
Мы рассмотрели различные методы объединения строк. Подведем итог, какой метод выбрать:
Помните о функции СократитьЛП() и обработке NULL — это спасет ваш отчет от некорректного отображения данных и лишних пробелов в интерфейсе.