Как в 1С отделить число от знака процента или других символов в строке?

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

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

Метод 1. Простая замена символов через СтрЗаменить

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

Разберем пример кода:


&НаКлиенте
Функция ОчиститьСтрокуОтПроцента(ИсходнаяСтрока)
    // Убираем знак процента, заменяя его на пустую строку
    ОчищеннаяСтрока = СтрЗаменить(ИсходнаяСтрока, "%", "");
    
    // Преобразуем результат в число
    Попытка
        Возврат Число(ОчищеннаяСтрока);
    Исключение
        Возврат 0; // Если в строке был не только процент, возвращаем 0
    КонецПопытки;
КонецФункции

Важный нюанс: при работе с процентами стоит помнить, что в математическом смысле "10%" — это не просто число 10, а 0.1. Если ваша задача предполагает дальнейшие финансовые расчеты, логично будет сразу делить полученный результат на 100, чтобы получить корректный коэффициент.

Метод 2. Универсальный перебор символов строки

Зачастую данные могут быть "загрязнены" не только одним знаком процента. В строке могут встретиться пробелы, неразрывные пробелы (код 160), кавычки или буквы. В таких случаях метод простой замены перестает быть эффективным. Рассмотрим более универсальный подход: мы проанализируем каждый символ строки и оставим только те, которые относятся к числам или разделителям дробной части.

Выполним это с помощью цикла:


&НаКлиентеНаСервереБезКонтекста
Функция ИзвлечьЧислоИзСтроки(Знач СтрокаСЧислом)
    
    // Определим, является ли значение процентом для корректной математики
    ЭтоПроцент = СтрЗаканчиваетсяНа(СтрокаСЧислом, "%");
    
    РазрешенныеСимволы = "0123456789,.";
    РезультатСтрокой = "";
    
    // Пройдем по каждому символу строки по порядку
    Для Счетчик = 1 По СтрДлина(СтрокаСЧислом) Цикл 
        
        ТекСимвол = Сред(СтрокаСЧислом, Счетчик, 1);
        
        // Если символ входит в список разрешенных, добавляем его в новую строку
        Если СтрНайти(РазрешенныеСимволы, ТекСимвол) > 0 Тогда 
            // Заменяем точку на запятую для корректной работы функции Число() в русской локализации
            Если ТекСимвол = "." Тогда
                ТекСимвол = ",";
            КонецЕсли;
            
            РезультатСтрокой = РезультатСтрокой + ТекСимвол;
        КонецЕсли;
        
    КонецЦикла;
    
    // Проверяем, не пустая ли строка получилась после очистки
    Если ПустаяСтрока(РезультатСтрокой) Тогда
        Возврат 0;
    КонецЕсли;
    
    // Финальное преобразование
    ЧисленноеЗначение = Число(РезультатСтрокой);
    
    Если ЭтоПроцент Тогда
        Возврат ЧисленноеЗначение / 100;
    Иначе
        Возврат ЧисленноеЗначение;
    КонецЕсли;
    
КонецФункции

Проанализируем ситуацию: данный метод хорош тем, что он игнорирует любые текстовые приписки. Если в функцию придет строка "Скидка: 15.5%", она корректно извлечет 0.155.

Метод 3. Использование регулярных выражений (RegExp)

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

Рассмотрим, как это реализовать:


&НаКлиенте
Функция ОчиститьСтрокуRegExp(Знач ВходнаяСтрока)
    РегВыражение = Новый COMОбъект("VBScript.RegExp");
    
    // Шаблон [^0-9,] означает: "всё, что НЕ является цифрой или запятой"
    РегВыражение.Pattern = "[^0-9,]";
    РегВыражение.Global = Истина;
    
    // Заменяем всё неподходящее на пустую строку
    Результат = РегВыражение.Replace(ВходнаяСтрока, "");
    
    Попытка
        Возврат Число(Результат);
    Исключение
        Возврат 0;
    КонецПопытки;
КонецФункции

Этот метод работает значительно быстрее циклов на больших объемах данных, но требует осторожности при работе в кроссплатформенных средах (например, на серверах под управлением Linux этот объект не создастся).

Типичные ошибки и нюансы преобразования

Разберем основные подводные камни, с которыми сталкиваются разработчики при отделении чисел от символов:

  1. Неразрывные пробелы: Часто при копировании из Excel или внешних сайтов в строку попадает символ с кодом 160. Он выглядит как пробел, но функция Число() не понимает его и выдает ошибку. Перед обработкой всегда рекомендуется делать СтрЗаменить(Строка, Символ(160), "").
  2. Разделители дробной части: В зависимости от региональных настроек системы 1С ожидает либо точку, либо запятую. Чтобы код был универсальным, лучше принудительно заменять точку на запятую перед вызовом преобразования, как мы сделали в Методе 2.
  3. Пустые строки: Всегда проверяйте результат очистки перед вызовом Число(). Вызов этой функции от пустой строки приведет к аварийному завершению кода, если он не обернут в Попытка...Исключение.
  4. Метод СтрРазделить: В начале обсуждения предлагалось использовать СтрРазделить с набором цифр в качестве разделителя. Это ошибочный путь, так как эта функция удалит сами цифры и оставит только "мусорные" символы, что прямо противоположно нашей задаче.

Альтернативный подход: Использование свойств формы

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

Выясним причину, почему это удобно: 1С умеет форматировать данные автоматически. Если у числового реквизита в свойстве Формат (или Формат редактирования) указать строку ЧЦ=10; ЧДЦ=2; ЧФ=0.00'%', то система сама будет рисовать знак процента в поле ввода. При этом в программном коде значение этого реквизита всегда будет чистым числом. Это избавляет от необходимости отделения символа от числа, так как символ существует только визуально для пользователя.

Подведем итог: для разовых задач по очистке данных из внешних источников лучше всего подходит универсальный цикл (Метод 2) или регулярные выражения (Метод 3). Для интерфейсных решений в управляемых формах оптимально использовать штатные свойства форматирования элементов формы.

← На главную