К статье
Практический материал

Разработка и Конфигурация · 12 мин

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

Как извлечь число из строки в 1С: перебор символов, регулярные выражения, преобразование типов. Готовые функции, обработка ошибок и примеры кода на встроенном языке.

Задача извлечь число из строки возникает в 1С постоянно: артикул поставщика содержит код товара, в наименовании документа зашит номер, в комментарии к платежу указана сумма. Встроенного оператора «вытащить число» во встроенном языке нет, поэтому разработчик выбирает один из нескольких подходов в зависимости от формата исходных данных.

Выбор метода зависит от трёх вопросов: число стоит в известной позиции или «плавает» по строке, в строке одно число или несколько, нужна целая часть или число с дробной частью. От ответов зависит, хватит ли простого перебора символов или потребуются регулярные выражения, а также как корректно преобразовать результат в тип «Число» без ошибок.

Ниже разобраны четыре рабочих способа: перебор символов, разбор по разделителям, регулярные выражения через COM-объект и преобразование типов. Для каждого приведены готовый код, условия применимости и типичные ошибки. Все примеры работают на платформе 8.3 в обычном и управляемом приложении, если не указано иное.

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

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

Идея проста: для каждого символа проверяем, является ли он цифрой, и если да — дописываем в строку-аккумулятор. Проверку удобно делать сравнением с диапазоном символов «0»–«9», так как в 1С символы сравниваются по кодам.

Функция ВыделитьЧислоИзСтроки(ИсходнаяСтрока) Экспорт

Результат = "";

Для Позиция = 1 По СтрДлина(ИсходнаяСтрока) Цикл

Символ = Сред(ИсходнаяСтрока, Позиция, 1);

Если Символ >= "0" И Символ <= "9" Тогда

Результат = Результат + Символ;

КонецЕсли;

КонецЦикла;

Если ПустаяСтрока(Результат) Тогда

Возврат 0;

КонецЕсли;

Возврат Число(Результат);

КонецФункции

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

Ограничение метода: он склеивает все цифры строки в одно число. Строка «Заказ 12 от 25.03, сумма 1500» превратится в 12251500. Если в строке несколько чисел и нужно конкретное, используйте разбор по разделителям или регулярные выражения.

1c
НомерДокумента = ВыделитьЧислоИзСтроки("Реализация № АБ-001245 от поставщика"); // вернёт 1245

Способ 2. Извлечение числа с дробной частью

Если нужно вытащить не целое, а дробное число — например, «12,5 кг» из строки упаковки, — простой фильтр цифр не подойдёт: разделитель будет потерян. Логику нужно расширить: пропускать цифры и первый встречный разделитель дробной части (точку или запятую), а остальные символы отбрасывать.

Дополнительная тонкость — функция Число() в 1С воспринимает в качестве разделителя точку, а запятую не понимает. Поэтому перед преобразованием запятую следует заменить на точку через СтрЗаменить().

Функция ВыделитьДробноеЧисло(ИсходнаяСтрока) Экспорт

Результат = "";

РазделительУжеБыл = Ложь;

Для Позиция = 1 По СтрДлина(ИсходнаяСтрока) Цикл

Символ = Сред(ИсходнаяСтрока, Позиция, 1);

Если Символ >= "0" И Символ <= "9" Тогда

Результат = Результат + Символ;

ИначеЕсли (Символ = "." Или Символ = ",") И Не РазделительУжеБыл Тогда

Результат = Результат + ".";

РазделительУжеБыл = Истина;

КонецЕсли;

КонецЦикла;

Если ПустаяСтрока(Результат) Тогда

Возврат 0;

КонецЕсли;

Возврат Число(Результат);

КонецФункции

Флаг РазделительУжеБыл защищает от строк вида «1.2.3», где второй разделитель сделал бы результат невалидным. Учтите, что функция собирает цифры со всей строки: для «вес 2,5 кг, цена 300» результат будет 25300 с точкой после первой двойки — то есть 2.5300. Если в строке несколько дробных чисел, сначала отделите нужный фрагмент (см. следующий раздел).

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

