Объединение строковых значений в одну строку — частая задача при работе с базами данных в 1С:Предприятие. Нужно ли сформировать список товаров через запятую, собрать адрес из отдельных полей или подготовить данные для отчёта — без грамотного объединения строк не обойтись. Однако стандартный язык запросов не всегда предлагает очевидные решения для таких операций, особенно когда речь идёт о группировке данных или работе с иерархическими структурами.

В этой статье разберём 5 основных способов объединения строк в запросах 1С 8.3 и 1С 8.2: от элементарной конкатенации с помощью оператора + до сложных конструкций с использованием СКД (Система Композиции Данных) и виртуальных таблиц. Особое внимание уделим объединению строк с группировкой по полям — задаче, которая часто вызывает затруднения у разработчиков. Все примеры приведены с учётом синтаксиса последних версий платформы, но применимы и к более ранним релизам (с оговорками).

1. Простая конкатенация строк оператором "+"

Самый базовый метод — использование оператора + для склеивания строк непосредственно в тексте запроса. Подходит для случаев, когда нужно объединить фиксированное количество полей или литералов.

Пример: объединение фамилии, имени и отчества сотрудника в одно поле ФИО:

ВЫБРАТЬ

Сотрудники.Фамилия + " " + Сотрудники.Имя + " " + Сотрудники.Отчество КАК ФИО

ИЗ

Справочник.Сотрудники КАК Сотрудники

  • Плюсы: максимальная простота, не требует дополнительных функций.
  • Минусы: не обрабатывает значения NULL (если одно из полей пустое, результат может быть некорректным).
  • ⚠️ Нюанс: для избежания пробелов в начале/конце результата используйте СокрЛП().

Чтобы исключить пробелы при пустых значениях, модифицируем запрос:

ВЫБРАТЬ

СокрЛП(Сотрудники.Фамилия + " " + Сотрудники.Имя + " " + Сотрудники.Отчество) КАК ФИО

ИЗ

Справочник.Сотрудники КАК Сотрудники

💡

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

2. Функции СтрСокрЛП() и СтрЗаменить() для обработки строк

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

  • СтрСокрЛП(Строка) — удаляет пробелы в начале и конце строки, а также заменяет множественные пробелы внутри на одиночные.
  • СтрЗаменить(Строка, Что, НаЧто) — заменяет все вхождения подстроки Что на НаЧто.

Пример использования СтрЗаменить() для форматирования телефонного номера:

ВЫБРАТЬ

СтрЗаменить(

СтрЗаменить(

Контрагенты.Телефон,

" ",

""

),

"-",

""

) КАК ТелефонБезФорматирования

ИЗ

Справочник.Контрагенты КАК Контрагенты

А вот как с помощью СтрСокрЛП() можно "очистить" адрес от лишних пробелов:

ВЫБРАТЬ

СтрСокрЛП(

Контрагенты.ПочтовыйИндекс + " " +

Контрагенты.Город + ", " +

Контрагенты.Улица + ", " +

Контрагенты.Дом

) КАК Адрес

ИЗ

Справочник.Контрагенты КАК Контрагенты

📊 Какой метод объединения строк вы используете чаще?
Оператор "+"
Функции СтрСокрЛП/СтрЗаменить
СКД (Система Композиции Данных)
Виртуальные таблицы
Другой

3. Объединение строк с группировкой (CONCAT в 1С)

Одна из самых востребованных задач — объединение строк с группировкой по какому-либо полю. Например, получить список всех товаров в заказе через запятую или перечень документов по контрагенту. В стандартном языке запросов нет аналога GROUP_CONCAT из SQL, но эту проблему можно решить несколькими способами.

Способ 1: Использование временных таблиц

Алгоритм:

  1. Создать временную таблицу с нужными данными.
  2. Пройти по ней в цикле на встроенном языке, объединяя строки.

Пример кода (в модуле отчёта или обработки):

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| ЗаказыПокупателей.Контрагент КАК Контрагент,

| ЗаказыПокупателей.Номер КАК НомерЗаказа

|ИЗ

| Документ.ЗаказПокупателя КАК ЗаказыПокупателей

|ГДЕ

| ЗаказыПокупателей.Дата >= &ДатаНачала

|УПОРЯДОЧИТЬ ПО

| Контрагент";

Запрос.УстановитьПараметр("ДатаНачала", НачалоДня(ТекущаяДата()));

РезультатЗапроса = Запрос.Выполнить();

// Создаём таблицу значений для группировки

ТаблицаГруппировки = Новый ТаблицаЗначений;

ТаблицаГруппировки.Колонки.Добавить("Контрагент");

ТаблицаГруппировки.Колонки.Добавить("СписокЗаказов");

// Проходим по результату и объединяем номера заказов

ТекущийКонтрагент = "";

СписокЗаказов = "";

Выборка = РезультатЗапроса.Выбрать();

