Как перевести число в текст во встроенном языке 1С и не сломать выгрузку

· 9 мин

Содержание

Чтобы получить число как строку в 1С без пробелов между разрядами, пишите Формат(Число, "ЧГ=0"). Для обмена с внешними системами (JSON, XML, HTTP-запросы) берите XMLСтрока(Число): она всегда отдаёт точку как разделитель дробной части и не ставит разделители разрядов.

Функция Строка() и неявное приведение при склейке "Текст" + Число выдают «человеческое» представление: 1 234,5 с неразрывным пробелом внутри. Для экрана это нормально, для файлов, кодов и ссылок — источник ошибок. Ниже по порядку: базовое приведение типов, форматная строка, разделители и локаль, веб-сервисы, скорость и отладка.

Базовое преобразование числа в строку: Строка() и склейка

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

  • 🔹 явно функцией Строка(Число);
  • 🔹 неявно при сложении со строкой: "Итого: " + Сумма;
  • 🔹 при подстановке в СтрШаблон("Итого: %1", Сумма).

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

Сумма = 1234567.8;
Сообщить(Строка(Сумма));            // 1 234 567,8
Сообщить("Итого: " + Сумма);        // Итого: 1 234 567,8
Сообщить(СтрШаблон("%1 руб.", Сумма)); // 1 234 567,8 руб.

Что стоит запомнить про Строка():

  • 📌 незначащие нули дробной части не выводятся: Строка(12.50) даст 12,5;
  • 📌 ноль выводится как 0;
  • 📌 отрицательные числа получают минус слева: -15;
  • 📌 пробел между разрядами — это не обычный пробел (код 32), а неразрывный (код 160, Символы.НПП).

Последний пункт — главная причина проблем. Строка 1 234 выглядит как обычная, но СтрЗаменить(Стр, " ", "") ничего из неё не уберёт.

Если число уходит в имя файла, код справочника, параметр URL или ключ соответствия — не используйте Строка() и склейку. Только Формат(..., "ЧГ=0") или XMLСтрока().

Функция Формат: форматная строка для чисел

Формат(Значение, ФорматнаяСтрока) даёт полный контроль над видом числа. Форматная строка — набор параметров Имя=Значение через точку с запятой. Порядок параметров не важен.

Основные параметры числового формата

ПараметрЧто задаётПримерРезультат для 1234.5
ЧГгруппировку разрядов; ЧГ=0 — без группировки"ЧГ=0"1234,5
ЧДЦчисло знаков после запятой, с округлением"ЧДЦ=2"1 234,50
ЧЦобщее число знаков (целая + дробная часть)"ЧЦ=8; ЧДЦ=2"1 234,50
ЧРДсимвол разделителя дробной части"ЧРД=.; ЧГ=0"1234.5
ЧРГсимвол разделителя групп разрядов"ЧРГ=' '"1 234,5 (обычный пробел)
ЧНчто выводить для нуля"ЧН=0"для нуля — 0
ЧВНвыводить ведущие нули (вместе с ЧЦ)"ЧЦ=6; ЧВН=; ЧГ=0"001235 (для целого 1235)
ЧСсдвиг разрядов (деление на 10 в степени)"ЧС=3; ЧДЦ=1"1,2
ЧОвид отрицательного числа"ЧО=0"для −5 — (5)
ЧФшаблон с подстановкой числа вместо Ч"ЧФ='Ч руб.'"1 234,5 руб.

Параметры комбинируются свободно. Пара ЧДЦ=2; ЧГ=0 — самый частый рабочий вариант: две цифры после запятой, без пробелов внутри.

Ноль превращается в пустую строку

У Формат есть поведение, которое регулярно ломает отчёты и выгрузки: для нулевого значения функция по умолчанию возвращает пустую строку. Формат(0, "ЧГ=0") вернёт "", а не "0".

Лечится параметром ЧН:

Количество = 0;
Текст1 = Формат(Количество, "ЧГ=0");          // ""
Текст2 = Формат(Количество, "ЧН=0; ЧГ=0");    // "0"
Текст3 = Формат(Количество, "ЧН=-; ЧГ=0");    // "-"

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

Ведущие нули и фиксированная длина

Для кодов, номеров и штрихкодов нужна строка фиксированной длины с нулями слева:

