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

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

Особое внимание уделим объединению строк непосредственно в тексте запроса 1С — это самый сложный и наименее документированный случай, где многие разработчики используют обходные пути вместо штатных механизмов. Вы узнаете, как правильно применять функцию ВЫРАЗИТЬ(), почему иногда лучше использовать СТРОКА(), и как избежать ошибки "Недопустимый тип данных" при работе с полями разных типов.

1. Конкатенация строк в программном коде 1С

Начнем с самого простого и интуитивно понятного способа — объединения строк непосредственно в модуле . Здесь у разработчика есть три основных инструмента:

  • 🔹 Оператор + — классический способ, работающий во всех версиях платформы. Пример: Результат = "Привет, " + ИмяПользователя.
  • 🔹 Функция СтрСокр() — удаляет пробелы по краям и объединяет строки. Полезна, если исходные данные содержат лишние символы: СтрСокр(" Hello" + " World ") вернет "Hello World".
  • 🔹 Метод СокрЛП() — аналог СтрСокр(), но удаляет только левые пробелы. Реже используется для конкатенации, но бывает полезен при обработке данных из внешних источников.

Важно понимать, что оператор + в не всегда эквивалентен аналогичному оператору в других языках программирования. Например, если одно из слагаемых имеет тип Число или Дата, платформа автоматически преобразует его в строку. Это может привести к неожиданным результатам:

Сообщение = "Сегодня " + ТекущаяДата(); // Результат: "Сегодня 20260515120000"

// Правильнее:

Сообщение = "Сегодня " + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy");

⚠️ Внимание: При конкатенации большого количества строк (например, в цикле) оператор + создает промежуточные объекты, что может привести к утечке памяти. В таких случаях лучше использовать СтрокаТаблицыЗначений или Поток для записи.

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

МассивСтрок = Новый Массив;

МассивСтрок.Добавить("Яблоки");

МассивСтрок.Добавить("Груши");

МассивСтрок.Добавить("Бананы");

Результат = СтрСоединить(МассивСтрок, ", "); // "Яблоки, Груши, Бананы"

💡

Если вам нужно объединить строки с переносом (Символы.ПС), используйте СтрСоединить(Массив, Символы.ПС). Это удобно для формирования многострочных сообщений или логов.

2. Объединение строк в запросе 1С: функция ВЫРАЗИТЬ

Самый мощный, но и самый сложный способ сцепки строк — непосредственно в тексте запроса. Здесь нельзя использовать оператор + или функции вроде СтрСокр(), зато есть специальная функция ВЫРАЗИТЬ(), которая преобразует любые данные в строку и позволяет их объединять.

Базовый синтаксис:

ВЫБРАТЬ

ВЫРАЗИТЬ(Контрагент.Наименование КАК СТРОКА(50)) КАК Наименование,

ВЫРАЗИТЬ(Документ.Номер КАК СТРОКА(10)) + " от " +

ВЫРАЗИТЬ(Документ.Дата КАК СТРОКА(10)) КАК НомерИДата

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

Ключевые моменты работы с ВЫРАЗИТЬ():

  • 🔹 Обязательно указывайте длину строки (например, СТРОКА(50)). Если длина будет меньше реального значения, данные обрежутся.
  • 🔹 Для дат и чисел можно использовать форматирование: ВЫРАЗИТЬ(Документ.Дата КАК СТРОКА(10) ФОРМАТ "ДЛФ=DD.MM.YYYY").
  • 🔹 Если одно из полей имеет значение NULL, результат всего выражения станет NULL. Чтобы избежать этого, используйте ЗНАЧЕНИЕ() или ЕСТЬNULL().
⚠️ Внимание: Функция ВЫРАЗИТЬ() в некоторых версиях платформы (особенно до 8.3.10) может работать медленно при обработке больших наборов данных. Если запрос выполняется долго, попробуйте перенести конкатенацию в программный код.

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

ВЫБРАТЬ

ВЫРАЗИТЬ(ЕСТЬNULL(Контрагент.Наименование, "") КАК СТРОКА(100)) +

" (" +

ВЫРАЗИТЬ(ЕСТЬNULL(Контрагент.ИНН, "") КАК СТРОКА(12)) +

")" КАК ПолноеНаименование

ИЗ ...

Указаны явные длины строк (СТРОКА(50))|Обработаны NULL значения через ЕСТЬNULL()|Для дат и чисел задан формат|Проверена производительность на больших данных-->

