Соединяем текст и число в коде 1С: рабочие способы

· 9 мин

Содержание

Напрямую сложить строку и число в 1С нельзя: выражение "Итого: " + 100 завершается ошибкой преобразования типов. Платформа не приводит число к строке автоматически — это нужно делать явно. Самый короткий способ собрать текст с числом — обернуть число в функцию Строка(): "Итого: " + Строка(100).

Дальше — все рабочие приёмы: как превратить число в текст, как убрать лишние пробелы функциями СокрЛ и СокрП, как через Формат() задать разделитель дробной части и число знаков после запятой, и какие ошибки в этом месте встречаются чаще всего. Все примеры — для встроенного языка 1С:Предприятие 8.3.

Почему «строка + число» выдаёт ошибку

Оператор + во встроенном языке 1С работает по-разному в зависимости от типа левого операнда.

  • Если слева число — это арифметическое сложение.
  • Если слева строка — это склейка (конкатенация), и справа тоже должна стоять строка.

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

Цена = 1500;
Сообщить("Цена: " + Цена + " руб.");   // ошибка: число и строку не сложить

В обратную сторону платформа иногда выручает: 100 + "50" вернёт 150, потому что слева число и 1С попробует привести строку к числу. Но полагаться на это не стоит — 100 + "abc" снова упадёт с ошибкой. Явное преобразование надёжнее.

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

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

Функция Строка() — самый простой перевод числа в текст

Строка() принимает значение любого типа и возвращает его текстовое представление. Для числа это и есть то, что нужно для склейки.

Цена = 1500;
Сообщить("Цена: " + Строка(Цена) + " руб.");   // Цена: 1 500 руб.

Обратите внимание на пробел внутри 1 500. Это не опечатка: Строка() применяет к числу оформление по умолчанию и разбивает его на группы разрядов. Разделителем выступает неразрывный пробел (символ с кодом 160), а не обычный.

Для сумм в интерфейсе такой вид обычно удобен. Но если строка пойдёт в имя файла, в номер, в выгрузку или в сравнение — разряды лучше убрать. Сделать это проще не постфактум, а сразу при форматировании (об этом ниже), потому что обычный СтрЗаменить(Текст, " ", "") неразрывный пробел не поймает.

Строку можно получить и от отрицательного числа, и от дробного:

Сообщить("Остаток: " + Строка(-500));    // Остаток: -500
Сообщить(Строка(1234.5));                 // 1 234,5

СтрШаблон() — сборка строки без длинных плюсов

Когда в текст надо подставить несколько значений, цепочка из + и Строка() становится громоздкой. Удобнее СтрШаблон(): в шаблоне ставите метки %1, %2, %3, а значения перечисляете следом.

Товар = "Болт М8";
Кол = 40;
Цена = 15;
Сообщить(СтрШаблон("%1: %2 шт. по %3 руб.", Товар, Кол, Цена));
// Болт М8: 40 шт. по 15 руб.

Числа в СтрШаблон() переводятся в текст автоматически, вручную оборачивать в Строка() не нужно.

Автоперевод работает по тем же правилам, что и Строка(). Значит, крупные числа снова получат разделитель разрядов: СтрШаблон("%1", 1000) даст 1 000. Если это мешает — подставляйте не само число, а заранее отформатированное значение: СтрШаблон("%1", Формат(1000, "ЧГ=0")).

Ещё СтрШаблон() удобен для многострочных сообщений и для текста, который потом переводится на другой язык: порядок подстановок задаётся метками, а не позицией в склейке.

Пара деталей, которые экономят время. Одну и ту же метку можно использовать несколько раз — СтрШаблон("%1 плюс %1 равно %2", 2, 4) даст 2 плюс 2 равно 4. Чтобы вывести сам знак процента, удваивайте его: %%. Подстановок в шаблоне поддерживается до десяти — от %1 до %10; если значений нужно больше, собирайте текст из частей через массив и СтрСоединить().

Убираем лишние пробелы: СокрЛ, СокрП и СокрЛП