Номер = 42;
Код = Формат(Номер, "ЧЦ=6; ЧВН=; ЧГ=0");   // "000042"

ЧВН= указывается без значения — само наличие параметра включает ведущие нули. Без ЧГ=0 вы получите 000 042.

Округление при форматировании

ЧДЦ округляет, а не отбрасывает: Формат(10.555, "ЧДЦ=2") даст 10,56. Но это округление только в тексте. Если затем складывать отформатированные строки, сравнивать их или переводить обратно в число, расхождения на копейку неизбежны.

Сначала округлите само число через Окр(Сумма, 2), считайте с ним, а форматируйте уже результат. Так текст и данные в базе совпадут.

Сумма прописью

Отдельный случай числа как строки — сумма прописью для платёжек и счетов. Для неё есть функция ЧислоПрописью:

Текст = ЧислоПрописью(1250.40, "Л=ru_RU; ДП=Истина",
    "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2");
// Одна тысяча двести пятьдесят рублей 40 копеек

Третий параметр — склонения целой и дробной части, род и число знаков дробной части.

Разделители разрядов и локализация

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

Как зафиксировать вид числа

Есть два надёжных пути:

  1. Явно задать разделители в форматной строке: "ЧРД=.; ЧГ=0". Результат не зависит от локали сеанса.
  2. Указать локаль параметром Л: Формат(1234.5, "Л=en_US") даст 1,234.5.

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

Как избавиться от неразрывного пробела

Если строка уже получена через Строка() и её надо почистить, убирайте именно Символы.НПП:

Текст = Строка(1234567);                      // "1 234 567" с кодом 160
Чистый = СтрЗаменить(Текст, Символы.НПП, ""); // "1234567"

Но правильнее не чистить, а сразу формировать нужный вид через Формат.

ЗадачаЧем делатьПример
Показать пользователюСтрока() или Формат с ЧДЦ1 234,50
Имя файла, код, ключФормат(Ч, "ЧГ=0")1234,5
CSV для Excel с русской локальюФормат(Ч, "ЧДЦ=2; ЧГ=0")1234,50
JSON, XML, URL, SQL-текстXMLСтрока(Ч)1234.5

Число в JSON, XML и веб-сервисах

Внешние системы ждут число в машинном виде: точка вместо запятой, никаких пробелов, ноль как 0. Ровно это делает XMLСтрока:

XMLСтрока(1234567.89);  // "1234567.89"
XMLСтрока(0);           // "0"
XMLСтрока(-15);         // "-15"

Используйте её для параметров HTTP-запроса, текста XML, подписи запроса, хешей и любого места, где формат строки задаёт не человек, а протокол.

Не собирайте JSON склейкой строк

Типичная ошибка — собрать JSON вручную:

// Плохо: получится "sum": 1 234,5 — невалидный JSON
Текст = "{""sum"": " + Сумма + "}";

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

Данные = Новый Структура("sum, qty", 1234.5, 3);
Запись = Новый ЗаписьJSON;
Запись.УстановитьСтроку();
ЗаписатьJSON(Запись, Данные);
Текст = Запись.Закрыть();   // {"sum": 1234.5, "qty": 3} (с переносами строк)

Когда принимающая сторона ждёт число строкой

Некоторые API требуют сумму в кавычках и с фиксированным числом знаков: "amount": "1234.50". Здесь XMLСтрока не подходит — она не добавит второй ноль. Нужен Формат:

Данные.Вставить("amount", Формат(Сумма, "ЧДЦ=2; ЧРД=.; ЧГ=0; ЧН=0.00"));

ЧН=0.00 защищает от пустой строки при нулевой сумме — без него API получит "amount": "".

Сумму в копейках (целым числом) многие платёжные API принимают надёжнее, чем дробную. Считайте её как Окр(Сумма * 100, 0) и передавайте числом.

Обратно: строка в число

Обратная задача встречается не реже: разобрать число из файла, ответа сервиса или поля ввода.

  1. Для машинного формата с точкой используйте Число("1234.5") или XMLЗначение(Тип("Число"), "1234.5").
  2. Перед разбором уберите пробелы обоих видов: СтрЗаменить(Стр, " ", "") и СтрЗаменить(Стр, Символы.НПП, "").
  3. Если источник пишет запятую — замените её на точку.
  4. Оберните разбор в Попытка ... Исключение: на нечисловой строке Число() вызывает исключение, а не возвращает ноль.
