Разработка и Конфигурация · 11 мин
Как разделить число на цифры в 1С
Как разбить число на отдельные цифры в 1С: преобразование в строку, цикл с остатком от деления, работа с разрядами. Готовые примеры кода и типичные ошибки.
Задача разделить число на отдельные цифры в 1С возникает чаще, чем кажется: при формировании кассовых документов с суммой по разрядам, при печати бланков с ячейками под каждую цифру, при обмене данными с оборудованием, которое принимает значения посимвольно. Встроенной функции «разбить число на цифры» во встроенном языке нет, поэтому задачу решают двумя рабочими подходами — через строку и через арифметику.
Первый подход — преобразовать число в строку и перебрать символы. Второй — последовательно делить число на 10 и брать остаток от деления. Оба способа дают одинаковый результат для целых чисел, но отличаются по поведению с дробной частью, отрицательными значениями и пробелами-разделителями групп разрядов.
Ниже разобраны оба метода с готовыми функциями, которые можно перенести в общий модуль, а также нюансы форматирования, проверки результата и типичные ошибки, из-за которых вместо «1234» получается «1 234» или «1,23E+3».
Как разбить число на цифры через преобразование в строку
Самый читаемый способ — привести число к строке и пройтись по символам функцией Сред(). Длина строки определяется функцией СтрДлина(), каждый символ извлекается по позиции и при необходимости преобразуется обратно в число.
Функция РазбитьЧислоНаЦифры(Число) Экспорт
Цифры = Новый Массив;
СтрокаЧисла = Формат(Число, "ЧГ=0");
Для Позиция = 1 По СтрДлина(СтрокаЧисла) Цикл
Символ = Сред(СтрокаЧисла, Позиция, 1);
Цифры.Добавить(Число(Символ));
КонецЦикла;
Возврат Цифры;
КонецФункции
Ключевой момент здесь — параметр "ЧГ=0" в функции Формат(). Он отключает группировку разрядов, иначе число 1234567 превратится в строку «1 234 567», и пробелы попадут в массив цифр. При вызове Число(" ") платформа вернёт 0 без ошибки, и вы получите лишние нули в середине результата — такую ошибку трудно заметить на маленьких числах.
Если число гарантированно целое и небольшое, можно обойтись и без Формат() — просто Строка(Число). Но функция Строка() для больших чисел может вернуть значение в экспоненциальной записи вида «1,23E+15», поэтому для универсальной функции формат с явными параметрами надёжнее.
Как получить цифры арифметически через остаток от деления
Второй метод не трогает строки вовсе. Цифры извлекаются оператором остатка от деления %: Число % 10 даёт последнюю цифру, после чего число целочисленно делится на 10. Цикл повторяется, пока число не станет равным нулю.
Функция ЦифрыЧислаАрифметически(Знач Число) Экспорт
Цифры = Новый Массив;
Число = Цел(Число);
Если Число = 0 Тогда
Цифры.Добавить(0);
Возврат Цифры;
КонецЕсли;
Пока Число > 0 Цикл
Цифры.Вставить(0, Число % 10);
Число = Цел(Число / 10);
КонецЦикла;
Возврат Цифры;
КонецФункции
Обратите внимание на Цифры.Вставить(0, ...): остаток от деления даёт цифры справа налево, поэтому каждая новая цифра вставляется в начало массива, чтобы итоговый порядок совпал с записью числа. Отдельная ветка для нуля обязательна — без неё цикл не выполнится ни разу и функция вернёт пустой массив.
Арифметический вариант удобен, когда нужно не просто получить цифры, а работать с разрядами как с величинами: например, вычислить контрольную сумму, проверить чётность разряда или собрать число обратно. Он также не зависит от региональных настроек форматирования, что важно в серверных процедурах, выполняемых под разными пользователями.
Число = 1234;
Пока Число > 0 Цикл
Сообщить(Число % 10); // выведет 4, 3, 2, 1
Число = Цел(Число / 10);
КонецЦикла;Как обработать дробную часть и отрицательные числа
Оба базовых метода предполагают целое неотрицательное число. Реальные данные — суммы документов, цены, количества — часто содержат копейки и знак минус, поэтому функцию стоит дополнить предобработкой.
Числа с копейками
Если нужно разбить сумму с копейками, типичное решение — умножить число на 100 и округлить, получив целое число копеек. Например, 1234,56 превращается в 123456, после чего разбивается любым из способов. Альтернатива — разделить целую и дробную части отдельно: Цел(Сумма) для рублей и Окр((Сумма - Цел(Сумма)) * 100, 0) для копеек.
Отрицательные значения
При преобразовании в строку минус станет первым символом и сломает вызов Число(Символ). В арифметическом методе условие Число > 0 просто не запустит цикл. Универсальное решение — в начале функции взять модуль: Число = Макс(Число, -Число), а знак при необходимости сохранить в отдельную переменную до разбора.
Как выбрать способ разбора
Как вывести цифры в ячейки табличного документа
Самый частый прикладной сценарий — печатная форма, где каждая цифра суммы или номера должна попасть в свою ячейку: квитанции, бланки строгой отчётности, поля машиночитаемых форм. Здесь строковый метод работает напрямую с областями табличного документа.
СтрокаСуммы = Формат(СуммаДокумента, "ЧГ=0; ЧДЦ=2; ЧРД=.");
СтрокаСуммы = СтрЗаменить(СтрокаСуммы, ".", "");
Для Позиция = 1 По СтрДлина(СтрокаСуммы) Цикл
ИмяОбласти = "Цифра" + Позиция;
Область = ТабДок.Области.Найти(ИмяОбласти);
Если Область <> Неопределено Тогда
Область.Текст = Сред(СтрокаСуммы, Позиция, 1);
КонецЕсли;
КонецЦикла;
Обратите внимание на выравнивание: если количество ячеек в макете фиксировано, а число короче, строку нужно дополнить ведущими пробелами или нулями слева. Для этого удобно вычислить смещение: Смещение = КоличествоЯчеек - СтрДлина(СтрокаСуммы) и начинать заполнение с позиции Смещение + 1. Иначе сумма «прилипнет» к левому краю бланка вместо правого.
Сравнение способов и их ограничения
Выбор между строковым и арифметическим методом зависит от контекста. Ниже — сопоставление по практическим критериям.
| Критерий | Строковый метод | Арифметический метод |
|---|---|---|
| Читаемость кода | Высокая, легко сопровождать | Требует понимания целочисленного деления |
| Зависимость от формата | Есть, нужен контроль ЧГ и ЧДЦ | Нет, работает с числом напрямую |
| Дробная часть | Требует замены разделителя | Отсекается функцией Цел() |
| Отрицательные числа | Минус попадает в строку | Цикл не выполнится, нужен модуль |
| Типичное применение | Печатные формы, посимвольный вывод | Расчёты, контрольные суммы, разряды |
Оба метода имеют общее ограничение: точность типа «Число» в 1С ограничена (максимум 38 знаков, из них не более 32 в целой части в типичных конфигурациях). Для очень длинных последовательностей цифр — например, штрихкодов или номеров карт — исходное значение лучше хранить и обрабатывать как строку с самого начала, не превращая его в число.
Как проверить корректность результата
После написания функции её стоит прогнать на наборе граничных значений до переноса в рабочую базу. Удобнее всего сделать это во внешней обработке или через консоль кода с выводом в окно сообщений.
Минимальный проверочный набор: 0 (должен дать массив из одного нуля), однозначное число, число с нулями внутри (например, 1002 — здесь легко потерять нули при неаккуратной обработке), большое число с разделителями по умолчанию (1000000), отрицательное число и сумма с копейками. Для каждого случая сверьте и количество элементов массива, и их значения, и порядок.
Дополнительная самопроверка — собрать число обратно из массива цифр и сравнить с исходным. Если функция разбора и функция сборки независимы, такой «кольцевой» тест надёжно выявляет потерю разрядов и перестановки.
Как проверить результат
Массив из 4 элементов: 1, 0, 0, 2
Нули потеряны или заменены пробелами
Строка без пробелов, 7 цифр
Строка "1 000 000", в массиве лишние элементы
Собранное значение равно исходному
Значение перевёрнуто или отличается — ошибка в порядке вставки
Массив содержит один элемент 0
Пустой массив — пропущена ветка для нуля
Частые вопросы
Как разбить число на цифры без массива, сразу в цикле?
Используйте арифметический вариант: внутри цикла Пока Число > 0 выражение Число % 10 сразу даёт очередную цифру (справа налево), которую можно обработать на месте — вывести, просуммировать или записать в таблицу значений. Промежуточный массив не нужен.
Почему вместо цифр получаются пробелы или буква E?
Это следствие форматирования по умолчанию: платформа группирует разряды пробелами, а для больших чисел может использовать экспоненциальную запись. Решение — явный формат: Формат(Число, "ЧГ=0") отключает группировку, а добавление "ЧДЦ=0" отсекает дробную часть.
Как разбить сумму на рубли и копейки отдельными цифрами?
Разделите значение на две части: Цел(Сумма) — рубли, Окр((Сумма - Цел(Сумма)) * 100, 0) — копейки. Каждую часть разбивайте на цифры отдельно, копейки при необходимости дополните ведущим нулём до двух знаков.
Можно ли разбить число на разряды (тысячи, миллионы), а не на цифры?
Да, используйте деление на степень десяти: Цел(Число / 1000) % 1000 даст группу тысяч, Цел(Число / 1000000) % 1000 — миллионов. Это удобно для сумм прописью, где число обрабатывается тройками разрядов.
Где разместить функцию разбора, чтобы использовать её в нескольких местах?
Оптимально — в общем модуле с признаком «Сервер» (и «Вызов сервера», если функция нужна на клиенте). Объявите функцию с ключевым словом Экспорт, тогда она будет доступна из модулей документов, отчётов и печатных форм.
Что делать, если исходное значение — строка с цифрами, а не число?
Тогда преобразование в число не требуется вовсе: сразу перебирайте символы через Сред() и при необходимости переводите каждый в число функцией Число(). Так безопаснее работать с длинными номерами, кодами и штрихкодами, где числовой тип теряет ведущие нули.
Что важно запомнить
Число на цифры в 1С разбивают либо через строку (Формат с ЧГ=0 и перебор Сред()), либо арифметически (цикл с остатком от деления на 10). Перед разбором уберите разделители групп, обработайте ноль, минус и дробную часть, а результат проверьте обратной сборкой числа.