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

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

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

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

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

Чаще всего задача возникает при формировании номеров документов с ведущими нулями, при проверке длины ИНН, ОГРН, расчётных счетов, при выгрузке данных в фиксированные форматы (банковские файлы, EDI, обмен с кассами) и при валидации пользовательского ввода. Во всех этих случаях важно корректно обработать отрицательные числа, ноль и дробную часть — иначе функция вернёт неверный результат на граничных значениях.

Ниже разобраны рабочие варианты кода, их ограничения и способы проверки результата. Все примеры выполняются на встроенном языке 1С и подходят для управляемых и обычных форм, тонкого и толстого клиента.

Что понимать под разрядностью в контексте 1С

Прежде чем писать код, зафиксируйте, какой именно показатель нужен. В практике 1С под «разрядностью» понимают три разные вещи, и путаница между ними — главный источник ошибок.

Первый вариант — фактическое количество цифр в конкретном значении: у числа 457 разрядность равна 3, у числа 8 — единице. Второй вариант — количество знаков после запятой (точность), которое у числа 12,345 равно трём. Третий вариант — декларативные ограничения типа: у реквизита справочника может быть задана длина 15 и точность 2, и реальное значение внутри этих рамок может занимать меньше разрядов.

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

Определяем количество цифр целого числа через строку

Самый надёжный и универсальный приём — преобразовать число в строку без группировки разрядов и посчитать длину строки. Функция Формат с параметром ЧГ=0 отключает разделение групп (пробелы между тысячами), иначе эти пробелы исказят подсчёт.

Функция РазрядностьЦелого(Знач Число)

ЧислоПоМодулю = МодульЧисла(Число);

СтрокаЧисла = Формат(Цел(ЧислоПоМодулю), "ЧГ=0");

Возврат СтрДлина(СтрокаЧисла);

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

Здесь три важных приёма. Во-первых, берём модуль числа, чтобы минус у отрицательных значений не попал в подсчёт: для -457 функция вернёт 3, а не 4. Во-вторых, функция Цел() отсекает дробную часть, чтобы разделитель и знаки после запятой не влияли на результат. В-третьих, "ЧГ=0" гарантирует, что число 1234567 превратится в строку "1234567", а не "1 234 567".

Обратите внимание: для нуля функция вернёт 1, поскольку строковое представление нуля — "0". Это математически корректно, но если в вашей задаче ноль должен обрабатываться особо (например, считаться «пустым» значением), добавьте явную проверку перед вызовом.

bsl
Функция РазрядностьЦелого(Знач Число)
	СтрокаЧисла = Формат(Цел(?(Число < 0, -Число, Число)), "ЧГ=0");
	Возврат СтрДлина(СтрокаЧисла);
КонецФункции

Считаем знаки после запятой

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

Функция ТочностьЧисла(Знач Число)

СтрокаЧисла = Формат(Число, "ЧГ=0");

СтрокаЧисла = СтрЗаменить(СтрокаЧисла, ",", ".");

ПозицияТочки = СтрНайти(СтрокаЧисла, ".");

Если ПозицияТочки = 0 Тогда

Возврат 0;

КонецЕсли;

Возврат СтрДлина(СтрокаЧисла) - ПозицияТочки;

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

У этого метода есть тонкость: функция Формат по умолчанию может округлить значение, если задать ограничение разрядности в параметрах. Не указывайте ЧДЦ в строке формата, иначе получите точность форматирования, а не фактическую точность значения. Для числа 0,1 + 0,2 результат может содержать хвост двоичного округления вроде 0,30000000000000004 — это ограничение представления дробных чисел, а не ошибка функции.

Если нужна точность «как задумано бизнес-логикой», а не фактическая, часто правильнее оперировать квалификаторами типа реквизита — об этом ниже.

Узнаём длину и точность реквизита через метаданные