Три функции отрезают пробелы по краям строки:

  • СокрЛ(Текст) — убирает пробелы слева (в начале).
  • СокрП(Текст) — убирает пробелы справа (в конце).
  • СокрЛП(Текст) — убирает пробелы с обеих сторон.

В задачах со склейкой они нужны в двух ситуациях.

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

Н = Формат(7, "ЧЦ=10");    // "         7" — ширина 10 знаков
Н = СокрЛ(Н);              // "7"

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

Введено = "  250 ";
Сумма = Число(СокрЛП(Введено));    // 250

Без СокрЛП функция Число() на строке с пробелами по краям может сработать не так, как вы ждёте. Поэтому связка Число(СокрЛП(...)) — рабочая привычка при разборе пользовательского ввода.

Функция Формат() — управляем видом числа

Формат() — это тот же перевод числа в строку, что и Строка(), но с полным контролем над видом. Параметры передаются строкой «ключ=значение» через точку с запятой. Для чисел чаще всего нужны четыре.

ПараметрЧто задаётПример
ЧГразделитель групп разрядов (ЧГ=0 отключает)Формат(1000, "ЧГ=0") → 1000
ЧДЦчисло знаков после запятойФормат(5, "ЧДЦ=2") → 5,00
ЧРДразделитель дробной частиФормат(5.5, "ЧРД=.") → 5.5
ЧЦ + ЧНширина и заполнение ведущими нулямиФормат(123, "ЧЦ=6; ЧН=0") → 000123

Несколько параметров можно комбинировать в одной строке:

Сумма = 1500;
Сообщить("К оплате: " + Формат(Сумма, "ЧГ=0; ЧДЦ=2") + " руб.");
// К оплате: 1500,00 руб.

Ведущие нули удобны для номеров документов и артикулов:

Номер = 123;
Сообщить("№ " + Формат(Номер, "ЧЦ=6; ЧН=0"));   // № 000123

Главное отличие от Строка(): Строка() даёт вид по умолчанию, а Формат() — ровно тот, который вы задали. Для денег, кодов и выгрузок почти всегда нужен Формат().

Дробные числа: разделитель и число знаков

С дробями чаще всего спотыкаются на двух вещах — на разделителе (запятая или точка) и на «хвосте» лишних знаков.

По умолчанию 1С отделяет дробную часть запятой:

Сообщить(Строка(1234.5));                  // 1 234,5
Сообщить(Формат(1234.5, "ЧГ=0"));          // 1234,5

Если число уходит в CSV, в JSON, в банковский файл или в чужую систему, там обычно ждут точку. Задаём её параметром ЧРД:

Сообщить(Формат(1234.5, "ЧГ=0; ЧРД=."));   // 1234.5

Фиксированное число знаков после запятой — через ЧДЦ. Это важно для сумм: ЧДЦ=2 добьёт нулями или округлит до копеек.

Сообщить(Формат(10, "ЧДЦ=2"));             // 10,00
Сообщить(Формат(10.999, "ЧДЦ=2"));         // 11,00  (округление)

ЧДЦ именно отображает округлённое значение, а не меняет само число в переменной. Если округление важно для расчёта, а не только для вывода, округляйте функцией Окр() до перевода в строку.

Разница наглядна на примере. Формат(10.456, "ЧДЦ=2") покажет 10,46, но в переменной останется 10.456, и следующее умножение возьмёт полное число. А Окр(10.456, 2) вернёт настоящее 10.46, с которым дальше и пойдёт расчёт. Для денежных сумм сначала считают и округляют Окр() до копеек, а Формат() применяют уже на выводе — тогда отчёт и проводки сходятся до копейки.

Собрать строку с ценой за единицу в «чистом» виде для выгрузки:

Цена = 1234.5;
Строкой = Формат(Цена, "ЧГ=0; ЧДЦ=2; ЧРД=.");   // 1234.50

Готовые примеры сборки строки

Несколько шаблонов, которые закрывают большинство задач.

Сумма для сообщения пользователю (разряды нужны, копейки — да):

