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

Особое внимание уделим типичным ошибкам, которые приводят к падению запросов или некорректным результатам. Например, почему оператор + может вернуть NULL вместо ожидаемой строки, или как правильно обрабатывать пустые значения при объединении полей. Материал будет полезен как начинающим специалистам, так и опытным программистам, которые хотят оптимизировать свои запросы.

Все примеры протестированы на актуальных версиях платформы 1С:Предприятие 8.3.20+, но majority методов работают и в более ранних редакциях. Для сложных случаев приведём альтернативные решения с пояснениями, когда их стоит применять.

1. Базовый синтаксис: оператор + и функция СтрСокрЛП()

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

Основное правило: если хотя бы одно из слагаемых равно NULL, результат всего выражения тоже будет NULL. Это часто становится причиной ошибок при работе с необязательными реквизитами. Пример корректного запроса:

ВЫБРАТЬ

Сотрудник.Наименование + " (" + Сотрудник.Должность + ")" КАК ПолноеИмя

ИЗ

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

Для защиты от NULL используйте функцию ВЫРАЗИТЬ() или ЗНАЧЕНИЕ():

ВЫБРАТЬ

Сотрудник.Наименование + " (" + ВЫРАЗИТЬ(Сотрудник.Должность КАК СТРОКА) + ")"

ИЗ

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

  • Плюсы: простой и интуитивно понятный синтаксис
  • ⚠️ Минусы: требует явной обработки NULL-значений
  • 🔧 Когда использовать: для простых случаев с гарантированно заполненными полями
📊 Какой способ конкатенации вы используете чаще?
Оператор +
Функция СтрСокрЛП
Конструктор строк
Программный обход
Другой

Функция СтрСокрЛП() полезна, когда нужно не только сложить строки, но и убрать лишние пробелы. Она автоматически убирает пробелы в начале и конце строки, а также сокращает несколько подряд идущих пробелов до одного:

ВЫБРАТЬ

СтрСокрЛП(Сотрудник.Наименование + " " + Сотрудник.Должность) КАК ПолноеИмя

ИЗ

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

2. Конструктор строк (СКД) и шаблонизация

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

  • 📝 Использовать параметры и условные выражения
  • 🎨 Форматировать результат (переносы строк, отступы)
  • 🔄 Динамически менять шаблон в зависимости от данных

Пример создания шаблона в СКД:

ВЫБРАТЬ

Сотрудник.Наименование КАК Имя,

Сотрудник.Должность КАК Должность,

"" КАК Шаблон

ПОМЕСТИТЬ ВТ_Сотрудники

ИЗ

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

// В параметрах СКД задаём шаблон:

&НаСервере

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

ДанныеВывода.Шаблон = "Сотрудник: &Имя (&Должность)";

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

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

💡

Для многострочных шаблонов в СКД используйте символ | для обозначения новой строки. Например: "Строка1|Строка2"

3. Функции СТРСОЕДИНИТЬ() и СТРЗАМЕНИТЬ() для сложных случаев

Когда нужно объединить несколько строк с разделителем или заменить части строки, удобно использовать специализированные функции:

Функция Назначение Пример использования
СТРСОЕДИНИТЬ() Объединение массива строк с разделителем СТРСОЕДИНИТЬ(", ", МассивСтрок)
СТРЗАМЕНИТЬ() Замена подстроки в строке СТРЗАМЕНИТЬ(Текст, "старое", "новое")
ЛЕВ()/ПРАВ() Извлечение части строки ЛЕВ(Строка, 10)

Пример использования СТРСОЕДИНИТЬ() для формирования списка через запятую:

ВЫБРАТЬ

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

СТРСОЕДИНИТЬ(", ",

ВЫБОР

КОГДА Номенклатура.Артикул <> ""

ТОГДА Номенклатура.Артикул

ИНАЧЕ NULL

КОНЕЦ,

ВЫБОР

КОГДА Номенклатура.Серия <> ""

ТОГДА Номенклатура.Серия

ИНАЧЕ NULL

КОНЕЦ

) КАК ПолноеОписание

ИЗ

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

Что делать если СТРСОЕДИНИТЬ возвращает NULL?

Функция вернёт NULL, если все передаваемые аргументы равны NULL. Чтобы избежать этого, добавьте в список хотя бы одну непустую строку, например: СТРСОЕДИНИТЬ(", ", " ", Артикул, Серия)

4. Работа с датами и числами при конкатенации

Частая ошибка — попытка сложить строку с датой или числом без явного приведения типов. В результате запрос либо падает с ошибкой несовместимости типов, либо возвращает неожиданные результаты. Всегда используйте функции приведения:

  • 📅 ФОРМАТ() — для форматирования дат
  • 🔢 СТРОКА() — для преобразования чисел
  • 💰 ФОРМАТИРОВАТЬЧИСЛО() — для денежных значений

Примеры корректного форматирования:

ВЫБРАТЬ

"Заказ №" + ФОРМАТ(Документ.Номер, "ЧГ=0") +

" от " + ФОРМАТ(Документ.Дата, "ДЛФ=DT") КАК Заголовок

ИЗ

Документ.ЗаказКлиента КАК Документ

Для денежных сумм важно учитывать настройки валюты и разделителей:

ВЫБРАТЬ

"Сумма: " + ФОРМАТИРОВАТЬЧИСЛО(Документ.СуммаДокумента, "ЧР= ; ЧДЦ=2; ЧРД= ; ЧН=Нет") КАК СуммаТекстом

ИЗ

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

💡

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

5. Программный обход: когда запрос не справится

