Как правильно выполнить конкатенацию строк в СКД?

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

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

Способ 1: Конкатенация непосредственно в тексте запроса

Самый очевидный способ — попытаться объединить строки прямо в языке запросов. Однако здесь начинающих разработчиков часто подстерегает ошибка «Несовместимые типы». Рассмотрим ситуацию: если мы попытаемся сложить два поля, которые являются ссылками (например, справочник «Города» и справочник «Склады»), система выдаст ошибку, так как ссылки складывать нельзя.

Для корректного объединения в запросе нам необходимо обращаться к строковым реквизитам объектов, чаще всего это Наименование или Представление. Разберем пример правильного написания кода в конструкторе запроса:


ВЫБРАТЬ
    ВЫРАЗИТЬ(ЗаказПокупателя.ГородПолучатель.Наименование КАК СТРОКА(300)) + " " + 
    ВЫРАЗИТЬ(ЗаказПокупателя.ОтделениеПолучатель.Наименование КАК СТРОКА(300)) КАК Адрес
ИЗ
    Документ.ЗаказПокупателя КАК ЗаказПокупателя

Важный нюанс: при работе в клиент-серверном варианте (MS SQL Server) использование функции ВЫРАЗИТЬ(... КАК СТРОКА) может привести к неожиданному результату. SQL Server дополняет строку пробелами до указанной длины. Если вы укажете СТРОКА(300), то получите строку из 300 символов, где после названия города будет идти множество пробелов, и только потом — название отделения. Чтобы избежать этого в запросе, старайтесь использовать поля, которые уже имеют строковый тип и не требуют явного приведения через ВЫРАЗИТЬ.

Способ 2: Использование вычисляемых полей СКД

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

Проанализируем выражение, которое можно написать в колонке «Выражение»:

Строка(ГородПолучатель) + " " + Строка(ОтделениеПолучатель)

Почему этот способ лучше? Функция Строка() в контексте вычисляемых полей СКД работает аналогично получению представления объекта. Она автоматически преобразует ссылку, число или дату в понятный пользователю текст. Более того, здесь мы можем использовать стандартные функции языка выражений СКД, такие как СократитьЛП() (или TrimAll()), чтобы гарантированно избавиться от лишних пробелов.

Способ 3: Обработка значений NULL

При конкатенации строк (особенно в запросе) критически важно учитывать наличие пустых значений (NULL). В языке SQL и языке запросов 1С действует правило: если вы складываете строку с NULL, результатом будет NULL. Это означает, что если в заказе не указано отделение, то все поле «Адрес» станет пустым, даже если город заполнен.

Чтобы избежать этой ситуации, мы должны использовать функцию ЕСТЬNULL(). Разберем правильную конструкцию:


ЕСТЬNULL(ЗаказПокупателя.ГородПолучатель.Наименование, "") + " " + 
ЕСТЬNULL(ЗаказПокупателя.ОтделениеПолучатель.Наименование, "")

В вычисляемых полях СКД проблема NULL стоит не так остро, но использование конструкции ВЫБОР позволяет сделать вывод более эстетичным. Например, добавлять разделитель (запятую или пробел) только в том случае, если оба поля заполнены:


Представление(Город) + ВЫБОР КОГДА НомерОтделения <> "" ТОГДА ", " + Строка(НомерОтделения) ИНАЧЕ "" КОНЕЦ

Способ 4: Агрегатная функция «СоединитьСтроки»

Иногда задача стоит иначе: нужно объединить значения не из разных колонок, а из разных строк внутри одной группировки. Например, вывести в одной ячейке через запятую все товары, входящие в заказ. Для этого в СКД существует мощная функция СоединитьСтроки().

Рассмотрим порядок действий для реализации этой задачи:

  1. Переходим на закладку «Ресурсы».
  2. Выбираем поле, значения которого нужно склеить (например, Номенклатура.Наименование).
  3. В колонке «Выражение» пишем: СоединитьСтроки(Номенклатура.Наименование, ", ").
  4. Указываем рассчитывать этот ресурс только для нужных группировок (например, для группировки по «Заказу»).

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

Способ 5: Вызов функций общих модулей

Бывают случаи, когда логика объединения строк слишком сложна для обычного выражения (например, сложное форматирование адреса по ФИАС или склонение ФИО). В СКД мы можем вызвать любую экспортную функцию из общего модуля. Рассмотрим, как это сделать:

  1. Создаем в конфигураторе общий модуль (или используем существующий), устанавливаем флаги «Сервер» и «Вызов сервера».
  2. Пишем функцию:
    
    Функция СформироватьПолныйАдрес(Город, Отделение) Экспорт
        // Сложная логика обработки
        Возврат "г. " + СократитьЛП(Город) + ", отд. №" + СократитьЛП(Отделение);
    КонецФункции
    
  3. В вычисляемом поле СКД вызываем эту функцию: ИмяОбщегоМодуля.СформироватьПолныйАдрес(Город, Отделение).

Способ 6: Альтернатива конкатенации — Группировка полей

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

В настройках отчета (закладка «Выбранные поля») мы можем создать группу полей:

  1. Нажимаем правой кнопкой мыши — «Новая группа выбранных полей».
  2. Перетаскиваем в эту группу Город и НомерОтделения.
  3. В свойствах группы устанавливаем «Расположение» в значение «Вместе» (выведет в одну строку через запятую) или «Вертикально» (выведет одно под другим).

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

Подведение итогов

Мы рассмотрели различные методы объединения строк. Подведем итог, какой метод выбрать:

Помните о функции СократитьЛП() и обработке NULL — это спасет ваш отчет от некорректного отображения данных и лишних пробелов в интерфейсе.

← На главную