Пока Выборка.Следующий() Цикл

Если ТекущийКонтрагент <> Выборка.Контрагент Тогда

Если ТекущийКонтрагент <> "" Тогда

СтрокаГруппировки = ТаблицаГруппировки.Добавить();

СтрокаГруппировки.Контрагент = ТекущийКонтрагент;

СтрокаГруппировки.СписокЗаказов = Лев(СписокЗаказов, СтрДлина(СписокЗаказов) - 2); // Убираем последнюю запятую

КонецЕсли;

ТекущийКонтрагент = Выборка.Контрагент;

СписокЗаказов = "";

КонецЕсли;

СписокЗаказов = СписокЗаказов + Выборка.НомерЗаказа + ", ";

КонецЦикла;

// Добавляем последнюю группу

Если ТекущийКонтрагент <> "" Тогда

СтрокаГруппировки = ТаблицаГруппировки.Добавить();

СтрокаГруппировки.Контрагент = ТекущийКонтрагент;

СтрокаГруппировки.СписокЗаказов = Лев(СписокЗаказов, СтрДлина(СписокЗаказов) - 2);

КонецЕсли;

Способ 2: Использование СКД (Система Композиции Данных)

СКД позволяет гибко настраивать вывод данных, включая объединение строк. Для этого:

  1. Создайте схему компоновки данных.
  2. В настройках группы укажите параметр Объединение.
  3. Задайте разделитель (например, запятую).

Пример настройки в конструкторе СКД:

&НаСервере

Процедура СформироватьОтчет(Отчет, ПараметрыОтчета)

СхемаКомпозиции = Новый СхемаКомпоновкиДанных;

НастройкиКомпозиции = СхемаКомпозиции.НастройкиПоУмолчанию;

// Настраиваем группировку и объединение

ГруппаКонтрагентов = НастройкиКомпозиции.Группировки.Добавить();

ГруппаКонтрагентов.Поле = Новый ПолеКомпоновкиДанных("Контрагент");

ГруппаКонтрагентов.Объединение = Истина;

ГруппаКонтрагентов.Разделитель = ", ";

// Добавляем поле для объединения

ПолеЗаказы = НастройкиКомпозиции.Поля.Добавить();

ПолеЗаказы.Поле = Новый ПолеКомпоновкиДанных("НомерЗаказа");

ПолеЗаказы.Объединение = Истина;

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;

Макет = КомпоновщикМакета.Выполнить(СхемаКомпозиции, НастройкиКомпозиции);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;

ПроцессорКомпоновки.Инициализировать(Макет);

// Выполняем запрос и передаём данные в обработчик

РезультатЗапроса = ПолучитьДанныеДляОтчета(ПараметрыОтчета);

ПроцессорКомпоновки.ОбработатьРезультат(РезультатЗапроса);

Отчет.Макет = ПроцессорКомпоновки.ПолучитьМакет("Основной");

КонецПроцедуры

Почему СКД может работать медленнее временных таблиц?

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

4. Виртуальные таблицы и объединение данных

В некоторых случаях для объединения строк удобно использовать виртуальные таблицы, особенно если данные нужно агрегировать по нескольким измерениям. Например, виртуальная таблица Документ.ЗаказПокупателя.СписокНоменклатуры позволяет получить все товары по заказу, а затем объединить их названия.

Пример запроса с виртуальной таблицей:

ВЫБРАТЬ

Заказы.Номер КАК НомерЗаказа,

СтрСокрЛП(

ВЫРАЗИТЬ(

МАКСИМУМ(

ВЫБОР

КОГДА Заказы.Номер = Товары.Ссылка.Номер

ТОГДА Товары.Номенклатура.Наименование + ", "

ИНАЧЕ ""

КОНЕЦ

) КАК Строка

) КАК Строка

) КАК СписокТоваров

ИЗ

Документ.ЗаказПокупателя КАК Заказы

ЛЕВОЕ СОЕДИНЕНИЕ Документ.ЗаказПокупателя.СписокНоменклатуры КАК Товары

ПО Заказы.Ссылка = Товары.Ссылка

СГРУППИРОВАТЬ ПО

Заказы.Номер

⚠️ Внимание: Виртуальные таблицы могут значительно увеличивать нагрузку на сервер, особенно при работе с большими документами (например, заказами с тысячами строк номенклатуры). Перед использованием оценивайте объём данных!
Метод объединения Сложность реализации Производительность Когда использовать
Оператор + Низкая Высокая Простая конкатенация без группировки
Функции СтрСокрЛП(), СтрЗаменить() Низкая Высокая Форматирование строк, удаление пробелов
Временные таблицы + цикл Средняя Средняя Группировка с объединением (например, списки заказов по контрагенту)
СКД (Система Композиции Данных) Высокая Низкая Сложные отчёты с визуализацией
Виртуальные таблицы Средняя Низкая Агрегация данных по документам

