Как объединить строки в 1С — во встроенном языке и в запросах

· 9 мин

Содержание

Две строки в коде склеиваются оператором +: Полное = "Иванов" + " " + "Иван". Если частей много или они лежат в коллекции — удобнее СтрСоединить(Массив, " "). Для подстановки значений в готовый текст есть СтрШаблон("Документ №%1 от %2", Номер, Дата). Внутри запроса поля сцепляются тем же +, но с двумя оговорками: пустые значения оборачивают в ЕСТЬNULL, а поля неограниченной длины — в ВЫРАЗИТЬ.

Дальше — конкретные приёмы для встроенного языка и для языка запросов, с переносами строк, числами, датами и разбором того, почему при склейке иногда вылезают «кракозябры» или ошибка преобразования типа.

Оператор сложения и функции склейки

Базовый способ соединить строки — сложение. Работает с любым числом операндов:

Фамилия = "Петров";
Имя = "Пётр";
ФИО = Фамилия + " " + Имя; // "Петров Пётр"

Когда частей три-четыре, читается нормально. Когда десяток — код превращается в лесенку из плюсов и пробелов, и легко потерять разделитель. Тут выручают две встроенные функции.

Если строку вы накапливаете плюсом в цикле, заводите переменную-накопитель пустой строкой: Результат = "". Иначе сложение с Неопределено на первой итерации даст ошибку типа. Пустая строка — нейтральный операнд, она ничего не портит.

СтрСоединить(Строки, Разделитель) собирает в одну строку элементы массива или списка значений, вставляя между ними разделитель. Появилась в платформе 8.3.6:

Части = Новый Массив;
Части.Добавить("Иванов");
Части.Добавить("Иван");
Части.Добавить("Иванович");

ФИО = СтрСоединить(Части, " "); // "Иванов Иван Иванович"
Строка = СтрСоединить(Части, "; "); // "Иванов; Иван; Иванович"

Удобно, когда число элементов заранее неизвестно — например, вы наполняете массив в цикле, а потом одной строкой получаете готовый результат. Обратная функция — СтрРазделить — разбивает строку по разделителю на массив.

СтрШаблон(Шаблон, З1, … З10) вставляет значения в заранее заданный текст на места %1…%10:

Текст = СтрШаблон("Документ №%1 от %2 на сумму %3 руб.",
    Номер, Формат(Дата, "ДЛФ=D"), Формат(Сумма, "ЧДЦ=2"));

Этот способ читается лучше всего: видно итоговую фразу целиком, а не разорванную плюсами. Один нюанс — чтобы вывести сам знак процента, его удваивают: %%.

Для коротких фраз берите +, для списка переменной длины — СтрСоединить, для шаблонных сообщений пользователю — СтрШаблон. Три инструмента под три разные задачи.

Переносы строк, табуляция и другие служебные символы

Нажать Enter внутри строкового литерала нельзя — перенос в коде задаётся через системное перечисление Символы. Самые ходовые:

  • Символы.ПС — перевод строки (аналог \n);
  • Символы.ВК — возврат каретки (\r);
  • Символы.Таб — табуляция;
  • Символы.НПП — неразрывный пробел;
  • Символы.ПФ — перевод формы.
Сообщение = "Проверьте реквизиты:" + Символы.ПС
    + "— ИНН" + Символы.ПС
    + "— КПП" + Символы.ПС
    + "— расчётный счёт";

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

Для файлов, которые потом откроют в Windows-программах (Блокнот, выгрузки для банка), ставьте пару Символы.ВК + Символы.ПС — иначе часть редакторов покажет текст одной строкой. Внутри самой 1С достаточно одного Символы.ПС.

Табуляцию применяют для выравнивания столбцов в простом текстовом отчёте:

Строка = Товар + Символы.Таб + Количество + Символы.Таб + Цена;

Если нужен символ, которого нет в перечислении, его получают по коду Unicode функцией Символ(Код). Например, Символ(160) — тот же неразрывный пробел, Символ(8364) — знак евро. Обратная функция КодСимвола(Строка, Позиция) возвращает код символа в указанной позиции.

