При работе с числовыми данными в 1С часто возникает необходимость узнать разрядность дробной части числа (количество знаков после запятой). Разберем эту задачу подробно, так как она делится на два принципиально разных случая: вычисление реального количества знаков в произвольном числе и получение настроек квалификатора числа (свойства РазрядностьДробнойЧасти), заданного в конфигураторе.
Прежде чем мы приступим к написанию алгоритмов, рассмотрим важную особенность платформы 1С. Если у нас есть простая переменная с типом «Число», то получить доступ к ее «Квалификатору числа» напрямую через ТипЗнч() невозможно. Базовый примитивный тип не хранит информацию о максимальной длине и точности, эти данные существуют только в привязке к объектам (реквизитам метаданных, элементам формы, колонкам таблиц).
Также стоит помнить, что базовый тип «Число» в 1С не хранит незначащие нули в конце. Для системы числа 0.120 и 0.12 абсолютно идентичны. Если вам нужно узнать именно количество введенных пользователем символов (включая нули на конце), перехватывать это значение необходимо на уровне интерфейса в виде строки, до преобразования текста в число.
Проанализируем несколько способов вычисления реального количества знаков после запятой. На форумах часто предлагают математические циклы (умножение на 10, пока число не станет целым), но в 1С их применять не рекомендуется из-за особенностей бинарного представления чисел с плавающей точкой — это может привести к бесконечному циклу из-за микропогрешностей.
Рассмотрим безопасные строково-математические подходы:
КоличествоРазрядов = Макс(СтрДлина(МоеЧисло) - СтрДлина(Цел(МоеЧисло)) - 1, 0);
%1 позволяет получить дробную часть числа. Чтобы корректно обработать отрицательные числа, возьмем модуль числа с помощью функции Макс().
КоличествоРазрядов = Макс(СтрДлина(Макс(МоеЧисло, -МоеЧисло) % 1) - 2, 0);
Здесь мы вычитаем 2, так как дробная часть всегда начинается с «0» и разделителя («0,»).
Обычное преобразование в строку или функция Формат() сильно зависят от региональных настроек компьютера. Кроме того, при очень маленьких числах платформа может применить экспоненциальную запись (например, 1.2E-4), что сломает простые алгоритмы поиска запятой. Разберем наиболее универсальный метод с использованием функции XMLСтрока().
Функция XMLСтрока(ВашеЧисло) всегда использует точку в качестве разделителя дроби и никогда не добавляет пробелы между тысячами. Посмотрим на пример кода:
СтрокаЧисла = XMLСтрока(МоеЧисло);
ПозицияТочки = СтрНайти(СтрокаЧисла, ".");
Если ПозицияТочки > 0 Тогда
Разрядность = СтрДлина(СтрокаЧисла) - ПозицияТочки;
Иначе
Разрядность = 0; // Число целое
КонецЕсли;
Если же ваша цель — узнать максимальную разрядность, заданную для реквизита конфигурации или элемента формы, то сделать это можно программным путем, обратившись к свойству РазрядностьДробнойЧасти объекта КвалификаторыЧисла.
Посмотрим, как получить эту информацию в разных ситуациях:
Разрядность = Метаданные.Справочники[ИмяСправочника].Реквизиты[ИмяРеквизита].Тип.КвалификаторыЧисла.РазрядностьДробнойЧасти;
ПолучитьРеквизиты(), чтобы получить описание типов.
МассивРеквизитов = ЭтаФорма.ПолучитьРеквизиты();
Для Каждого Реквизит Из МассивРеквизитов Цикл
Если Реквизит.Имя = "МойРеквизит" Тогда
Разрядность = Реквизит.ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
КонецЕсли;
КонецЦикла;
Разрядность = ТаблицаЗначений.Колонки["ИмяКолонки"].ТипЗначения.КвалификаторыЧисла.РазрядностьДробнойЧасти;
Таким образом, мы выяснили, что для получения реального числа знаков после запятой лучше всего использовать работу со строками (в идеале — XMLСтрока), а для получения установленных лимитов необходимо обращаться к описанию типов через метаданные или свойства элементов формы.