Функция ЧислоИзТекста(Знач Текст, ЗначениеПоУмолчанию = 0)
    Текст = СокрЛП(Текст);
    Текст = СтрЗаменить(Текст, Символы.НПП, "");
    Текст = СтрЗаменить(Текст, " ", "");
    Текст = СтрЗаменить(Текст, ",", ".");
    Если ПустаяСтрока(Текст) Тогда
        Возврат ЗначениеПоУмолчанию;
    КонецЕсли;
    Попытка
        Возврат Число(Текст);
    Исключение
        Возврат ЗначениеПоУмолчанию;
    КонецПопытки;
КонецФункции

Функция годится для данных, где запятая — только разделитель дробной части. Если в источнике запятая разделяет тысячи (английский формат 1,234.5), замена запятой на точку испортит число — такой формат разбирайте отдельно.

Скорость при массовом преобразовании

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

Что реально влияет на скорость:

  • ⚡ Склейка через + в цикле. Каждое Текст = Текст + ... создаёт новую строку. На большом объёме это главный тормоз. Собирайте части в массив и соединяйте один раз через СтрСоединить(Массив, Символы.ПС).
  • ⚡ Форматная строка в переменной. Задайте её один раз до цикла, а не собирайте конкатенацией на каждой итерации.
  • ⚡ Потоковая запись. Для больших JSON используйте ЗаписьJSON.ОткрытьФайл() вместо УстановитьСтроку(): данные пишутся в файл по мере обхода, память не растёт.
  • ⚡ Место выполнения. Массовую выгрузку делайте на сервере, а не на клиенте с передачей коллекций туда и обратно.
ФорматСуммы = "ЧДЦ=2; ЧРД=.; ЧГ=0; ЧН=0.00";
Строки = Новый Массив;
Для Каждого Стр Из ТаблицаТоваров Цикл
    Строки.Добавить(Стр.Артикул + ";" + Формат(Стр.Сумма, ФорматСуммы));
КонецЦикла;
Результат = СтрСоединить(Строки, Символы.ПС);

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

Типичные ошибки и как их найти

Большинство проблем с числами-строками выглядят одинаково: «на экране всё правильно, а файл не принимают». Ниже — как распознать причину по симптому.

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

Как увидеть невидимый символ

Когда строка «на вид правильная», проверьте коды символов. В отладчике или через сообщения:

Для Поз = 1 По СтрДлина(Текст) Цикл
    Сообщить(Сред(Текст, Поз, 1) + " = " + КодСимвола(Текст, Поз));
КонецЦикла;

Код 160 — неразрывный пробел, 32 — обычный. Так за минуту видно, откуда взялся «лишний пробел».

Проверка формата в отладчике

Поставьте точку останова после формирования строки и откройте значение в окне вычисления выражений. Вычислите там же СтрДлина(Текст): строка 1 234 с неразрывным пробелом имеет длину 5, а ожидаемая 1234 — 4. Несовпадение длины сразу показывает лишний символ.

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

Почему Строка(0) выдаёт «0», а Формат(0) — пустую строку?
У функции Формат для нуля по умолчанию задано пустое представление. Чтобы получить ноль, добавьте параметр ЧН=0.
Как вывести число с двумя знаками после запятой даже для целых?
Формат(Число, “ЧДЦ=2”). Для 15 получится 15,00. Добавьте ЧГ=0, если пробелы между разрядами не нужны.
Чем XMLСтрока отличается от Формат с ЧРД=. и ЧГ=0?
XMLСтрока не зависит от параметров и всегда даёт машинный вид, ноль — как 0, без фиксированного числа знаков. Формат позволяет задать точность, например 1234.50.
Можно ли преобразовать число в строку прямо в запросе?
Язык запросов 1С не преобразует число в строку. Получите число в выборке и форматируйте его во встроенном языке или в настройках вывода отчёта.
Как задать формат числа в табличном документе без кода?
В свойствах ячейки макета есть поле формата: туда записывается та же форматная строка, например ЧДЦ=2; ЧН=0.