Когда задача — узнать, сколько разрядов допускает поле объекта конфигурации (например, для проверки перед записью или для генерации тестовых данных), обращаются к метаданным. У каждого реквизита типа «Число» есть описание типа с квалификаторами.

ОписаниеТипа = Метаданные.Документы.РеализацияТоваровУслуг

.Реквизиты.СуммаДокумента.Тип;

Квалификаторы = ОписаниеТипа.КвалификаторыЧисла;

Длина = Квалификаторы.Длина; // общее число знаков

Точность = Квалификаторы.Точность; // знаков после запятой

Длина в квалификаторах включает и целую, и дробную части: при длине 15 и точности 2 на целую часть остаётся 13 знаков. Знак минуса в длину не входит, но неотрицательность контролируется отдельным свойством ДопустимыйЗнак.

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

Альтернатива: подсчёт разрядов математически

Разрядность целого положительного числа можно найти без преобразования в строку — через десятичный логарифм или цикл деления на 10. Во встроенном языке 1С есть функция Log10, но из-за погрешностей вычислений с плавающей точкой результат требует аккуратного округления.

Функция РазрядностьЧерезЦикл(Знач Число)

Число = Цел(МодульЧисла(Число));

Если Число = 0 Тогда

Возврат 1;

КонецЕсли;

Разрядов = 0;

Пока Число > 0 Цикл

Число = Цел(Число / 10);

Разрядов = Разрядов + 1;

КонецЦикла;

Возврат Разрядов;

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

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

Сравнение способов

Строка + СтрДлина

Универсально, короткий код, работает с нулём и отрицательными числами. Требует параметра ЧГ=0, чтобы исключить разделители групп.

Цикл деления на 10

Не зависит от форматирования и локали, предсказуем на границах. Чуть длиннее код, медленнее при массовых вызовах.

Log10

Самый компактный для положительных чисел, но требует обработки нуля и погрешностей округления — легко получить ошибку на степенях десяти.

Метаданные

Единственный способ узнать ограничения поля, а не значение. Не подходит для подсчёта цифр конкретного числа.

Практический сценарий: дополнение номера нулями

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

Функция ДополнитьНулями(Знач Число, Знач ТребуемаяДлина)

СтрокаЧисла = Формат(Цел(Число), "ЧГ=0");

Пока СтрДлина(СтрокаЧисла) < ТребуемаяДлина Цикл

СтрокаЧисла = "0" + СтрокаЧисла;

КонецЦикла;

Возврат СтрокаЧисла;

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

Тот же результат даёт функция Формат с параметром ЧЦ: Формат(Число, "ЧЦ=8; ЧВН=; ЧГ=0") вернёт строку из восьми символов с ведущими нулями. Это короче и предпочтительнее ручного цикла. Ручной способ оправдан, только если логика дополнения сложнее — например, нужен не ноль, а другой символ-заполнитель.

Порядок действий при проверке длины значения
  1. 1
    Определите, что проверяете: фактическое число цифр значения или ограничение реквизита
  2. 2
    Для значения приведите число к строке через Формат с ЧГ=0 и возьмите СтрДлина
  3. 3
    Для отрицательных чисел предварительно возьмите модуль, для дробных — отсечьте дробную часть через Цел()
  4. 4
    Для ограничения поля прочитайте КвалификаторыЧисла через метаданные объекта
  5. 5
    Проверьте результат на граничных значениях: 0, 9, 10, -1, максимально допустимое число

Типичные ошибки и как их избежать

Первая ошибка — забыть параметр ЧГ=0. Строка "1 234 567" имеет длину 9 вместо 7, и все последующие проверки ломаются. Ошибка проявляется только на числах от тысячи и выше, поэтому на тестовых малых значениях её легко пропустить.

Вторая ошибка — не обработать знак минуса. Для -42 наивный подсчёт вернёт 3 вместо 2. Третья — поиск разделителя дробной части только по запятой: в англоязычных региональных настройках разделитель — точка, и функция СтрНайти не найдёт запятую, вернув нулевую точность для дробного числа.