3. Альтернативный способ: функция СТРОКА() в запросах

Помимо ВЫРАЗИТЬ(), в языке запросов есть менее известная, но иногда более удобная функция — СТРОКА(). Она автоматически преобразует переданные аргументы в строки и объединяет их:

ВЫБРАТЬ

СТРОКА(Контрагент.Наименование, " (ИНН: ", Контрагент.ИНН, ")") КАК ПолноеНаименование

ИЗ ...

Преимущества СТРОКА() перед ВЫРАЗИТЬ():

Критерий ВЫРАЗИТЬ() СТРОКА()
Читаемость кода Низкая (много вложенных функций) Высокая (естественный синтаксис)
Обработка NULL Требует ЕСТЬNULL() Автоматически заменяет на пустую строку
Производительность Зависит от версии платформы Стабильно высокая
Форматирование дат/чисел Поддерживается Не поддерживается (нужно предварительное форматирование)

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

ВЫБРАТЬ

(ВЫБРАТЬ СТРОКА(Документ.Номер, " от ", Документ.Дата)) КАК НомерИДата

ИЗ ...

В таких случаях приходится возвращаться к ВЫРАЗИТЬ() или переносить логику в программный код.

ВЫРАЗИТЬ()|СТРОКА()|Переношу в программный код|Другой вариант-->

4. Объединение строк в СКД (Система Компоновки Данных)

Если вы формируете отчет с помощью Системы Компоновки Данных (СКД), то для сцепки строк можно использовать:

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

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

  1. Откройте схему компоновки данных.
  2. Перейдите на вкладку Вычисляемые поля.
  3. Добавьте новое поле с именем, например, ПолноеНаименование.
  4. В выражении укажите:
    ВЫРАЗИТЬ(Номенклатура.Наименование КАК СТРОКА(100)) + " (" + ВЫРАЗИТЬ(Номенклатура.Артикул КАК СТРОКА(20)) + ")"
  5. Используйте это поле в структуре отчета.

Для сложных случаев, когда нужно объединить данные с условиями (например, добавлять артикул только если он заполнен), лучше использовать программное заполнение. В обработчике ПриКомпоновкеРезультата можно написать:

Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)

Для Каждого Строка Из ДанныеРасшифровки Цикл

Если НЕ ЗначениеЗаполнено(Строка.Артикул) Тогда

Строка.ПолноеНаименование = Строка.Наименование;

Иначе

Строка.ПолноеНаименование = Строка.Наименование + " (" + Строка.Артикул + ")";

КонецЕсли;

КонецЦикла;

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

⚠️ Внимание: В СКД 1С 8.3.18+ появилась возможность использовать СТРОКА() прямо в вычисляемых полях, что упрощает синтаксис. В более ранних версиях этот метод не работает.

5. Конкатенация в динамических списках и формах

При работе с динамическими списками или полями форм объединение строк часто требуется для отображения комплексных данных в одной колонке. Здесь есть два основных подхода:

  • 🔹 Вычисляемые поля — настраиваются в конфигураторе для динамического списка.
  • 🔹 Обработка в модуле — когда логика слишком сложна для вычисляемого поля.

Пример настройки вычисляемого поля в динамическом списке:

  1. Откройте форму со списком (например, список документов).
  2. В дереве элементов формы найдите ДинамическийСписок.
  3. В палитре свойств перейдите на вкладку Вычисляемые поля.
  4. Добавьте новое поле, например, ПолныйНомер.
  5. В выражении укажите:
    Строка(Объект.Номер) + " от " + Формат(Объект.Дата, "ДФ=dd.MM.yyyy")
  6. Добавьте поле в колонки списка.

Если нужно объединить данные из связанных справочников (например, наименование контрагента и его ИНН), используйте точку для обращения к реквизитам:

Строка(Объект.Контрагент.Наименование) + " (" + Строка(Объект.Контрагент.ИНН) + ")"

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

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Текст = "<b>" + Объект.Наименование + "</b> (артикул: " + Объект.Артикул + ")";

ЭлементыФормы.ПолеHTML.УстановитьТекст(Текст);

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

Как объединить строки с переносами в динамическом списке?

Используйте функцию СтрЗаменить() для замены Символы.ПС на <br>, а затем установите свойство колонки ТолькоПросмотр = Истина и HTMLДокумент = Истина. Пример:

