При переходе с платформы 1С 7.7 на 1С 8.х многие разработчики сталкиваются с изменением поведения базовых функций. Одной из таких функций является Число(). Если в «семерке» вызов Число("21xx") без проблем возвращал 21, то в «восьмерке» аналогичный код вызовет ошибку выполнения. Это связано с изменением философии платформы: теперь типизация стала более строгой для минимизации скрытых ошибок в данных.
В этой статье мы разберем несколько способов, как получить число из строки, если в её конце могут присутствовать произвольные нецифровые символы.
Проанализируем ситуацию: в 1С 7.7 функция Число() работала по принципу чтения слева направо до первого недопустимого символа. В 1С 8.х подход изменился. Теперь строка должна полностью соответствовать формату числа (допускаются только пробелы-разделители, десятичный знак и минус в начале). Любой посторонний символ, будь то буква или спецсимвол в конце строки, приводит к исключению. Это сделано для того, чтобы программист точно контролировал процесс преобразования и не получал неверные данные в расчетах.
Рассмотрим самый надежный способ, который работает на любой версии платформы 1С 8. Суть метода заключается в проходе по строке слева направо и поиске первого символа, который не является цифрой. Как только такой символ найден, мы отсекаем правую часть строки и преобразуем остаток.
Разберем пример кода:
// Исходная строка, например, "21abc"
ТвояСтрока = "21xx";
ИскомоеЧисло = 0;
Для К = 1 По СтрДлина(ТвояСтрока) Цикл
// Проверяем, входит ли текущий символ в набор цифр
Если СтрНайти("0123456789", Сред(ТвояСтрока, К, 1)) = 0 Тогда
// Нашли первую букву — прерываем цикл
Прервать;
КонецЕсли;
КонецЦикла;
// Отсекаем всё, что правее найденного индекса (К-1)
СтрокаСЦифрами = Лев(ТвояСтрока, К - 1);
Если ЗначениеЗаполнено(СтрокаСЦифрами) Тогда
ИскомоеЧисло = Число(СтрокаСЦифрами);
КонецЕсли;
Сообщить(ИскомоеЧисло); // Результат: 21
Преимущества: метод работает быстро, не требует наличия БСП и стабилен на старых версиях платформы.
Начиная с версии платформы 1С 8.3.15, в языке появились встроенные функции для работы с регулярными выражениями. Это позволяет решить задачу буквально в одну-две строки. Мы можем использовать функцию СтрЗаменитьПоРегулярномуВыражению, чтобы оставить только цифры в начале строки.
Посмотрим на пример реализации:
ИсходнаяСтрока = "21xx";
// Регулярное выражение: ^(\d+) означает "найти группу цифр в начале строки"
// .* означает "все остальные символы после них"
Шаблон = "^(\d+).*";
РезультатСтрокой = СтрЗаменитьПоРегулярномуВыражению(ИсходнаяСтрока, Шаблон, "$1");
Попытка
ИскомоеЧисло = Число(РезультатСтрокой);
Исключение
ИскомоеЧисло = 0;
КонецПопытки;
Если ваша платформа ниже 8.3.15, можно воспользоваться объектом VBScript.RegExp через COMОбъект, однако это будет работать только под управлением ОС Windows.
Если ваша конфигурация построена на базе БСП, можно попытаться использовать готовые инструменты. Однако здесь есть важный нюанс. Функция СтроковыеФункцииКлиентСервер.ТолькоЦифры() удаляет все нецифровые символы из строки, где бы они ни находились.
Проанализируем пример:
"21xx" — функция вернет "21". Это нам подходит."21xx3" — функция вернет "213". Это может нарушить логику, если вам нужны только начальные цифры.Поэтому используйте функции БСП осторожно, только если уверены, что цифр в середине или конце «хвоста» быть не может.
Существует еще один подход, который иногда называют методом итерационного сокращения. Мы пытаемся преобразовать всю строку целиком, и если получаем ошибку — отрезаем один символ справа и пробуем снова.
Функция ИзвлечьЧислоИзНачалаСтроки(Знач ВходнаяСтрока)
Пока СтрДлина(ВходнаяСтрока) > 0 Цикл
Попытка
Возврат Число(ВходнаяСтрока);
Исключение
// Если ошибка, отрезаем один символ справа
ВходнаяСтрока = Лев(ВходнаяСтрока, СтрДлина(ВходнаяСтрока) - 1);
КонецПопытки;
КонецЦикла;
Возврат 0;
КонецФункции
Этот метод менее производителен, чем поиск через СтрНайти, но он полезен, если в строке могут быть допустимые для числа символы (например, точка или запятая), которые вы хотите сохранить.
При получении данных из внешних источников (Excel, текстовые файлы, веб-сервисы), выясним одну частую причину ошибок. В строке могут содержаться невидимые символы, такие как неразрывный пробел (код 160). Визуально строка выглядит как "21", но Число() выдает ошибку.
Перед любым преобразованием рекомендуем выполнять очистку:
СокрЛП() для удаления обычных пробелов по краям.СтрЗаменить(Строка, Символы.НПП, "").Подводя итог, отметим: наиболее «красивым» и быстрым решением для современной платформы является использование регулярных выражений. Если же важна совместимость со старыми релизами 8.1 или 8.2 — используйте цикл с проверкой каждого символа, так как он гарантирует предсказуемый результат без лишних затрат ресурсов.