При работе в 1С программисты часто сталкиваются с ситуацией, когда стандартное преобразование числа в строку функцией Строка() выдает результат с разделителями групп разрядов (неразрывными пробелами). Например, число 2222 превращается в "2 222", и функция СтрДлина() возвращает 5 вместо ожидаемых 4. Ситуация усложняется, когда нужно посчитать количество знаков в дробной части или обработать отрицательные значения. В этой статье мы подробно разберем, как получить «чистую» длину числа, используя различные методы платформы 1С.
Самый правильный и надежный способ управления строковым представлением числа в 1С — это использование функции Формат(). По умолчанию система добавляет разделители групп разрядов (пробел или неразрывный пробел) для удобства чтения пользователем, но для программной обработки это мешает. Чтобы подавить это поведение, мы используем параметр ЧГ=0 (Число Группировок = 0).
Рассмотрим пример кода, который решает базовую задачу автора:
// Стандартный подход, убирающий разделители групп разрядов
ЧислоДляОбработки = 2222;
СтрокаБезПробелов = Формат(ЧислоДляОбработки, "ЧГ=0");
Длина = СтрДлина(СтрокаБезПробелов); // Результат будет 4
Проанализируем параметры форматной строки:
Иногда разработчики пытаются использовать СтрЗаменить(). Важно понимать, что 1С использует не обычный пробел (код 32), а неразрывный пробел (NBSP, код 160). В современных версиях платформы также может встречаться узкий неразрывный пробел (код 8239). Простая замена кавычек с пробелом " " может не сработать.
Разберем, как сделать это правильно, если вы все же решили идти по пути замены символов:
ЧислоСтрокой = Строка(2222);
// Заменяем стандартный неразрывный пробел платформы
ЧислоСтрокой = СтрЗаменить(ЧислоСтрокой, Символы.НПП, "");
Длина = СтрДлина(ЧислоСтрокой);
Однако помните, что функция Формат() из первого метода гораздо эффективнее и читабельнее.
Вопрос становится интереснее, когда нужно посчитать длину только дробной части или длину числа без ведущего нуля (например, для 0,222 получить длину 3). Выясним причину, почему стандартные методы здесь пасуют: 1С всегда форматирует дробные числа с разделителем (запятая или точка) и ведущим нулем.
Посмотрим на пример обработки дробного числа, чтобы посчитать значащие цифры после запятой:
НужноеЧисло = 0.222;
// Преобразуем в строку без групп, заменяем 0 и запятую на пустоту
ЧислоСтрокой = Формат(НужноеЧисло, "ЧГ=0; ЧРД=,");
ЧислоСтрокой = СтрЗаменить(ЧислоСтрокой, "0,", "");
Длина = СтрДлина(ЧислоСтрокой); // Результат: 3
Если задача стоит более комплексно (учитывать и целую, и дробную части, но без служебных символов), проанализируем следующий алгоритм:
Функция ПолучитьЧистуюДлину(Знач ВхЧисло)
// Убираем минус, разделители групп и разделитель дробной части
СтрокаЦифр = Формат(ВхЧисло, "ЧГ=0; ЧН=0");
СтрокаЦифр = СтрЗаменить(СтрокаЦифр, "-", "");
СтрокаЦифр = СтрЗаменить(СтрокаЦифр, ",", "");
СтрокаЦифр = СтрЗаменить(СтрокаЦифр, ".", "");
// Если нужно убрать ведущие нули для дробных чисел меньше 1
Если Абс(ВхЧисло) < 1 Тогда
Пока Лев(СтрокаЦифр, 1) = "0" Цикл
СтрокаЦифр = Сред(СтрокаЦифр, 2);
КонецЦикла;
КонецЕсли;
Возврат СтрДлина(СтрокаЦифр);
КонецФункции
Для любителей математических решений можно использовать десятичный логарифм. Это позволяет определить количество разрядов целого числа без преобразования в строку. Выясним, как это работает: целая часть десятичного логарифма числа плюс один дает количество его знаков.
Число = 2222;
Если Число <> 0 Тогда
Длина = Цел(Log10(Абс(Число))) + 1;
Иначе
Длина = 1;
КонецЕсли;
Важное ограничение: этот метод хорошо работает только для целых чисел. Для дробных чисел логарифм не покажет количество знаков после запятой напрямую без дополнительных манипуляций (умножения на 10 в степени точности).
Существует еще один "хитрый" способ получить число в каноническом виде, который часто используют опытные разработчики. Функция XMLСтрока() преобразует значение в формат XML, где нет разделителей групп разрядов, а в качестве разделителя дробной части всегда используется точка. Это избавляет от зависимости от региональных настроек пользователя.
Число = 2222.45;
ЧистаяСтрока = XMLСтрока(Число); // Получим "2222.45"
// Теперь достаточно убрать точку и минус
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, ".", "");
ЧистаяСтрока = СтрЗаменить(ЧистаяСтрока, "-", "");
Длина = СтрДлина(ЧистаяСтрока);
Если вы работаете на платформе 8.3.10 и выше, мы можем применить современные функции работы со строками СтрРазделить() и СтрСоединить(). Это позволит нам эффективно "отфильтровать" только цифры из любого строкового представления числа.
Разберем по шагам:
ТвоеЧисло = -2 222.78;
СтрокаСМусором = Строка(ТвоеЧисло);
// Указываем все возможные разделители
МассивЧастей = СтрРазделить(СтрокаСМусором, " ,.-" + Символы.НПП, Ложь);
ТолькоЦифры = СтрСоединить(МассивЧастей, "");
Длина = СтрДлина(ТолькоЦифры); // Получим 6
Проанализировав все способы, можно сделать следующие выводы:
Формат(Число, "ЧГ=0").СтрЗаменить после форматирования или логику с Сред().Абс() (модуль числа) перед расчетами, чтобы знак "минус" не увеличивал длину.XMLСтрока является самым стабильным, так как не зависит от того, какие настройки разделителей стоят в операционной системе пользователя (Windows, Linux или macOS).Выбирайте метод в зависимости от ваших требований к производительности и того, какие именно знаки числа вы считаете "значащими".