СтрЗаменить(Объект.Описание, Символы.ПС, "<br>")

6. Оптимизация производительности при объединении строк

При работе с большими объемами данных (тысячи строк) неоптимальная конкатенация может стать узким местом производительности. Рассмотрим ключевые моменты оптимизации:

  • 🔹 Избегайте конкатенации в циклах — каждый оператор + создает новый строковый объект. Для большого количества итераций используйте СтрокаТаблицыЗначений или Поток.
  • 🔹 Переносите логику в СУБД — если возможно, выполняйте объединение строк прямо в запросе, а не в программном коде.
  • 🔹 Используйте буферизацию — для формирования больших текстов (например, XML или JSON) используйте ЗаписьТекста.

Пример оптимизированного кода для объединения 10 000 строк:

// Плохо (медленно):

Результат = "";

Для Сч = 1 По 10000 Цикл

Результат = Результат + "Строка " + Сч + Символы.ПС;

КонецЦикла;

// Хорошо (быстро):

ЗаписьТекста = Новый ЗаписьТекста;

ЗаписьТекста.Открыть();

Для Сч = 1 По 10000 Цикл

ЗаписьТекста.ЗаписатьСтроку("Строка " + Сч);

КонецЦикла;

Результат = ЗаписьТекста.Закрыть();

Для запросов с большими выборками:

  • 🔹 Отдавайте предпочтение СТРОКА() вместо ВЫРАЗИТЬ(), если не нужно форматирование.
  • 🔹 Избегайте объединения строк в ГРУППИРОВКА ПО — это может привести к полному сканированию таблицы.
  • 🔹 Если возможно, разделите запрос на два: сначала получите данные, затем объедините строки в программном коде.
Метод Время выполнения (10 000 строк) Память
Оператор + в цикле ~1200 мс Высокая (много промежуточных объектов)
СтрокаТаблицыЗначений ~300 мс Средняя
ЗаписьТекста ~150 мс Низкая
ВЫРАЗИТЬ() в запросе ~800 мс (зависит от СУБД) Низкая
💡

Для больших объемов данных всегда тестируйте производительность на реальной базе. Например, ВЫРАЗИТЬ() в PostgreSQL может работать быстрее, чем в MS SQL.

7. Типичные ошибки и их решения

Даже опытные разработчики иногда сталкиваются с неожиданными ошибками при объединении строк. Разберем самые распространенные случаи:

  • 🔴 "Недопустимый тип данных" — возникает, когда пытаетесь объединить строку с NULL, Неопределено или нестроковым типом без явного приведения. Решение: используйте ЕСТЬNULL() или ЗНАЧЕНИЕ().
  • 🔴 "Слишком длинная строка" — в максимальная длина строки ограничена (обычно 2 Гб, но может варьироваться). Решение: разбивайте данные на части или используйте Поток.
  • 🔴 "Потеря данных при обрезке" — если в ВЫРАЗИТЬ(... КАК СТРОКА(10)) реальная длина превышает 10 символов, строка обрежется без предупреждения. Решение: всегда закладывайте запас по длине.

Пример ошибки с NULL и ее исправление:

// Ошибка:

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

"ВЫБРАТЬ

| ВЫРАЗИТЬ(Контрагент.Наименование КАК СТРОКА(100)) + "" ("" + ВЫРАЗИТЬ(Контрагент.ИНН КАК СТРОКА(12)) + "")""

|ИЗ Справочник.Контрагенты КАК Контрагент";

// Если ИНН не заполнен, результат всего выражения станет NULL.

// Правильно:

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

"ВЫБРАТЬ

| ВЫРАЗИТЬ(Контрагент.Наименование КАК СТРОКА(100)) +