Когда структура строки известна заранее — например, артикул вида «ТОВ-00456-Р» или наименование «Кабель 3х2.5 медь», — эффективнее разбить строку на части и взять нужный фрагмент. Для этого во встроенном языке есть функция СтрРазделить(), доступная начиная с платформы 8.3.6.

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

СтрокаАртикула = "ТОВ-00456-Р";

Части = СтрРазделить(СтрокаАртикула, "-");

Если Части.Количество() >= 2 Тогда

КодТовара = Число(Части[1]); // 456

КонецЕсли;

Для строк с пробелами удобно разделять по пробелу и искать первый фрагмент, который целиком состоит из цифр. Так решается задача «в строке несколько чисел, взять первое».

Функция ПервоеЧислоВСтроке(ИсходнаяСтрока)

Части = СтрРазделить(СокрЛП(ИсходнаяСтрока), " ");

Для Каждого Фрагмент Из Части Цикл

ТолькоЦифры = Истина;

Для Позиция = 1 По СтрДлина(Фрагмент) Цикл

Символ = Сред(Фрагмент, Позиция, 1);

Если Не (Символ >= "0" И Символ <= "9") Тогда

ТолькоЦифры = Ложь;

Прервать;

КонецЕсли;

КонецЦикла;

Если ТолькоЦифры И Не ПустаяСтрока(Фрагмент) Тогда

Возврат Число(Фрагмент);

КонецЕсли;

КонецЦикла;

Возврат 0;

КонецФункции

Способ 4. Регулярные выражения через VBScript.RegExp

Для сложных шаблонов — «число после слова Итого», «сумма с разделителями разрядов», «все числа в строке» — удобны регулярные выражения. Встроенной поддержки во встроенном языке нет, но на Windows-сервере и клиенте доступен COM-объект VBScript.RegExp.

Функция НайтиЧислоПоШаблону(ИсходнаяСтрока)

Попытка

RegExp = Новый COMОбъект("VBScript.RegExp");

Исключение

Возврат 0; // COM недоступен (Linux, веб-клиент)

КонецПопытки;

RegExp.Pattern = "\d+([.,]\d+)?";

RegExp.Global = Ложь;

Совпадения = RegExp.Execute(ИсходнаяСтрока);

Если Совпадения.Count = 0 Тогда

Возврат 0;

КонецЕсли;

Найденное = СтрЗаменить(Совпадения.Item(0).Value, ",", ".");

Возврат Число(Найденное);

КонецФункции

Шаблон \d+([.,]\d+)? находит целое или дробное число. Установка Global = Истина позволяет получить все совпадения и перебрать их в цикле — это самый компактный способ извлечь несколько чисел из одной строки.

Главное ограничение — кроссплатформенность. COM-объект существует только в Windows: на Linux-сервере и в веб-клиенте создание объекта вызовет ошибку. Поэтому вызов оборачивается в Попытка/Исключение, а для кроссплатформенных решений лучше использовать посимвольный разбор или выносить логику в общий модуль с серверным вызовом на Windows-узле.

Сравнение вариантов

Посимвольный перебор

Работает везде, включая веб-клиент и Linux. Подходит, когда число одно или нужно собрать все цифры. Медленнее на очень длинных строках.

СтрРазделить по разделителю

Лучший выбор при известной структуре строки (артикулы, коды, наименования с фиксированным форматом). Требует платформы 8.3.6+.

Регулярные выражения (COM)

Гибкие шаблоны, извлечение нескольких чисел, поиск по контексту. Только Windows, требует обработки недоступности COM.

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

Подходит, только если строка уже содержит чистое число без лишних символов. Любой посторонний символ даст исключение.

Проверка результата и обработка ошибок

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

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

Контрольные точки

Как проверить результат

Результат функции на строке без цифр
Норма

Возвращается 0 или Неопределено без исключения

Тревожный признак

Ошибка «Преобразование значения к типу Число не может быть выполнено»

Дробное число с запятой («12,5»)
Норма

Получено 12.5

Тревожный признак

