Объединение (конкатенация) строк в 1С:Предприятие — задача, с которой сталкивается каждый разработчик при формировании отчетов, обработке данных или интеграции систем. Казалось бы, что может быть проще, чем склеить две строки? Но в 1С для этой операции существует минимум 5 принципиально разных подходов, каждый из которых имеет свои нюансы, ограничения и области применения.
Самый очевидный способ — использование оператора + или функции СтрСокр() в программном коде — работает далеко не всегда. Например, при формировании запроса к базе данных через язык запросов 1С эти методы просто не доступны. А если речь идет о больших объемах данных, то неоптимальный способ конкатенации может замедлить выполнение операции в десятки раз. В этой статье мы разберем все возможные варианты сцепки строк, их синтаксис, производительность и типичные ошибки, которые допускают даже опытные программисты.
Особое внимание уделим объединению строк непосредственно в тексте запроса 1С — это самый сложный и наименее документированный случай, где многие разработчики используют обходные пути вместо штатных механизмов. Вы узнаете, как правильно применять функцию ВЫРАЗИТЬ(), почему иногда лучше использовать СТРОКА(), и как избежать ошибки "Недопустимый тип данных" при работе с полями разных типов.
1. Конкатенация строк в программном коде 1С
Начнем с самого простого и интуитивно понятного способа — объединения строк непосредственно в модуле 1С. Здесь у разработчика есть три основных инструмента:
- 🔹 Оператор
+— классический способ, работающий во всех версиях платформы. Пример:Результат = "Привет, " + ИмяПользователя. - 🔹 Функция
СтрСокр()— удаляет пробелы по краям и объединяет строки. Полезна, если исходные данные содержат лишние символы:СтрСокр(" Hello" + " World ")вернет"Hello World". - 🔹 Метод
СокрЛП()— аналогСтрСокр(), но удаляет только левые пробелы. Реже используется для конкатенации, но бывает полезен при обработке данных из внешних источников.
Важно понимать, что оператор + в 1С не всегда эквивалентен аналогичному оператору в других языках программирования. Например, если одно из слагаемых имеет тип Число или Дата, платформа автоматически преобразует его в строку. Это может привести к неожиданным результатам:
Сообщение = "Сегодня " + ТекущаяДата(); // Результат: "Сегодня 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. Альтернативный способ: функция СТРОКА() в запросах
Помимо ВЫРАЗИТЬ(), в языке запросов 1С есть менее известная, но иногда более удобная функция — СТРОКА(). Она автоматически преобразует переданные аргументы в строки и объединяет их:
ВЫБРАТЬ
СТРОКА(Контрагент.Наименование, " (ИНН: ", Контрагент.ИНН, ")") КАК ПолноеНаименование
ИЗ ...
Преимущества СТРОКА() перед ВЫРАЗИТЬ():
| Критерий | ВЫРАЗИТЬ() |
СТРОКА() |
|---|---|---|
| Читаемость кода | Низкая (много вложенных функций) | Высокая (естественный синтаксис) |
| Обработка NULL | Требует ЕСТЬNULL() |
Автоматически заменяет на пустую строку |
| Производительность | Зависит от версии платформы | Стабильно высокая |
| Форматирование дат/чисел | Поддерживается | Не поддерживается (нужно предварительное форматирование) |
Однако у СТРОКА() есть серьезное ограничение: она не работает в подзапросах и некоторых сложных конструкциях. Например, следующий запрос вызовет ошибку:
ВЫБРАТЬ
(ВЫБРАТЬ СТРОКА(Документ.Номер, " от ", Документ.Дата)) КАК НомерИДата
ИЗ ...
В таких случаях приходится возвращаться к ВЫРАЗИТЬ() или переносить логику в программный код.
ВЫРАЗИТЬ()|СТРОКА()|Переношу в программный код|Другой вариант-->
4. Объединение строк в СКД (Система Компоновки Данных)
Если вы формируете отчет с помощью Системы Компоновки Данных (СКД), то для сцепки строк можно использовать:
- 📌 Вычисляемые поля — создаются в настройках схемы компоновки и позволяют объединять данные прямо в макете.
- 📌 Выражения в тексте — если строка формируется в текстовом поле отчета (например, в заголовке).
- 📌 Программное заполнение — когда логика слишком сложна для СКД, и проще обработать данные в модуле.
Пример создания вычисляемого поля в СКД для объединения наименования и артикула товара:
- Откройте схему компоновки данных.
- Перейдите на вкладку
Вычисляемые поля. - Добавьте новое поле с именем, например,
ПолноеНаименование. - В выражении укажите:
ВЫРАЗИТЬ(Номенклатура.Наименование КАК СТРОКА(100)) + " (" + ВЫРАЗИТЬ(Номенклатура.Артикул КАК СТРОКА(20)) + ")" - Используйте это поле в структуре отчета.
Для сложных случаев, когда нужно объединить данные с условиями (например, добавлять артикул только если он заполнен), лучше использовать программное заполнение. В обработчике ПриКомпоновкеРезультата можно написать:
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, СтандартнаяОбработка)
Для Каждого Строка Из ДанныеРасшифровки Цикл
Если НЕ ЗначениеЗаполнено(Строка.Артикул) Тогда
Строка.ПолноеНаименование = Строка.Наименование;
Иначе
Строка.ПолноеНаименование = Строка.Наименование + " (" + Строка.Артикул + ")";
КонецЕсли;
КонецЦикла;
КонецПроцедуры
⚠️ Внимание: В СКД 1С 8.3.18+ появилась возможность использовать СТРОКА() прямо в вычисляемых полях, что упрощает синтаксис. В более ранних версиях этот метод не работает.
5. Конкатенация в динамических списках и формах
При работе с динамическими списками или полями форм объединение строк часто требуется для отображения комплексных данных в одной колонке. Здесь есть два основных подхода:
- 🔹 Вычисляемые поля — настраиваются в конфигураторе для динамического списка.
- 🔹 Обработка в модуле — когда логика слишком сложна для вычисляемого поля.
Пример настройки вычисляемого поля в динамическом списке:
- Откройте форму со списком (например, список документов).
- В дереве элементов формы найдите
ДинамическийСписок. - В палитре свойств перейдите на вкладку
Вычисляемые поля. - Добавьте новое поле, например,
ПолныйНомер. - В выражении укажите:
Строка(Объект.Номер) + " от " + Формат(Объект.Дата, "ДФ=dd.MM.yyyy") - Добавьте поле в колонки списка.
Если нужно объединить данные из связанных справочников (например, наименование контрагента и его ИНН), используйте точку для обращения к реквизитам:
Строка(Объект.Контрагент.Наименование) + " (" + Строка(Объект.Контрагент.ИНН) + ")"
Для форм с управляемым интерфейсом можно использовать поле 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. Типичные ошибки и их решения
Даже опытные разработчики 1С иногда сталкиваются с неожиданными ошибками при объединении строк. Разберем самые распространенные случаи:
- 🔴 "Недопустимый тип данных" — возникает, когда пытаетесь объединить строку с
NULL,Неопределеноили нестроковым типом без явного приведения. Решение: используйтеЕСТЬNULL()илиЗНАЧЕНИЕ(). - 🔴 "Слишком длинная строка" — в 1С максимальная длина строки ограничена (обычно 2 Гб, но может варьироваться). Решение: разбивайте данные на части или используйте
Поток. - 🔴 "Потеря данных при обрезке" — если в
ВЫРАЗИТЬ(... КАК СТРОКА(10))реальная длина превышает 10 символов, строка обрежется без предупреждения. Решение: всегда закладывайте запас по длине.
Пример ошибки с NULL и ее исправление:
// Ошибка:
Запрос.Текст =
"ВЫБРАТЬ
| ВЫРАЗИТЬ(Контрагент.Наименование КАК СТРОКА(100)) + "" ("" + ВЫРАЗИТЬ(Контрагент.ИНН КАК СТРОКА(12)) + "")""
|ИЗ Справочник.Контрагенты КАК Контрагент";
// Если ИНН не заполнен, результат всего выражения станет NULL.
// Правильно:
Запрос.Текст =
"ВЫБРАТЬ
| ВЫРАЗИТЬ(Контрагент.Наименование КАК СТРОКА(100)) +
| ЕСТЬNULL("" ("" + ВЫРАЗИТЬ(Контрагент.ИНН КАК СТРОКА(12)) + "")"", """")
|ИЗ Справочник.Контрагенты КАК Контрагент";
Еще одна частая проблема — некорректное форматирование дат и чисел. Например:
// Плохо: дата будет в формате "20260515000000"
Строка = "Документ от " + Документ.Дата;
// Хорошо:
Строка = "Документ от " + Формат(Документ.Дата, "ДФ=dd.MM.yyyy");
В запросах для форматирования дат используйте конструкцию ФОРМАТ:
ВЫРАЗИТЬ(Документ.Дата КАК СТРОКА(10) ФОРМАТ "ДЛФ=DD.MM.YYYY")
Потому что 1С по умолчанию выполняет целочисленное деление. Чтобы получить дробный результат, используйте ВЫРАЗИТЬ(1.0/3 КАК СТРОКА(10)) или явно преобразуйте типы.-->
8. Продвинутые техники: регулярные выражения и JSON
Для сложных задач объединения строк в 1С можно использовать:
- 🔹 Регулярные выражения — для извлечения и объединения частей строк по шаблону. Например, объединить все цифры из текста:
Текст = "Заказ №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" + Символы.ПС + "Строка