| ЕСТЬNULL("" ("" + ВЫРАЗИТЬ(Контрагент.ИНН КАК СТРОКА(12)) + "")"", """")

|ИЗ Справочник.Контрагенты КАК Контрагент";

Еще одна частая проблема — некорректное форматирование дат и чисел. Например:

// Плохо: дата будет в формате "20260515000000"

Строка = "Документ от " + Документ.Дата;

// Хорошо:

Строка = "Документ от " + Формат(Документ.Дата, "ДФ=dd.MM.yyyy");

В запросах для форматирования дат используйте конструкцию ФОРМАТ:

ВЫРАЗИТЬ(Документ.Дата КАК СТРОКА(10) ФОРМАТ "ДЛФ=DD.MM.YYYY")

Потому что по умолчанию выполняет целочисленное деление. Чтобы получить дробный результат, используйте ВЫРАЗИТЬ(1.0/3 КАК СТРОКА(10)) или явно преобразуйте типы.-->

8. Продвинутые техники: регулярные выражения и JSON

Для сложных задач объединения строк в можно использовать:

  • 🔹 Регулярные выражения — для извлечения и объединения частей строк по шаблону. Например, объединить все цифры из текста:
Текст = "Заказ №12345 от 15.05.2026";

Регулярка = Новый РегулярноеВыражение("\d+");

Номера = Регулярка.Найти(Текст, 0);

Результат = "";

Пока Номера.Найден() Цикл

Результат = Результат + Номера.Значение;

Номера = Регулярка.Найти(Текст, Номера.Позиция + 1);

КонецЦикла;

// Результат: "1234515052026"

  • 🔹 Работа с JSON — если нужно объединить данные для передачи во внешнюю систему. В 1С 8.3.13+ есть встроенные методы для работы с JSON:
ОбъектJSON = Новый Структура();

ОбъектJSON.Вставить("Наименование", "Товар 1");

ОбъектJSON.Вставить("Артикул", "ART-001");

ОбъектJSON.Вставить("Цена", 1000);

СтрокаJSON = СериализоватьJSON(ОбъектJSON);

// Результат: {"Наименование":"Товар 1","Артикул":"ART-001","Цена":1000}

  • 🔹 Шаблонизация строк — для динамического формирования текстов (например, писем или сообщений). Можно использовать функцию СтрШаблон():
Шаблон = "Уважаемый %1! Ваш заказ №%2 на сумму %3 руб. принят в обработку.";

Параметры = Новый Массив;

Параметры.Добавить(Клиент.Наименование);

Параметры.Добавить(Документ.Номер);

Параметры.Добавить(Формат(Документ.СуммаДокумента, "ЧДЦ=2; ЧРЗ= "));

Результат = СтрШаблон(Шаблон, Параметры);

⚠️ Внимание: При работе с РегулярноеВыражение в 1С 8.3.10 и ниже могут возникать ошибки с кириллицей. Всегда проверяйте кодировку исходного текста.

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

Как объединить строки с разделителем в запросе 1С?

В запросе можно использовать функцию СТРОКА() с явным указанием разделителя:

ВЫБРАТЬ

СТРОКА(Товар.Наименование, ", ", Товар.Артикул) КАК ПолноеНаименование

ИЗ ...

Если разделитель должен добавляться только при наличии второго значения, используйте ВЫБОР:

ВЫБРАТЬ

Товар.Наименование +

ВЫБОР

КОГДА Товар.Артикул ЕСТЬ NULL ТОГДА ""

ИНАЧЕ ", " + Товар.Артикул

КОНЕЦ КАК ПолноеНаименование

ИЗ ...

Почему при объединении строк в запросе получаю ошибку "Тип не совместим с СТРОКА"?

Эта ошибка возникает, когда вы пытаетесь объединить данные нестроковых типов без явного приведения. Например:

// Ошибка:

ВЫРАЗИТЬ(Документ.Сумма КАК СТРОКА(10)) + " руб." // Сумма может быть NULL

// Решение:

ВЫРАЗИТЬ(ЕСТЬNULL(Документ.Сумма, 0) КАК СТРОКА(10)) + " руб."

Также проверьте, что все поля в выражении имеют совместимые типы. Например, нельзя напрямую объединять строку с булевым значением.

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

Используйте соединения (СОЕДИНЕНИЕ) и функцию СТРОКА() или ВЫРАЗИТЬ():

ВЫБРАТЬ

СТРОКА(

Документ.Номер,

" от ",

ВЫРАЗИТЬ(Документ.Дата КАК СТРОКА(10) ФОРМАТ "ДЛФ=DD.MM.YYYY"),

", контрагент: ",

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

) КАК ПолнаяИнформация

ИЗ

Документ.РеализацияТоваровУслуг КАК Документ

ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагент

ПО Документ.Контрагент = Контрагент.Ссылка

Если нужно объединить данные из подзапросов, используйте временные таблицы или общие табличные выражения (С).

Можно ли в 1С объединить строки с переносом строки?

Да, для этого используйте символ переноса строки Символы.ПС:

// В программном коде:

Текст = "Строка 1" + Символы.ПС + "Строка