Итого = 48500;
Сообщить("Итого к оплате: " + Формат(Итого, "ЧДЦ=2") + " руб.");
// Итого к оплате: 48 500,00 руб.

Номер строки + текст (разряды не нужны):

Для Сч = 1 По 3 Цикл
    Сообщить("Строка " + Формат(Сч, "ЧГ=0") + " обработана");
КонецЦикла;

Сумма двух текстовых чисел — здесь нужно сначала превратить текст в числа, сложить, и только потом собрать строку:

А = "100";
Б = "50";
Сумма = Число(А) + Число(Б);           // 150
Сообщить("Сумма: " + Строка(Сумма));    // Сумма: 150

Проверьте глазами: 100 + 50 = 150 — склейка "10050" здесь была бы ошибкой, потому что оба операнда уже приведены к числу.

Разбор строки с разрядами. Если текст пришёл с неразрывным пробелом внутри (например, его когда-то вернул Строка()), прямой Число("1 000") может не сработать. Надёжнее сразу форматировать исходное число через ЧГ=0, а не склеивать и потом разбирать обратно.

Сборка в цикле: не тормозим на больших объёмах

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

Правильнее собирать части в массив, а в конце склеить одним вызовом СтрСоединить():

Строки = Новый Массив;
Для Сч = 1 По 50000 Цикл
    Строки.Добавить("Строка " + Формат(Сч, "ЧГ=0"));
КонецЦикла;
Результат = СтрСоединить(Строки, Символы.ПС);   // перевод строки между элементами

Второй аргумент СтрСоединить() — разделитель. Символы.ПС ставит перевод строки, можно подставить ";", "," или любой свой текст. Для коротких циклов на несколько десятков шагов разница незаметна — там обычный + проще и нагляднее.

Склеиваем текст не только с числом

Те же правила действуют для других типов: дату, булево и ссылку тоже нельзя приписать к строке напрямую, их переводят через Строка() или Формат().

Сообщить("Дата документа: " + Формат(ТекущаяДата(), "ДФ=dd.MM.yyyy"));
Сообщить("Проведён: " + Строка(Истина));    // Проведён: Да

Для булева Строка(Истина) вернёт Да, а Строка(Ложь) — Нет. Для даты удобнее Формат() с параметром ДФ — он задаёт порядок дня, месяца и года. А Строка() от ссылки на элемент справочника или документ даст его представление — то же, что вы видите в списке, поэтому приписать ссылку к тексту для сообщения тоже можно без лишних преобразований.

Проверьте себя
Что вернёт `"Код: " + Строка(7)`?
Как убрать разделитель разрядов у большого числа?
Каким параметром задать точку вместо запятой в дробной части?

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

Почему `"Сумма " + 100` не работает, а `100 + "5"` работает?
Оператор + смотрит на левый операнд. Слева строка — это склейка, и справа ждут строку, число туда не подставится. Слева число — это сложение, и справа 1С попробует привести строку к числу. Чтобы не зависеть от этого, число для текста всегда переводите функцией Строка() или Формат().
Откуда в `Строка(1500)` взялся пробел?
Это разделитель групп разрядов — неразрывный пробел по умолчанию. Чтобы его убрать, используйте Формат(1500, "ЧГ=0").
Чем `Строка()` отличается от `Формат()`?
Строка() даёт представление числа по умолчанию, Формат() — ровно такое, какое вы задали параметрами (ЧГ, ЧДЦ, ЧРД, ЧЦ). Для денег, номеров и выгрузок берите Формат().
Как показать сумму всегда с двумя знаками после запятой?
Формат(Сумма, "ЧДЦ=2"). Параметр добьёт нулями (10 → 10,00) и округлит лишние знаки при выводе. Само число в переменной при этом не меняется — для расчётов округляйте Окр().
Нужно ли `СокрЛП()` при обычной склейке строки с числом?
При склейке через Строка() и Формат() — нет. СокрЛП() нужен, когда вы разбираете текст из поля ввода обратно в число или отрезаете ведущие пробелы у числа, отформатированного с фиксированной шириной (ЧЦ).