Сложение строк в запросах 1С:Предприятие — задача, с которой сталкивается практически каждый разработчик. Несмотря на кажущуюся простоту, здесь есть множество нюансов: от синтаксических особенностей разных версий платформы до оптимизации производительности при работе с большими объемами данных. В этой статье мы разберём все актуальные способы конкатенации — от стандартных функций языка запросов до программных обходных путей, когда стандартные методы не работают.
Особое внимание уделим типичным ошибкам, которые приводят к падению запросов или некорректным результатам. Например, почему оператор + может вернуть NULL вместо ожидаемой строки, или как правильно обрабатывать пустые значения при объединении полей. Материал будет полезен как начинающим специалистам, так и опытным программистам, которые хотят оптимизировать свои запросы.
Все примеры протестированы на актуальных версиях платформы 1С:Предприятие 8.3.20+, но majority методов работают и в более ранних редакциях. Для сложных случаев приведём альтернативные решения с пояснениями, когда их стоит применять.
1. Базовый синтаксис: оператор + и функция СтрСокрЛП()
Самый очевидный способ сложить строки в запросе — использовать оператор +. Он работает аналогично большинству языков программирования, но имеет важные особенности в контексте 1С:
Основное правило: если хотя бы одно из слагаемых равно NULL, результат всего выражения тоже будет NULL. Это часто становится причиной ошибок при работе с необязательными реквизитами. Пример корректного запроса:
ВЫБРАТЬ
Сотрудник.Наименование + " (" + Сотрудник.Должность + ")" КАК ПолноеИмя
ИЗ
Справочник.Сотрудники КАК Сотрудник
Для защиты от NULL используйте функцию ВЫРАЗИТЬ() или ЗНАЧЕНИЕ():
ВЫБРАТЬ
Сотрудник.Наименование + " (" + ВЫРАЗИТЬ(Сотрудник.Должность КАК СТРОКА) + ")"
ИЗ
Справочник.Сотрудники КАК Сотрудник
- ✅ Плюсы: простой и интуитивно понятный синтаксис
- ⚠️ Минусы: требует явной обработки
NULL-значений - 🔧 Когда использовать: для простых случаев с гарантированно заполненными полями
Функция СтрСокрЛП() полезна, когда нужно не только сложить строки, но и убрать лишние пробелы. Она автоматически убирает пробелы в начале и конце строки, а также сокращает несколько подряд идущих пробелов до одного:
ВЫБРАТЬ
СтрСокрЛП(Сотрудник.Наименование + " " + Сотрудник.Должность) КАК ПолноеИмя
ИЗ
Справочник.Сотрудники КАК Сотрудник
2. Конструктор строк (СКД) и шаблонизация
Для сложных случаев конкатенации, особенно когда нужно формировать строки по шаблону, удобно использовать конструктор строк в системе компоновки данных (СКД). Это позволяет:
- 📝 Использовать параметры и условные выражения
- 🎨 Форматировать результат (переносы строк, отступы)
- 🔄 Динамически менять шаблон в зависимости от данных
Пример создания шаблона в СКД:
ВЫБРАТЬ
Сотрудник.Наименование КАК Имя,
Сотрудник.Должность КАК Должность,
"" КАК Шаблон
ПОМЕСТИТЬ ВТ_Сотрудники
ИЗ
Справочник.Сотрудники КАК Сотрудник
// В параметрах СКД задаём шаблон:
&НаСервере
Процедура ПриКомпоновкеРезультата(ДанныеРасшифровки, ДанныеВывода, СтандартнаяОбработка)
ДанныеВывода.Шаблон = "Сотрудник: &Имя (&Должность)";
КонецПроцедуры
Важный нюанс: шаблонизация в СКД работает медленнее прямой конкатенации в запросе. Если вам нужно обработать тысячи строк, лучше использовать программный обход результата запроса (см. раздел 5).
Для многострочных шаблонов в СКД используйте символ | для обозначения новой строки. Например: "Строка1|Строка2"
3. Функции СТРСОЕДИНИТЬ() и СТРЗАМЕНИТЬ() для сложных случаев
Когда нужно объединить несколько строк с разделителем или заменить части строки, удобно использовать специализированные функции:
| Функция | Назначение | Пример использования |
|---|---|---|
СТРСОЕДИНИТЬ() |
Объединение массива строк с разделителем | СТРСОЕДИНИТЬ(", ", МассивСтрок) |
СТРЗАМЕНИТЬ() |
Замена подстроки в строке | СТРЗАМЕНИТЬ(Текст, "старое", "новое") |
ЛЕВ()/ПРАВ() |
Извлечение части строки | ЛЕВ(Строка, 10) |
Пример использования СТРСОЕДИНИТЬ() для формирования списка через запятую:
ВЫБРАТЬ
Номенклатура.Наименование КАК Товар,
СТРСОЕДИНИТЬ(", ",
ВЫБОР
КОГДА Номенклатура.Артикул <> ""
ТОГДА Номенклатура.Артикул
ИНАЧЕ NULL
КОНЕЦ,
ВЫБОР
КОГДА Номенклатура.Серия <> ""
ТОГДА Номенклатура.Серия
ИНАЧЕ NULL
КОНЕЦ
) КАК ПолноеОписание
ИЗ
Справочник.Номенклатура КАК Номенклатура
Что делать если СТРСОЕДИНИТЬ возвращает NULL?
Функция вернёт NULL, если все передаваемые аргументы равны NULL. Чтобы избежать этого, добавьте в список хотя бы одну непустую строку, например: СТРСОЕДИНИТЬ(", ", " ", Артикул, Серия)
4. Работа с датами и числами при конкатенации
Частая ошибка — попытка сложить строку с датой или числом без явного приведения типов. В результате запрос либо падает с ошибкой несовместимости типов, либо возвращает неожиданные результаты. Всегда используйте функции приведения:
- 📅
ФОРМАТ()— для форматирования дат - 🔢
СТРОКА()— для преобразования чисел - 💰
ФОРМАТИРОВАТЬЧИСЛО()— для денежных значений
Примеры корректного форматирования:
ВЫБРАТЬ
"Заказ №" + ФОРМАТ(Документ.Номер, "ЧГ=0") +
" от " + ФОРМАТ(Документ.Дата, "ДЛФ=DT") КАК Заголовок
ИЗ
Документ.ЗаказКлиента КАК Документ
Для денежных сумм важно учитывать настройки валюты и разделителей:
ВЫБРАТЬ
"Сумма: " + ФОРМАТИРОВАТЬЧИСЛО(Документ.СуммаДокумента, "ЧР= ; ЧДЦ=2; ЧРД= ; ЧН=Нет") КАК СуммаТекстом
ИЗ
Документ.РеализацияТоваровУслуг КАК Документ
Всегда проверяйте региональные настройки при форматировании чисел и дат. В разных базах разделителем дробной части может быть как точка, так и запятая.
5. Программный обход: когда запрос не справится
В некоторых случаях конкатенацию проще и эффективнее сделать не в самом запросе, а программно после его выполнения. Это актуально когда:
- 📊 Нужно объединить данные из разных запросов
- 🔄 Логика формирования строки слишком сложная
- ⚡ Требуется максимальная производительность
Пример программного объединения:
&НаСервере
Функция ПолучитьПолныеИменаСотрудников()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сотрудник.Ссылка КАК Ссылка,
| Сотрудник.Наименование КАК Имя,
| Сотрудник.Должность КАК Должность
|ИЗ
| Справочник.Сотрудники КАК Сотрудник";
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
ПолноеИмя = СтрСокрЛП(Выборка.Имя + " " + ?(Выборка.Должность <> "", Выборка.Должность, ""));
// Дальнейшая обработка...
КонецЦикла;
КонецФункции
Преимущества программного подхода:
- Гибкость — можно использовать любые функции 1С и условную логику
- Производительность — иногда быстрее, чем сложные выражения в запросе
- Отладка — проще находить ошибки в коде, чем в SQL-представлении запроса
Потребовалось более 3-х вложенных ВЫБОР КОГДА в запросе|Нужно объединить данные из разных источников|Логика формирования строки меняется в зависимости от прав пользователя|Запрос выполняется слишком долго (более 1 секунды)
-->
6. Оптимизация производительности
Конкатенация в запросах может значительно замедлять выполнение, особенно при работе с большими таблицами. Основные правила оптимизации:
- Избегайте конкатенации в секции ГДЕ — это приводит к полному сканированию таблицы
- Используйте индексируемые поля — не конкатенируйте поля, по которым есть индексы
- Разделяйте сложные выражения — лучше сделать два простых запроса и объединить результаты
Пример неоптимального запроса:
ВЫБРАТЬ
Клиент.Наименование + " (" + Клиент.ИНН + ")" КАК ПолноеИмя
ИЗ
Справочник.Контрагенты КАК Клиент
ГДЕ
Клиент.Наименование + Клиент.ИНН = "Тест1234567890"
Оптимизированный вариант:
ВЫБРАТЬ
Клиент.Наименование КАК Имя,
Клиент.ИНН КАК ИНН
ИЗ
Справочник.Контрагенты КАК Клиент
ГДЕ
Клиент.Наименование = "Тест"
И Клиент.ИНН = "1234567890"
// Объединение делаем программно после выполнения запроса
Критическая ошибка многих разработчиков: конкатенация в секции ГДЕ полностью отменяет использование индексов, даже если поля по отдельности индексированы. Это может увеличить время выполнения запроса в сотни раз на больших базах.
7. Типичные ошибки и их решения
Даже опытные разработчики иногда сталкиваются с неожиданными проблемами при конкатенации строк. Разберём самые распространённые случаи:
| Ошибка | Причина | Решение |
|---|---|---|
Результат NULL вместо строки |
Одно из полей содержит NULL |
Используйте ВЫРАЗИТЬ(Поле КАК СТРОКА) или ЗНАЧЕНИЕ(Поле) |
| Ошибка "Несовместимые типы" | Попытка сложить строку с числом/датой | Явное приведение типов с помощью ФОРМАТ() или СТРОКА() |
| Неправильная кодировка символов | Разные кодировки исходных строк | Используйте СтрЗаменить() для нормализации или настройте кодировку базы |
Особый случай — работа с полнотекстовым поиском. Если вы конкатенируете поля для последующего поиска по ним, помните:
⚠️ Внимание: Полнотекстовый индекс не учитывает строки, полученные в результате конкатенации в запросе. Для поиска по таким полям нужно создавать отдельные колонки в таблице или использовать программный обход.
8. Альтернативные подходы: временные таблицы и СКД
Для сложных сценариев, когда стандартные методы не подходят, можно использовать:
- 🗃️ Временные таблицы — для многоэтапной обработки
- 📊 Система компоновки данных — для гибкого форматирования
- 🔄 Объединение запросов — когда данные разнесены по разным источникам
Пример с временной таблицей:
ВЫБРАТЬ
Товар.Ссылка КАК Ссылка,
Товар.Наименование КАК Наименование,
Товар.Артикул КАК Артикул
ПОМЕСТИТЬ ВТ_Товары
ИЗ
Справочник.Номенклатура КАК Товар
// Второй запрос работает с временной таблицей
ВЫБРАТЬ
ВТ.Наименование + " (" + ВТ.Артикул + ")" КАК ПолноеНаименование
ИЗ
ВТ_Товары КАК ВТ
Для отчётов с сложным форматированием строк лучше сразу использовать СКД. Это позволит:
- Гибко настраивать вывод в зависимости от параметров
- Использовать условное оформление
- Легко модифицировать шаблоны без изменения кода
Временные таблицы особенно полезны когда нужно сделать несколько проходов по данным с разной логикой обработки. Это часто быстрее, чем пытаться сделать всё в одном сложном запросе.
FAQ: Ответы на частые вопросы
Можно ли в запросе 1С использовать конкатенацию с переносами строк?
Да, для этого используйте символ | (вертикальная черта) или функцию СтрЗаменить() с символом перевода строки Символы.ПС. Пример:
ВЫБРАТЬ
"Строка1" + Символы.ПС + "Строка2" КАК Текст
В СКД для многострочного вывода удобнее использовать параметр "Перенос строк" в настройках поля.
Почему при конкатенации пропадают пробелы между словами?
Это происходит если вы используете функцию СтрСокрЛП(), которая автоматически убирает лишние пробелы. Чтобы сохранить пробелы, используйте простую конкатенацию через + или функцию СТРСОЕДИНИТЬ() с явным указанием разделителя:
СТРСОЕДИНИТЬ(" ", Поле1, Поле2, Поле3)
Как объединить строки с проверкой на пустые значения?
Используйте конструкцию ВЫБОР КОГДА или функцию ЗНАЧЕНИЕ():
ВЫБРАТЬ
ВЫБОР
КОГДА НЕ Поле1 ЕСТЬ NULL И НЕ Поле2 ЕСТЬ NULL
ТОГДА Поле1 + " " + Поле2
ИНАЧЕ ЗНАЧЕНИЕ(Поле1) + ЗНАЧЕНИЕ(Поле2)
КОНЕЦ КАК Результат
Для нескольких полей удобнее использовать программный обход с проверкой каждого значения.
Можно ли конкатенировать строки разных кодировок в одном запросе?
Технически можно, но результат может содержать некорректные символы. Для нормализации используйте:
СтрЗаменить(Поле, Символ(НекорректныйКод), Символ(КорректныйКод))
Лучше всего обеспечить единую кодировку на уровне базы данных или при загрузке данных.
Как ускорить запрос с множественной конкатенацией полей?
Основные способы оптимизации:
- Вынесите конкатенацию в программный код после выполнения запроса
- Используйте временные таблицы для промежуточных результатов
- Разбейте сложный запрос на несколько простых
- Создайте вычисляемое поле в справочнике/документе, если конкатенация часто используется
Самый радикальный способ — денормализация данных с созданием отдельного реквизита для хранения сконкатенированной строки.