Получено 125 или ошибка преобразования

Строка с несколькими числами
Норма

Извлечено именно нужное число по правилу выбора

Тревожный признак

Цифры склеились в одно большое число

Очень длинная последовательность цифр
Норма

Значение корректно или обработано ограничение разрядности

Тревожный признак

Потеря точности — тип Число в 1С ограничен 38 разрядами

Отдельно контролируйте ведущие нули. Число(«00456») вернёт 456 — если код с ведущими нулями используется для сравнения или поиска в базе, преобразование в число сломает логику. В таких случаях число нужно только для арифметики, а хранить и сравнивать — исходную строку.

Типичные ошибки и ограничения

Типичные ошибки
01
Вызов Число() без проверки — исключение на пустой строке или строке с буквами обрывает обработку данных.
02
Склейка всех цифр строки в одно число, когда в строке их несколько и нужно конкретное.
03
Забытая замена запятой на точку перед Число() — дробная часть теряется или возникает ошибка.
04
Использование VBScript.RegExp без Попытка/Исключение — код падает на Linux-сервере и в веб-клиенте.
05
Потеря ведущих нулей при преобразовании кодов и номеров в число — ломается поиск и сопоставление.
06
Неразрывные пробелы и символы валют из выгрузок сайтов не отфильтровываются простой проверкой на цифры и мешают преобразованию.

Частая ситуация — числа из Excel или веб-страниц содержат неразрывный пробел (код 160) как разделитель разрядов: «1 234 567». Фильтр цифр такую строку обработает корректно, а вот прямое Число() — нет. Перед преобразованием полезно выполнить СтрЗаменить(Строка, Символ(160), "") и удалить обычные пробелы.

Ещё одно ограничение — разрядность. Тип «Число» в 1С имеет максимальную точность 38 разрядов. Идентификаторы длиннее (например, длинные штрихкоды или внешние ключи) нельзя хранить как число без потери точности — их следует оставлять строками.

Итог

Что важно запомнить

Универсальное решение — посимвольный фильтр цифр с проверкой пустого результата. При известной структуре строки используйте СтрРазделить, при сложных шаблонах — RegExp с защитой от недоступности COM. Всегда заменяйте запятую на точку перед Число(), не превращайте в число коды с ведущими нулями и тестируйте функцию на реальных строках из ваших данных.

Частые вопросы

Как извлечь число из строки, если оно стоит в конце, после текста?

Идите по строке с конца: перебирайте символы от последнего к первому и собирайте цифры, пока не встретится нецифровой символ. Затем разверните полученную строку или собирайте результат вставкой в начало: Результат = Символ + Результат. Так вы получите именно последнее число, а не склейку всех цифр строки.

Что делать, если в строке несколько чисел и нужны все?

Используйте RegExp с шаблоном \d+([.,]\d+)? и флагом Global = Истина, затем переберите коллекцию совпадений и сложите преобразованные значения в массив. Без COM подойдёт разбор по пробелам с проверкой каждого фрагмента на «только цифры».

Почему Число("12,5") выдаёт ошибку, хотя в Excel это число?

Встроенная функция Число() понимает только точку как разделитель дробной части. Перед преобразованием выполните СтрЗаменить(Строка, ",", "."). Учтите, что при выводе числа в отчёт или строку форматирование снова будет зависеть от региональных настроек — используйте Формат() с явным указанием разделителя.

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

Напишите функцию-проверку: пройдите по символам и убедитесь, что каждый — цифра или единственный разделитель. Альтернатива — обернуть Число(Строка) в Попытка/Исключение и вернуть Ложь в ветке исключения. Второй вариант короче, но первый быстрее при массовой обработке.

Работает ли VBScript.RegExp на сервере под Linux?

Нет, COM-технология доступна только в Windows. На Linux создание объекта вызовет ошибку, поэтому вызов нужно оборачивать в Попытка/Исключение и предусматривать запасной алгоритм — посимвольный разбор, который работает на любой платформе и в любом клиенте.

Как извлечь число из номера документа с префиксом, например «00БП-001234»?

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