Когда многострочную строку нужно потом разобрать обратно по строкам, пригодятся СтрЧислоСтрок(Текст) (сколько строк в тексте) и СтрПолучитьСтроку(Текст, Номер) (вернуть строку по номеру). Это удобнее, чем вручную искать Символы.ПС через СтрНайти. А если результат нужен массивом — тот же СтрРазделить(Текст, Символы.ПС) разложит многострочный текст на элементы.

Склейка полей внутри запроса

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

ВЫБРАТЬ
    Контрагенты.Наименование + " (ИНН " + Контрагенты.ИНН + ")" КАК Представление
ИЗ
    Справочник.Контрагенты КАК Контрагенты

Здесь два подводных камня, из-за которых запрос либо падает, либо выдаёт пустоту.

Первый — NULL. Если хоть один операнд равен NULL (а так бывает при левом соединении или у незаполненного реквизита), весь результат склейки станет NULL, и строка пропадёт. Каждое ненадёжное поле оборачивают в ЕСТЬNULL:

ВЫБРАТЬ
    Контрагенты.Наименование + " (ИНН " + ЕСТЬNULL(Контрагенты.ИНН, "—") + ")" КАК Представление
ИЗ
    Справочник.Контрагенты КАК Контрагенты

Второй — поля неограниченной длины. Реквизиты вроде «Комментарий» хранятся как строка неограниченной длины. Их нельзя напрямую сцеплять, группировать и сравнивать — запрос вернёт ошибку. Поле приводят к конечной длине через ВЫРАЗИТЬ:

ВЫБРАТЬ
    Заказы.Номер + ": " + ВЫРАЗИТЬ(Заказы.Комментарий КАК СТРОКА(150)) КАК Описание
ИЗ
    Документ.ЗаказПокупателя КАК Заказы

Проверять такие запросы удобно в консоли запросов — внешней обработке, которая выполняет текст запроса и показывает результат таблицей. Она же подскажет точную позицию ошибки, если склейка составлена неверно.

Третий — типы операндов. Оператор + в запросе складывает только строки. Числовое или ссылочное поле сначала приводят к строке. Число — через ВЫРАЗИТЬ, ссылку — через ПРЕДСТАВЛЕНИЕ:

ВЫБРАТЬ
    "Заказ № " + ВЫРАЗИТЬ(Заказы.Номер КАК СТРОКА(15)) + " — "
        + ПРЕДСТАВЛЕНИЕ(Заказы.Контрагент) КАК Строка
ИЗ
    Документ.ЗаказПокупателя КАК Заказы

Функция ПРЕДСТАВЛЕНИЕ возвращает читаемое наименование ссылки (контрагента, номенклатуры) той же строкой, что видна пользователю в списке. Для даты в запросе удобнее не склеивать её текст, а вернуть поле как есть и отформатировать в коде через Формат() — так проще управлять видом даты.

В запросе нельзя подставить Символы.ПС — это объект встроенного языка, а не языка запросов. Перенос либо вставляют реальным разрывом строки внутри строкового литерала запроса, либо, что надёжнее, добавляют уже в коде после получения результата.

Сборка текста из чисел, дат и коллекций

Сложить строку с числом «в лоб» нельзя: "Итого: " + 100 вызовет ошибку преобразования, потому что платформа попытается привести всё выражение к числу. Число и дату сначала переводят в строку.

Короткий путь — функция Строка():

Текст = "Остаток: " + Строка(Остаток) + " шт.";

Но Строка(Число) подставляет групповые разделители и региональный формат — для банковских выгрузок и технических строк это мешает. Тогда берут Формат() с явными параметрами:

ЗадачаВыражениеРезультат
Сумма с копейкамиФормат(Сумма, "ЧДЦ=2")1 234,56
Число без разделителя группФормат(Сумма, "ЧГ=0")1234
Дата в коротком видеФормат(Дата, "ДЛФ=D")07.10.2026
Только дата из «датавремя»Формат(Дата, "ДФ=dd.MM.yyyy")07.10.2026

