При переходе с платформы 1С:Предприятие 7.7 на версию 8.x многие разработчики сталкиваются с тем, что привычная функция Число() ведет себя гораздо строже. Если в «семерке» пустая строка или строка с текстом просто превращалась в ноль, то в современных версиях 1С это приводит к фатальной ошибке: «Преобразование значения к типу Число не может быть выполнено». В этой статье мы подробно разберем, почему так происходит, и рассмотрим все способы сделать код надежным.
Проанализируем логику работы платформы. В 1С 8.3 реализована строгая типизация при явном преобразовании. Функция Число() ожидает, что переданная ей строка является «числом в чистом виде». Если в строке встречается хотя бы один лишний символ (пробел, неразрывный пробел, буква) или если строка пустая — система не берет на себя ответственность за интерпретацию этих данных и останавливает выполнение программы.
Рассмотрим стандартный неудачный пример:
// Это вызовет ошибку, если Параметр = "" или " "
Результат = Число(Параметр);
Самый быстрый и часто используемый способ — добавить «0» перед строкой. Это позволяет избежать ошибки при передаче пустой строки, так как Число("0") корректно вернет ноль. Однако здесь есть важный нюанс: если в строке есть пробелы, этот метод все равно может дать сбой.
Разберем правильную реализацию с очисткой пробелов:
// Используем СокрЛП для удаления пробелов по краям
ЗначениеДляПреобразования = СокрЛП(Параметр);
Результат = Число("0" + ЗначениеДляПреобразования);
Важный момент: если Параметр уже является числом, а не строкой, конкатенация "0" + Параметр может привести к неожиданным результатам, так как число преобразуется в строку с разделителями. Поэтому всегда проверяйте тип данных.
Профессиональный подход к решению задачи заключается в использовании метода ПривестиЗначение() объекта ОписаниеТипов. Его главное преимущество в том, что он никогда не вызывает исключение. Если данные невозможно преобразовать в число, метод просто вернет значение по умолчанию для этого типа (для числа это 0).
Рассмотрим, как это реализовать в коде:
// Создаем описание типа "Число"
ОписаниеТипаЧисло = Новый ОписаниеТипов("Число");
// Метод вернет 0, если передать пустую строку, массив или "мусор"
Результат = ОписаниеТипаЧисло.ПривестиЗначение(Параметр);
Этот метод идеально подходит для массовой обработки данных, где важна скорость работы и отсутствие прерываний из-за некорректных входных значений.
Часто данные приходят из Excel или внешних систем через XML/JSON. В таких строках число может выглядеть как "1 500", но обычный пробел там на самом деле является неразрывным пробелом (символ с кодом 160). Функция СокрЛП() его не удаляет.
Проанализируем ситуацию, когда стандартные методы не помогают. Нам нужно принудительно удалить все специфические символы разделителей:
ЧистаяСтрока = СокрЛП(Параметр);
// Удаляем неразрывный пробел (код 160)
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, Символы.НПП, "");
// На всякий случай удаляем обычный пробел
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, " ", "");
// Преобразуем
Результат = Число("0" + ЧистаяСтрока);
Если вы работаете с дробными числами, помните о региональных настройках. В одном сеансе разделителем может быть точка, в другом — запятая. Выясним, какой разделитель используется, и приведем строку к нужному виду:
// Заменяем точку на запятую для русской локали
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, ".", ",");
Результат = Число(ЧистаяСтрока);
Если ваша задача — получить строку из числа без группировки разрядов (чтобы вместо "1 234" получить "1234"), используйте функцию Формат(). Это часто требуется при формировании артикулов или номеров документов.
Посмотрим на пример:
ЧисловоеЗначение = 2023;
// Параметр "ЧГ=0" отключает группировку разрядов
СтрокаБезПробелов = Формат(ЧисловоеЗначение, "ЧГ=0");
// Результат: "2023"
Когда данных много и они приходят из крайне «грязных» источников, проще всего использовать конструкцию Попытка...Исключение. Это позволит программе продолжить работу, даже если конкретное значение совсем не похоже на число.
Рассмотрим пример:
Результат = 0;
Попытка
Результат = Число(СокрЛП(Параметр));
Исключение
// Сюда попадем, если в строке буквы или она пустая
Результат = 0;
Сообщить("Не удалось преобразовать значение: " + Параметр);
КонецПопытки;
Для повседневной работы программиста полезно иметь в общем модуле функцию, которая оставляет в строке только цифры. Проанализируем пример такой функции:
Функция ТолькоЦифрыВЧисло(Знач ВходнаяСтрока) Экспорт
// Оставляем только то, что может относиться к числу
РазрешенныеСимволы = "0123456789.,-";
РезультатСтрокой = "";
Для Позиция = 1 По СтрДлина(ВходнаяСтрока) Цикл
Символ = Сред(ВходнаяСтрока, Позиция, 1);
Если Найти(РазрешенныеСимволы, Символ) > 0 Тогда
РезультатСтрокой = РезультатСтрокой + Символ;
КонецЕсли;
КонецЦикла;
Возврат Число("0" + СтрЗаменить(РезультатСтрокой, ".", ","));
КонецФункции
Подведем итог:
Число("0" + СокрЛП(Стр)).ОписаниеТипов.Символы.НПП (код 160)."ЧГ=0".Используя эти методы, вы обезопасите свои алгоритмы от неожиданных остановок и сделаете код более устойчивым к ошибкам пользовательского ввода.