Как преобразовать строку с лишними разделителями и точкой в конце в число?

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

При интеграции 1С с внешними системами, такими как веб-сайты, Excel-файлы или сторонние API, программисты часто сталкиваются с проблемой «грязных» данных. Например, числовое значение может приходить в виде строки "1,978.23.". Для системы 1С такая строка не является валидным числом из-за лишней запятой (разделителя триад) и случайной точки в конце строки. В этой статье мы подробно разберем, как очистить подобные строки и корректно преобразовать их в числовой тип данных.

Метод 1: Базовое использование функций СтрЗаменить и Лев

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


// Допустим, входная строка: "1,978.23."
СтрокаСЧислом = "1,978.23.";

// 1. Убираем последний символ (точку)
ОчищеннаяСтрока = Лев(СтрокаСЧислом, СтрДлина(СтрокаСЧислом) - 1);

// 2. Удаляем запятые (разделители групп разрядов)
ОчищеннаяСтрока = СтрЗаменить(ОчищеннаяСтрока, ",", "");

// 3. Преобразуем результат в число
ИтоговоеЧисло = Число(ОчищеннаяСтрока);

Этот метод хорошо работает, если формат входящих данных строго фиксирован. Функция Лев с параметром СтрДлина - 1 эффективно отсекает последний символ, а СтрЗаменить полностью вычищает все вхождения запятой. Однако стоит помнить, что если точки в конце строки не окажется, данный код удалит значащую цифру. Поэтому перед использованием Лев рекомендуется добавить проверку на наличие точки в конце строки.

Метод 2: Использование объекта ОписаниеТипов для безопасного приведения

Существует более «продвинутый» способ, который минимизирует риск возникновения ошибок при преобразовании. Рассмотрим вариант с использованием объекта ОписаниеТипов. Этот метод позволяет системе более гибко обрабатывать входящие данные и приводить их к нужному типу.


ВхСтрока = "1,978.23.";
// Создаем описание типа "Число"
ТипЧисло = Новый ОписаниеТипов("Число");

// Комбинированный метод очистки через разделение и соединение
// Убираем запятые, делим по точкам и собираем обратно, чтобы убрать лишние вкрапления
ЧастиСтроки = СтрРазделить(СтрЗаменить(ВхСтрока, ",", ""), ".", Ложь);

// Собираем обратно только значащие части (целую и дробную)
// В данном случае мы берем все части, кроме последней, если она пустая
РезультатСтрокой = СтрСоединить(ЧастиСтроки, ".");

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

Этот подход полезен тем, что ОписаниеТипов при методе ПривестиЗначение не вызывает аварийного завершения программы (исключения), если строка окажется совсем некорректной, а просто вернет значение по умолчанию (0).

Метод 3: Очистка от неразрывных пробелов

Разберем ситуацию, когда данные копируются из веб-интерфейсов или Excel. В таких строках часто присутствуют так называемые «неразрывные пробелы» (символ с кодом 160). Обычная функция СтрЗаменить(Строка, " ", "") их «не видит», из-за чего функция Число() выдает ошибку. Выясним, как с этим бороться.

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


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

// Теперь преобразование пройдет успешно
Результат = Число(ЧистаяСтрока);

Метод 4: Регулярные выражения для универсальной очистки

Если формат входящих строк крайне нестабилен (могут быть буквы, разные знаки препинания, случайные символы), проанализируем использование регулярных выражений (RegExp). Это наиболее мощный инструмент для работы со строками в 1С через COM-объекты Windows.

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


// Создаем объект для работы с регулярными выражениями
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Истина;
RegExp.MultiLine = Истина;

// Шаблон [^0-9.] означает: найти всё, что НЕ является цифрой или точкой
RegExp.Pattern = "[^0-9.]";

ВходнаяСтрока = "Цена: 1,978.23 руб.";
// Заменяем все найденные "плохие" символы на пустую строку
ТолькоЧислоСтрокой = RegExp.Replace(ВходнаяСтрока, "");

// Если в конце осталась точка (как в нашем примере 1978.23.), ее нужно убрать
Если Прав(ТолькоЧислоСтрокой, 1) = "." Тогда
    ТолькоЧислоСтрокой = Лев(ТолькоЧислоСтрокой, СтрДлина(ТолькоЧислоСтрокой) - 1);
КонецЕсли;

ИтоговоеЧисло = Число(ТолькоЧислоСтрокой);

Метод 5: Обработка региональных настроек и безопасное преобразование

Важно помнить, что функция Число() в 1С сильно зависит от региональных настроек операционной системы. Если на сервере или компьютере пользователя в качестве разделителя дробной части установлена запятая, то попытка преобразовать строку "1978.23" (с точкой) приведет к ошибке.

Рассмотрим, как написать отказоустойчивый код, используя конструкцию Попытка...Исключение:

  1. Нормализация разделителя. Перед преобразованием приведите строку к формату, который понимает текущий сеанс 1С.
  2. Проверка через ЭтоЧисло. Прежде чем вызывать исключение, можно проверить строку встроенной функцией.
  3. Блок перехвата ошибок. Всегда оборачивайте финальный этап в Попытка.

СтрокаЗначение = "1,978.23.";
// 1. Предварительная очистка
СтрокаЗначение = СтрЗаменить(СтрокаЗначение, ",", "");
Если Прав(СтрокаЗначение, 1) = "." Тогда
    СтрокаЗначение = Лев(СтрокаЗначение, СтрДлина(СтрокаЗначение) - 1);
КонецЕсли;

// 2. Попытка преобразования
Попытка
    Результат = Число(СтрокаЗначение);
Исключение
    // Если возникла ошибка (например, из-за настроек разделителя точка/запятая)
    // Попробуем заменить точку на запятую
    Попытка
        Результат = Число(СтрЗаменить(СтрокаЗначение, ".", ","));
    Исключение
        Результат = 0; // Если ничего не помогло
        Сообщить("Не удалось преобразовать значение: " + СтрокаЗначение);
    КонецПопытки;
КонецПопытки;

Использование функций БСП

Если ваша конфигурация разработана на базе БСП (Библиотеки стандартных подсистем), рекомендуем заглянуть в общий модуль СтроковыеФункцииКлиентСервер. Там часто уже реализованы функции типа ТолькоЦифрыВСтроке или специализированные парсеры чисел, которые учитывают все вышеописанные нюансы с пробелами и разделителями.

Подведем итог: для решения задачи по очистке строки "1,978.23." эффективнее всего комбинировать удаление запятых через СтрЗаменить и проверку последнего символа. Для более сложных случаев всегда используйте регулярные выражения и не забывайте про неразрывные пробелы, которые часто становятся причиной трудноуловимых ошибок.

← На главную