Как получить число из строки в 1С: полный разбор методов

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

В практике программирования на 1С часто возникает задача очистки данных. Например, при загрузке информации из Excel, распознавании сканов документов или интеграции со сторонними системами нам могут приходить строки вида "Вес: 120 кг", "Артикул № 123-45/А" или "Суплата: 10 500.00 руб.". Чтобы работать с этими данными как с числами, необходимо отделить цифры от текста.

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

Метод 1: Классический перебор (Цикл)

Самый надежный и универсальный способ, который работает на любой версии платформы (7.7, 8.1, 8.2, 8.3) и в любой операционной системе (Windows, Linux, MacOS) — это посимвольный обход строки. Алгоритм прост: мы смотрим на каждый символ и проверяем, является ли он цифрой.

Рассмотрим функцию, которая собирает все найденные цифры в одну строку и возвращает массив чисел. Это полезно, если в строке может быть несколько чисел (например, "Код 123, кол-во 5").

Для проверки, является ли символ цифрой, можно использовать сравнение диапазонов кодов символов или просто сравнение строк.


Функция НайтиЧислаВСтроке(Знач ИсходнаяСтрока) Экспорт
    
    МассивЧисел = Новый Массив;
    СтрокаЧисла = "";
    
    // Проходим по всей длине строки
    Для Индекс = 1 По СтрДлина(ИсходнаяСтрока) Цикл
        
        Символ = Сред(ИсходнаяСтрока, Индекс, 1);
        КодСимвола = КодСимвола(Символ);
        
        // Проверяем, является ли символ цифрой (коды ASCII от 48 до 57 соответствуют '0'-'9')
        // Также можно добавить проверку на разделители дроби, например "." или ","
        Если КодСимвола >= 48 И КодСимвола <= 57 Тогда
            СтрокаЧисла = СтрокаЧисла + Символ;
        Иначе
            // Если цепочка цифр прервалась, и мы уже что-то накопили — сохраняем число
            Если Не ПустаяСтрока(СтрокаЧисла) Тогда
                МассивЧисел.Добавить(Число(СтрокаЧисла));
                СтрокаЧисла = "";
            КонецЕсли;
        КонецЕсли;
        
    КонецЦикла;
    
    // Не забываем добавить последнее число, если строка заканчивалась цифрой
    Если Не ПустаяСтрока(СтрокаЧисла) Тогда
        МассивЧисел.Добавить(Число(СтрокаЧисла));
    КонецЕсли;
    
    Возврат МассивЧисел;
    
КонецФункции

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

Недостатки: Код получается громоздким. На очень длинных строках конкатенация (сложение строк) может работать медленно.

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

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

Для этого мы используем системный COM-объект VBScript.RegExp. Разберем пример, который умеет извлекать не только целые, но и дробные числа (с точкой или запятой).


Функция ДостатьЧислаRegExp(ИсходнаяСтрока) Экспорт
    
    МассивРезультат = Новый Массив;
    
    // Создаем COM-объект
    Попытка
        RegExp = Новый COMОбъект("VBScript.RegExp");
    Исключение
        // Скорее всего, это не Windows или закрыт доступ к COM
        Возврат МассивРезультат;
    КонецПопытки;
    
    RegExp.IgnoreCase = Истина; // Игнорировать регистр (не важно для цифр, но полезно знать)
    RegExp.Global = Истина;     // Искать все вхождения, а не только первое
    RegExp.MultiLine = Ложь;
    
    // Паттерн: 
    // \d+      - одна или более цифр
    // [.,]?    - необязательный разделитель (точка или запятая)
    // \d*      - ноль или более цифр после разделителя
    RegExp.Pattern = "\d+[.,]?\d*";
    
    Matches = RegExp.Execute(ИсходнаяСтрока);
    
    Для Каждого Match Из Matches Цикл
        Попытка
            // Заменяем запятую на точку или наоборот, чтобы Число() корректно сработало
            // в зависимости от настроек системы, но чаще всего 1С понимает оба варианта,
            // если это стандартная функция Число()
            МассивРезультат.Добавить(Число(Match.Value));
        Исключение
            // Обработка ошибок преобразования
        КонецПопытки;
    КонецЦикла;
    
    Возврат МассивРезультат;
    
КонецФункции

Важное примечание: Этот код не будет работать на серверах под управлением Linux, в веб-клиенте (браузере) и на мобильных устройствах, так как там нет библиотеки VBScript.