Когда нужно собрать текст из множества однотипных значений — например, перечислить номенклатуру через запятую — накапливайте элементы в массив и склейте одним вызовом, а не плюсом в цикле:

Названия = Новый Массив;
Для Каждого Строка Из Товары Цикл
    Названия.Добавить(Строка.Номенклатура.Наименование);
КонецЦикла;

Перечень = СтрСоединить(Названия, ", ");

Такой код не оставляет «висящего» разделителя в конце и работает заметно быстрее, чем конкатенация строки плюсом на каждой итерации: при склейке + платформа каждый раз пересоздаёт строку целиком, и на больших объёмах это ощутимо тормозит.

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

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

  • СокрЛП(Значение) — убирает пробелы по краям (а СокрЛ и СокрП — только слева или справа);
  • ВРег, НРег, Трег — приводят к верхнему, нижнему регистру или к виду «С Заглавной»;
  • СтрЗаменить(Строка, Что, НаЧто) — вычищает лишние символы, например двойные пробелы;
  • Лев, Прав, Сред — отрезают нужную часть, если склеить надо не всё значение, а первые N символов.
Код = СокрЛП(ВРег(ИсходныйКод));
Префикс = Лев(Код, 3);
Результат = Префикс + "-" + Код;

Юникод и кодировки: откуда берутся «кракозябры»

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

Классический случай — собрали строку, записали в файл, открыли, а там нечитаемые символы. Причина не в склейке, а в несовпадении кодировок записи и чтения. Кодировку задают явно:

Запись = Новый ЗаписьТекста("C:\Выгрузка\data.txt", КодировкаТекста.UTF8);
Запись.ЗаписатьСтроку(Перечень);
Запись.Закрыть();

При чтении указывают ту же кодировку, в которой файл реально сохранён:

Чтение = Новый ЧтениеТекста("C:\Выгрузка\data.txt", КодировкаТекста.UTF8);
Содержимое = Чтение.Прочитать();
Чтение.Закрыть();

Если принимаете файл от стороннего сервиса и символы «поехали» — почти всегда дело в том, что файл в UTF-8, а вы читаете его как ANSI (или наоборот). Кодировку выгрузки уточняют в описании формата обмена.

Отдельная тонкость — невидимые символы, которые приезжают вместе с данными: неразрывные пробелы, табуляции, переносы. При склейке они никуда не денутся и будут мешать сравнению. Перед соединением «сырые» значения чистят: СокрЛП(Значение) убирает пробелы по краям, а при необходимости лишние символы вырезают через СтрЗаменить.

Ошибки при склейке строк и как их убрать

Почти все проблемы сводятся к нескольким повторяющимся сценариям. Ниже — симптом и что проверить.

Диагностика: выберите симптом

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

Частые вопросы

Чем `СтрСоединить` лучше сложения через `+`?
Он сам ставит разделитель между элементами и не добавляет его после последнего, работает с массивом переменной длины и быстрее на больших объёмах. Для двух-трёх строк разницы нет — берите +.
Можно ли вставить перенос строки прямо в запросе?
Штатного символа переноса в языке запросов нет: Символы.ПС там не работает. Либо вставляйте реальный разрыв внутри строкового литерала запроса, либо добавляйте перенос уже в коде после выборки — это надёжнее.
Почему `"Итого: " + 100` выдаёт ошибку?
Платформа пытается привести всю операцию к числу и спотыкается о текст. Число нужно явно перевести в строку: "Итого: " + Строка(100) или через Формат(), если важен вид числа.
Как убрать групповые пробелы в числе при склейке?
Используйте Формат(Число, "ЧГ=0") — параметр ЧГ=0 отключает разделитель групп разрядов. Для суммы с копейками добавьте ЧДЦ=2.
Склейка кириллицы с латиницей ломает кодировку?
Нет. В памяти 1С все строки в Юникоде, соединяйте любые символы свободно. Кодировка важна только при записи строки в файл или обмене с внешней системой.