В некоторых случаях конкатенацию проще и эффективнее сделать не в самом запросе, а программно после его выполнения. Это актуально когда:

  • 📊 Нужно объединить данные из разных запросов
  • 🔄 Логика формирования строки слишком сложная
  • ⚡ Требуется максимальная производительность

Пример программного объединения:

&НаСервере

Функция ПолучитьПолныеИменаСотрудников()

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

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

"ВЫБРАТЬ

| Сотрудник.Ссылка КАК Ссылка,

| Сотрудник.Наименование КАК Имя,

| Сотрудник.Должность КАК Должность

|ИЗ

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

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

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

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

ПолноеИмя = СтрСокрЛП(Выборка.Имя + " " + ?(Выборка.Должность <> "", Выборка.Должность, ""));

// Дальнейшая обработка...

КонецЦикла;

КонецФункции

Преимущества программного подхода:

  1. Гибкость — можно использовать любые функции и условную логику
  2. Производительность — иногда быстрее, чем сложные выражения в запросе
  3. Отладка — проще находить ошибки в коде, чем в SQL-представлении запроса

Потребовалось более 3-х вложенных ВЫБОР КОГДА в запросе|Нужно объединить данные из разных источников|Логика формирования строки меняется в зависимости от прав пользователя|Запрос выполняется слишком долго (более 1 секунды)

-->

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

Конкатенация в запросах может значительно замедлять выполнение, особенно при работе с большими таблицами. Основные правила оптимизации:

  1. Избегайте конкатенации в секции ГДЕ — это приводит к полному сканированию таблицы
  2. Используйте индексируемые поля — не конкатенируйте поля, по которым есть индексы
  3. Разделяйте сложные выражения — лучше сделать два простых запроса и объединить результаты

Пример неоптимального запроса:

ВЫБРАТЬ

Клиент.Наименование + " (" + Клиент.ИНН + ")" КАК ПолноеИмя

ИЗ

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

ГДЕ

Клиент.Наименование + Клиент.ИНН = "Тест1234567890"

Оптимизированный вариант:

ВЫБРАТЬ

Клиент.Наименование КАК Имя,

Клиент.ИНН КАК ИНН

ИЗ

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

ГДЕ

Клиент.Наименование = "Тест"

И Клиент.ИНН = "1234567890"

// Объединение делаем программно после выполнения запроса

Критическая ошибка многих разработчиков: конкатенация в секции ГДЕ полностью отменяет использование индексов, даже если поля по отдельности индексированы. Это может увеличить время выполнения запроса в сотни раз на больших базах.

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

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

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

Особый случай — работа с полнотекстовым поиском. Если вы конкатенируете поля для последующего поиска по ним, помните:

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

8. Альтернативные подходы: временные таблицы и СКД

Для сложных сценариев, когда стандартные методы не подходят, можно использовать:

  • 🗃️ Временные таблицы — для многоэтапной обработки
  • 📊 Система компоновки данных — для гибкого форматирования
  • 🔄 Объединение запросов — когда данные разнесены по разным источникам

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

ВЫБРАТЬ

Товар.Ссылка КАК Ссылка,

Товар.Наименование КАК Наименование,

Товар.Артикул КАК Артикул

ПОМЕСТИТЬ ВТ_Товары

ИЗ

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

// Второй запрос работает с временной таблицей

ВЫБРАТЬ

ВТ.Наименование + " (" + ВТ.Артикул + ")" КАК ПолноеНаименование

ИЗ

ВТ_Товары КАК ВТ

Для отчётов с сложным форматированием строк лучше сразу использовать СКД. Это позволит:

  • Гибко настраивать вывод в зависимости от параметров
  • Использовать условное оформление
  • Легко модифицировать шаблоны без изменения кода
💡

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

FAQ: Ответы на частые вопросы

Можно ли в запросе 1С использовать конкатенацию с переносами строк?

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

ВЫБРАТЬ

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

В СКД для многострочного вывода удобнее использовать параметр "Перенос строк" в настройках поля.

Почему при конкатенации пропадают пробелы между словами?

Это происходит если вы используете функцию СтрСокрЛП(), которая автоматически убирает лишние пробелы. Чтобы сохранить пробелы, используйте простую конкатенацию через + или функцию СТРСОЕДИНИТЬ() с явным указанием разделителя:

СТРСОЕДИНИТЬ(" ", Поле1, Поле2, Поле3)
Как объединить строки с проверкой на пустые значения?

Используйте конструкцию ВЫБОР КОГДА или функцию ЗНАЧЕНИЕ():

ВЫБРАТЬ

ВЫБОР

КОГДА НЕ Поле1 ЕСТЬ NULL И НЕ Поле2 ЕСТЬ NULL

ТОГДА Поле1 + " " + Поле2

ИНАЧЕ ЗНАЧЕНИЕ(Поле1) + ЗНАЧЕНИЕ(Поле2)

КОНЕЦ КАК Результат

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

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

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

СтрЗаменить(Поле, Символ(НекорректныйКод), Символ(КорректныйКод))

Лучше всего обеспечить единую кодировку на уровне базы данных или при загрузке данных.

Как ускорить запрос с множественной конкатенацией полей?

Основные способы оптимизации:

  1. Вынесите конкатенацию в программный код после выполнения запроса
  2. Используйте временные таблицы для промежуточных результатов
  3. Разбейте сложный запрос на несколько простых
  4. Создайте вычисляемое поле в справочнике/документе, если конкатенация часто используется

Самый радикальный способ — денормализация данных с созданием отдельного реквизита для хранения сконкатенированной строки.