Как извлечь числовое значение из текстовой строки в 1С

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

В процессе разработки конфигураций и обработок в 1С регулярно возникает необходимость извлечь числовой параметр из текстовой строки. Типичный пример — текстовое наименование материала вида "Мат Стандарт 240-501", где первое число (240) обозначает ширину полотна, а второе — другой технологический параметр. Рассмотрим несколько способов решения этой задачи: от универсального алгоритмического перебора до современных встроенных средств платформы.

Способ 1. Посимвольный перебор строки

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

Посмотрим на пример реализации данного алгоритма, создающего список найденных в строке чисел:


ИсходнаяСтрока = "Мат Стандарт 240-501";
ЭталонЦифр = "0123456789";
ДлинаСтроки = СтрДлина(ИсходнаяСтрока);

СписокЧисел = Новый СписокЗначений;
ТекущаяЦифра = "";

Для Индекс = 1 По ДлинаСтроки Цикл
    ТекущийСимвол = Сред(ИсходнаяСтрока, Индекс, 1);
    
    Если Найти(ЭталонЦифр, ТекущийСимвол) > 0 Тогда
        ТекущаяЦифра = ТекущаяЦифра + ТекущийСимвол;
    Иначе
        Если ТекущаяЦифра <> "" Тогда
            СписокЧисел.Добавить(Число(ТекущаяЦифра));
            ТекущаяЦифра = "";
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Если ТекущаяЦифра <> "" Тогда
    СписокЧисел.Добавить(Число(ТекущаяЦифра));
КонецЕсли;

// Первый элемент списка содержит число 240 (ширина)
Если СписокЧисел.Количество() > 0 Тогда
    ШиринаПолотна = СписокЧисел[0].Значение;
КонецЕсли;

Проанализируем работу данного кода:

  1. Функция СтрДлина() вычисляет общее количество символов в наименовании.
  2. В цикле с помощью функции Сред() поочередно извлекается каждый символ.
  3. Функция Найти() проверяет, входит ли символ в строку-шаблон "0123456789".
  4. Как только встречается нечисловой символ (пробел, дефис или буква), накопленная последовательность переводится в тип Число и добавляется в массив или список значений.

Способ 2. Поиск по разделителям и сплит строки

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

Рассмотрим ситуацию, когда ширина полотна находится перед дефисом. Посмотрим на следующий пример кода:


ИсходнаяСтрока = "Мат Стандарт 240-501";

// 1. Разбиваем строку по пробелам, чтобы получить последнюю часть с числами
МассивПодстрок = СтрРазделить(ИсходнаяСтрока, " ");
ПоследняяЧасть = МассивПодстрок[МассивПодстрок.ВГраница()]; // Получаем "240-501"

// 2. Находим позицию дефиса
ПозицияДефиса = СтрНайти(ПоследняяЧасть, "-");

Если ПозицияДефиса > 0 Тогда
    ТекстШирины = Лев(ПоследняяЧасть, ПозицияДефиса - 1);
    ШиринаПолотна = Число(ТекстШирины); // Получаем число 240
КонецЕсли;

Этот способ работает существенно быстрее посимвольного перебора, однако требует строгого соблюдения формата записи наименований.

Способ 3. Использование регулярных выражений

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

Вариант А: Встроенные функции (Платформа 8.3.23 и новее)

Начиная с версии 8.3.23, в платформу добавлены штатные функции работы с регулярными выражениями. Выясним, как извлечь первое числовое значение из строки с их помощью:


ИсходнаяСтрока = "Мат Стандарт 240-501";
Шаблонпоиска = "\d+"; // Ищем одну или несколько цифр подряд

РезультатПоиска = СтрНайтиПоРегулярномуВыражению(ИсходнаяСтрока, Шаблонпоиска);

Если РезультатПоиска <> Неопределено Тогда
    ИзвлеченныйТекст = Сред(ИсходнаяСтрока, РезультатПоиска.НачальнаяПозиция, РезультатПоиска.Длина);
    ШиринаПолотна = Число(ИзвлеченныйТекст); // Получаем 240
КонецЕсли;

Вариант Б: COM-объект VBScript.RegExp (Для старых версий платформы)

В более ранних версиях платформы регулярные выражения применяются через COM-объект VBScript.RegExp:


RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина;
RegExp.Global = Ложь; // Берем только первое совпадение
RegExp.Pattern = "\d+";

Совпадения = RegExp.Execute("Мат Стандарт 240-501");

Если Совпадения.Count > 0 Тогда
    ШиринаПолотна = Число(Совпадения.Item(0).Value);
КонецЕсли;

Важное ограничение: Использование COMОбъект("VBScript.RegExp") работает исключительно под управлением ОС Windows. На серверах под Linux данный метод вызовет ошибку выполнения.

Архитектурные рекомендации по хранению данных

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

  1. Создавать отдельные числовые реквизиты объекта (например, реквизит Ширина с типом Число) или использовать механизм дополнительных реквизитов и сведений БСП.
  2. Генерировать полное наименование автоматически при записи объекта на основе введенных числовых характеристик, а не пытаться извлекать их из текста обратным путем.
← На главную