5. Использование внешних функций и расширений

Если стандартные средства не покрывают ваши нужды (например, требуется сложное форматирование или работа с большими объёмами данных), можно воспользоваться:

  • Внешними компонентами (например, 1Script или OneScript для расширенной обработки строк).
  • 📦 Готовыми расширениями из каталога 1С:Галлерея решений (например, для экспорта данных в Excel с объединёнными ячейками).
  • 🔧 SQL-запросами (если база данных поддерживает GROUP_CONCAT или аналогичные функции).

Пример использования GROUP_CONCAT в PostgreSQL (если работает с этой СУБД):

ВЫБРАТЬ

Контрагенты.Наименование КАК Контрагент,

ВЫРАЗИТЬ(

ВНЕШНИЙ_ЗАПРОС(

"SELECT string_agg(заказы.номер, ', ')

FROM заказы

WHERE заказы.контрагент_id = контрагенты.id"

) КАК Строка

) КАК СписокЗаказов

ИЗ

Справочник.Контрагенты КАК Контрагенты

⚠️ Внимание: Использование внешних компонент и прямых SQL-запросов может нарушить поддержку типовой конфигурации и усложнить обновления. Применяйте такие методы только в крайних случаях и документируйте изменения!

6. Типичные ошибки и как их избежать

При объединении строк в запросах разработчики часто сталкиваются с следующими проблемами:

  • 🔴 Пустые значения (NULL): если одно из полей пустое, оператор + может вернуть неожиданный результат. Всегда проверяйте значения на ЗначениеЗаполнено() или используйте ВЫРАЗИТЬ(... КАК Строка).
  • 🔴 Переполнение строки: в длина строки ограничена ~4 ГБ, но на практике при объединении тысяч значений может возникнуть ошибка. В таких случаях разделяйте данные на части.
  • 🔴 Неправильные разделители: забытые запятые или пробелы в конце строки портят форматирование. Используйте Лев(Строка, СтрДлина(Строка) - 2) для удаления последнего разделителя.
  • 🔴 Производительность: объединение большого количества строк в цикле может тормозить систему. Для критичных операций используйте временные таблицы в SQL.

Пример обработки NULL:

ВЫБРАТЬ

ВЫРАЗИТЬ(Сотрудники.Отчество КАК Строка) КАК ОтчествоБезNULL

ИЗ

Справочник.Сотрудники КАК Сотрудники

Исключены пустые значения (NULL)|Учтена максимальная длина результирующей строки|Правильно обработаны разделители (запятые, пробелы)|Оптимизирован запрос для больших объёмов данных-->

FAQ: Частые вопросы по объединению строк в 1С

Как объединить строки с переносом строки (символом новой строки)?

Используйте функцию Символы.ПС (перенос строки) в качестве разделителя:

СтрЗаменить(СписокСтрок, ", ", Символы.ПС)

Для вывода в отчёт настройте параметр МногострочныйРежим в поле компоновки данных.

Можно ли объединить строки без использования временных таблиц?

Да, для простых случаев подходит оператор + или функции СтрСокрЛП(). Однако для группировки с объединением (аналог GROUP_CONCAT) без временных таблиц или СКД не обойтись.

Почему при объединении строк в СКД пропали некоторые значения?

Проверьте:

  1. Настройки группировки в схеме компоновки (возможно, не все поля включены в объединение).
  2. Фильтры в отчёте — некоторые строки могли быть исключены.
  3. Параметр Объединение для поля — он должен быть установлен в Истина.
Как объединить строки с учётом иерархии (например, номенклатура → характеристики)?

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

ВЫБРАТЬ

Номенклатура.Наименование КАК Номенклатура,

СтрСокрЛП(

ВЫБОР

КОГДА Характеристики.Наименование <> ""

ТОГДА Характеристики.Наименование

ИНАЧЕ ""

КОНЕЦ

) КАК Характеристики

ИЗ

Справочник.Номенклатура КАК Номенклатура

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ХарактеристикиНоменклатуры КАК Характеристики

ПО Номенклатура.Ссылка = Характеристики.Номенклатура

Есть ли ограничения на длину результирующей строки при объединении?

Теоретический предел — около 4 ГБ (максимальный размер строки в ). Однако на практике:

  • При выводе в отчёт СКД может обрезать длинные строки.
  • В временных таблицах ограничение зависит от настроек СУБД.
  • Для SQL Server и PostgreSQL максимальная длина результата GROUP_CONCAT настраивается отдельно.

Если строка превышает 1000 символов, разделяйте её на части или выгружайте в файл.

💡

Для большинства задач по объединению строк в 1С достаточно комбинации оператора +, функций СтрСокрЛП()/СтрЗаменить() и временных таблиц. СКД удобна для отчётов, но проигрывает в производительности при больших объёмах данных.