Метод 3: Элегантное решение через СтрРазделить (для 8.3.6 и выше)

Начиная с версии платформы 8.3.6, появились функции СтрРазделить и СтрСоединить. С их помощью можно реализовать "гениальный" метод очистки строки от мусора в две строчки кода без использования циклов 1С. Этот метод работает очень быстро, так как функции реализованы внутри платформы на C++.

Суть метода заключается в двойной инверсии:

  1. Сначала мы используем цифры как разделители, чтобы получить строку, состоящую только из мусора (букв и знаков).
  2. Затем мы используем полученный "мусор" как разделители для исходной строки, чтобы получить только цифры.

Разберем это по шагам на примере строки "Артикул123Склад":


Функция ОставитьТолькоЦифры(Знач ИсходнаяСтрока) Экспорт
    
    // 1. Получаем строку, содержащую ВСЕ символы, кроме цифр.
    // Мы "дробим" строку цифрами.
    // "Артикул123Склад" -> Разделитель "0123456789" -> Массив ["Артикул", "Склад"]
    // Затем соединяем обратно -> "АртикулСклад"
    ЛишниеСимволы = СтрСоединить(СтрРазделить(ИсходнаяСтрока, "0123456789", Ложь), "");
    
    // 2. Теперь используем полученные "ЛишниеСимволы" как разделитель для исходной строки.
    // "Артикул123Склад" -> Разделитель "АртикулСклад" -> Массив ["", "123", ""] (пустые строки отсекаются параметром Ложь)
    // В итоге получаем чистое число в виде строки.
    ЧистаяСтрокаСЧислом = СтрСоединить(СтрРазделить(ИсходнаяСтрока, ЛишниеСимволы, Ложь), "");
    
    // Преобразуем в число (если строка пустая, вернется 0)
    Возврат Число(ЧистаяСтрокаСЧислом);
    
КонецФункции

Или вариант в одну строку ("One-liner"), который можно встретить в коде опытных разработчиков:


Результат = СтрСоединить(СтрРазделить(Строка, СтрСоединить(СтрРазделить(Строка, "0123456789"), "")), "");

Особенность метода: Этот способ склеит все цифры в одно число. Если у вас строка "Вес 10 Цена 20", то результатом будет число 1020. Если вам нужно получить массив чисел [10, 20], этот метод нужно модифицировать (не делать последний СтрСоединить, а перебирать массив).

Метод 4: Получение массива чисел через СтрРазделить

Если нам нужно из строки "15; 24; 42" получить массив чисел, используя современные функции, можно сделать так:


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

Нюансы работы с дробными числами

Сложнее всего, когда нужно сохранить дробную часть, например, из строки "Сумма 123.50 руб".

Если использовать метод "удаления лишнего" (Метод 3), точка может попасть в "мусор" и удалиться, превратив 123.50 в 12350. Чтобы этого избежать, нужно добавить точку (или запятую) в список "разрешенных" символов при первом разделении.

Давайте адаптируем однострочное решение для дробных чисел:


// Добавляем точку и запятую в строку цифр
ЛишниеСимволы = СтрСоединить(СтрРазделить(ИсходнаяСтрока, "0123456789.,"), "");

// Теперь при удалении лишнего, точки и запятые останутся
ЧистаяСтрока = СтрСоединить(СтрРазделить(ИсходнаяСтрока, ЛишниеСимволы, Ложь), "");

Однако здесь есть риск. Если строка вида "1.2.3.4", то такой метод оставит "1.2.3.4", что вызовет ошибку при преобразовании в число. Поэтому для сложных случаев с грязными данными надежнее использовать Метод 1 (Цикл) или Метод 2 (RegExp) с четким паттерном.

Рекомендации по выбору метода

  1. Если вы пишете универсальный код (который может работать на Linux-сервере или в мобильном приложении) и строки не слишком длинные — используйте Метод 1 (Цикл) или Метод 4 (СтрРазделить).
  2. Если вам нужно максимально быстро очистить строку и вы уверены, что там только одно число (или их слияние допустимо) — используйте Метод 3 (Однострочник). Это самое производительное решение на платформе 8.3.
  3. Если у вас сложная логика (например, нужно доставать суммы, даты и артикулы по разным маскам) и сервер работает на Windows — используйте Регулярные выражения (Метод 2).
← На главную