Как преобразовать строку с пробелами в число в 1С без ошибок?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке в среде 1С:Предприятие одной из классических и часто встречающихся задач является преобразование строкового представления числа в полноценный числовой тип. Очень часто строки приходят из внешних источников (файлы Excel, CSV, XML, веб-сервисы) или формируются самой платформой с использованием группировки разрядов. В таких строках присутствуют разделители — пробелы или специальные неразрывные пробелы (НПП). Если попытаться преобразовать такую строку «в лоб», система может выдать критическую ошибку выполнения. В этой статье мы подробно разберем, как правильно, безопасно и эффективно решать эту задачу в различных сценариях.

Выясняем причину: откуда берутся пробелы и что такое неразрывный пробел (НПП)

Для начала проанализируем ситуацию с разделителями. Платформа 1С при выводе чисел по умолчанию использует группировку разрядов для удобства восприятия пользователем (например, число 11580 отображается как "11 580"). В качестве разделителя групп 1С использует не обычный пробел (символ с кодом 32), а неразрывный пробел (НПП), имеющий код 160 (в Unicode). Этот символ доступен в системе через глобальное свойство Символы.НПП.

Если строка формируется встроенными механизмами платформы, или копируется из экранных форм, в ней гарантированно будет содержаться именно неразрывный пробел. Обычные функции очистки строк, удаляющие стандартные пробелы (например, функция СокрЛП), неразрывный пробел не удаляют. Именно поэтому стандартная функция преобразования может повести себя непредсказуемо, если предварительно не подготовить строку.

Вариант 1. Прямое присвоение в реквизит и функция Число()

Рассмотрим поведение платформы при попытке напрямую преобразовать строку "11 580" (где в качестве разделителя используется пробел или Символы.НПП).

Если мы попытаемся присвоить строку реквизиту с типом Число напрямую:

РеквизитСТипомЧисло = СтрокаЧисла;

В этом случае платформа выполнит неявное приведение типов. Поведение системы зависит от контекста выполнения (клиент или сервер) и конкретного символа разделителя. Если разделителем является корректный неразрывный пробел, платформа с большой долей вероятности успешно преобразует значение в число 11580. Однако, если в строке окажется обычный пробел или другие посторонние символы, неявное приведение может «молча» обрезать строку до первого нецифрового знака (записав в реквизит значение 11) или просто сбросить значение в 0. Поэтому использовать неявное приведение крайне не рекомендуется из-за непредсказуемости результата.

Теперь посмотрим на пример явного использования функции Число():

ПеременнаяЧтоТо = Число(СтрокаЧисла);

Функция Число() анализирует переданную строку как с учетом региональных настроек информационной базы, так и без них. Если строка содержит корректный разделитель групп (неразрывный пробел), функция вернет числовое значение 11580. Однако, если строка содержит обычный пробел (код 32) или любые другие символы, не удовлетворяющие маске числа, платформа вызовет критическое исключение (ошибку выполнения), которая приведет к аварийной остановке программы, если код не обернут в блок обработки ошибок.

Вариант 2. Безопасное приведение через ОписаниеТипов

Для того чтобы избежать аварийного завершения работы программы при невозможности преобразовать строку, мы можем использовать специальный класс платформы — ОписаниеТипов. Метод ПривестиЗначение() этого объекта возвращает значение по умолчанию для выбранного типа (в случае числа — это 0), если преобразование выполнить не удалось.

Разберем по шагам, как это реализовать на практике:


ОписаниеТиповЧисло = Новый ОписаниеТипов("Число");
Результат = ОписаниеТиповЧисло.ПривестиЗначение(СтрокаЧисла);

В данном примере, если в переменной СтрокаЧисла находится значение "11 580" с неразрывным пробелом, метод вернет полноценное число 11580. Если же строка будет содержать некорректные символы (например, буквы или некорректные знаки препинания), программа не упадет с ошибкой — в переменную Результат просто запишется число 0. Это делает данный метод чрезвычайно удобным для безопасной обработки «грязных» внешних данных.

Вариант 3. Очистка строки от пробелов перед преобразованием

Чтобы гарантировать 100% успех при использовании функции Число(), лучшей практикой является предварительная очистка строки от всех возможных видов пробелов — как обычных, так и неразрывных. Для этого мы можем применить функцию СтрЗаменить().

Рассмотрим пример кода:


// Очищаем строку от неразрывных пробелов (Символы.НПП) и обычных пробелов
ОчищеннаяСтрока = СтрЗаменить(СтрокаЧисла, Символы.НПП, "");
ОчищеннаяСтрока = СтрЗаменить(ОчищеннаяСтрока, " ", "");

// Теперь безопасно преобразуем очищенную строку в число
Попытка
    РезультатЧисло = Число(ОчищеннаяСтрока);
Исключение
    РезультатЧисло = 0; // Обработка ситуации, если в строке были буквы
КонецПопытки;

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

Вариант 4. Использование функций Библиотеки стандартных подсистем (БСП)

Если вы работаете в современной конфигурации, построенной на базе БСП (например, 1С:Бухгалтерия 3.0, 1С:ERP, 1С:Управление торговлей 11 и др.), вам не нужно писать собственные велосипеды для очистки строк. В составе БСП есть готовый общий модуль, содержащий функции для безопасной работы со строками.

Рекомендуется использовать функцию СтроковыеФункцииКлиентСервер.СтрокаВЧисло(). Давайте проанализируем пример ее вызова:


// Пример использования стандартной функции БСП
ЗначениеЧислом = СтроковыеФункцииКлиентСервер.СтрокаВЧисло(СтрокаЧисла);

Преимущества использования БСП:

  1. Функция полностью безопасна и никогда не вызывает исключений (ошибок выполнения). Если строка не может быть преобразована, она вернет Неопределено (или 0 для пустой строки).
  2. Она автоматически удаляет любые виды пробелов: как лидирующие/концевые, так и разделители разрядов внутри числа (включая обычные пробелы и неразрывные пробелы Символы.НПП).
  3. Корректно обрабатывает ведущие нули (например, строка "000125" превратится в число 125).
  4. Умеет работать как с точкой, так и с запятой в качестве десятичного разделителя, преобразуя дробную часть без привязки к локальным настройкам операционной системы сервера.

Вариант 5. Применение функции Формат() для обратной задачи

Иногда разработчики сталкиваются с обратной задачей: число нужно преобразовать в строку, но так, чтобы платформа не добавляла неразрывные пробелы в качестве разделителей групп. Это критически важно при формировании XML-файлов, отправке JSON-запросов или выгрузке данных в банк-клиент.

Для управления форматированием числа используется стандартная функция Формат() с параметром ЧГ=0 (что означает "Число Группировать = 0"). Рассмотрим пример:


ЧисловоеЗначение = 11580;
// Преобразуем число в строку без разделителей групп (без пробелов)
СтрокаБезПробелов = Формат(ЧисловоеЗначение, "ЧГ=0"); // Результат: "11580"

Использование этого метода гарантирует, что на выходе вы получите «чистую» строку без лишних символов, которую затем можно легко передавать во внешние системы без дополнительной обработки.

Подведем итоги

Мы подробно разобрали особенности работы с числами и строками в 1С. Для обеспечения стабильной работы ваших алгоритмов придерживайтесь следующих правил:

← На главную