Четвёртая ошибка — путать разрядность значения с длиной типа. Проверка «ИНН должен содержать 10 или 12 цифр» решается подсчётом цифр значения, а проверка «поместится ли сумма в реквизит» — чтением квалификаторов. Смешение этих задач приводит к ложным срабатываниям валидации.

Типичные ошибки
01
Формат без ЧГ=0 — пробелы-разделители тысяч завышают посчитанную длину
02
Подсчёт без модуля — минус у отрицательного числа считается лишним разрядом
03
Поиск только запятой — при точке как разделителе дробная часть не находится
04
Ограничение ЧДЦ в Формат — измеряется точность форматирования, а не значения
05
Проверка на нуле не прописана — поведение функции на нуле остаётся неявным

Проверка корректности функции

После написания функции прогоните её на эталонном наборе: 0 → 1 разряд, 5 → 1, 10 → 2, 99 → 2, 100 → 3, -7 → 1, -1000 → 4. Для точности: 1,5 → 1 знак, 0,25 → 2 знака, целое число → 0. Границы между степенями десяти (9/10, 99/100, 999/1000) — самые показательные места, где проявляются ошибки округления.

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

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

Число 1000
Норма

Функция возвращает 4

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

Возвращает 5 или 6 — в строку попали пробелы-разделители групп

Число -58
Норма

Функция возвращает 2

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

Возвращает 3 — не взят модуль числа

Число 3,14
Норма

Точность равна 2

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

Точность 0 — не найден разделитель, или длинный хвост — эффект двоичного представления

Число 0
Норма

Разрядность 1, точность 0

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

Ошибка выполнения или нулевая разрядность — не обработан особый случай

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

Ответы на частые вопросы

Итог

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

Разрядность значения считают через Формат с ЧГ=0 и СтрДлина, предварительно взяв модуль и отсечь дробную часть. Точность — через позицию разделителя в строке с заменой запятой на точку. Ограничения поля читают из КвалификаторыЧисла метаданных. Граничные значения 0, 9/10 и отрицательные числа проверяют обязательно.

Как определить разрядность числа в запросе 1С?

Прямой функции длины числа в языке запросов нет. Можно привести число к строке через ПОДСТРОКА и ВЫРАЗИТЬ, но такой подход громоздок и зависит от форматирования. Практичнее вычислить разрядность на встроенном языке до запроса и передать результат параметром, либо обработать выборку после выполнения запроса.

Почему СтрДлина возвращает больше, чем цифр в числе?

Чаще всего причина в разделителях групп разрядов: число 1234567 форматируется как «1 234 567» с пробелами. Добавьте параметр ЧГ=0 в функцию Формат. Вторая возможная причина — знак минуса у отрицательного числа: возьмите модуль перед преобразованием.

Как узнать максимальную длину числового реквизита документа?

Через метаданные: Метаданные.Документы.ИмяДокумента.Реквизиты.ИмяРеквизита.Тип.КвалификаторыЧисла.Длина. Свойство Точность покажет знаки после запятой. Учтите, что длина включает дробную часть: при длине 10 и точности 2 на целую часть остаётся 8 знаков.

Можно ли определить разрядность без преобразования в строку?

Да, циклом последовательного деления на 10 с подсчётом итераций или через десятичный логарифм Log10 с округлением вверх. Цикл надёжнее: логарифм на степенях десяти может дать ошибку из-за погрешности вычислений с плавающей точкой. Ноль в обоих способах обрабатывайте отдельно.

Как проверить, что ИНН содержит 10 или 12 цифр?

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

Чем отличается разрядность от точности в 1С?

Разрядность (в квалификаторах — длина) — общее количество знаков числа, включая целую и дробную части. Точность — только количество знаков после разделителя. У числа 1234,56 длина равна 6, точность равна 2, разрядность целой части равна 4.