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

Разработка и Конфигурация · 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, ...): остаток от деления даёт цифры справа налево, поэтому каждая новая цифра вставляется в начало массива, чтобы итоговый порядок совпал с записью числа. Отдельная ветка для нуля обязательна — без неё цикл не выполнится ни разу и функция вернёт пустой массив.

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

1c
Число = 1234;
Пока Число > 0 Цикл
    Сообщить(Число % 10); // выведет 4, 3, 2, 1
    Число = Цел(Число / 10);
КонецЦикла;

Как обработать дробную часть и отрицательные числа

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

Числа с копейками

Если нужно разбить сумму с копейками, типичное решение — умножить число на 100 и округлить, получив целое число копеек. Например, 1234,56 превращается в 123456, после чего разбивается любым из способов. Альтернатива — разделить целую и дробную части отдельно: Цел(Сумма) для рублей и Окр((Сумма - Цел(Сумма)) * 100, 0) для копеек.

Отрицательные значения

При преобразовании в строку минус станет первым символом и сломает вызов Число(Символ). В арифметическом методе условие Число > 0 просто не запустит цикл. Универсальное решение — в начале функции взять модуль: Число = Макс(Число, -Число), а знак при необходимости сохранить в отдельную переменную до разбора.

Маршрут решения

Как выбрать способ разбора

Нужны цифры для вывода в печатную форму или ячейки бланкаИспользуйте строковый метод с Формат(Число, "ЧГ=0") и Сред()
Нужны вычисления с разрядами: контрольные суммы, проверки, сборка числаИспользуйте арифметический цикл с остатком от деления на 10
Число содержит дробную часть (сумма с копейками)Сначала умножьте на 100 и округлите, затем разбивайте как целое
Число может быть отрицательнымВозьмите модуль перед разбором и обработайте знак отдельно

Как вывести цифры в ячейки табличного документа

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

СтрокаСуммы = Формат(СуммаДокумента, "ЧГ=0; ЧДЦ=2; ЧРД=.");

СтрокаСуммы = СтрЗаменить(СтрокаСуммы, ".", "");

Для Позиция = 1 По СтрДлина(СтрокаСуммы) Цикл

ИмяОбласти = "Цифра" + Позиция;

Область = ТабДок.Области.Найти(ИмяОбласти);

Если Область <> Неопределено Тогда

Область.Текст = Сред(СтрокаСуммы, Позиция, 1);

КонецЕсли;

КонецЦикла;

Обратите внимание на выравнивание: если количество ячеек в макете фиксировано, а число короче, строку нужно дополнить ведущими пробелами или нулями слева. Для этого удобно вычислить смещение: Смещение = КоличествоЯчеек - СтрДлина(СтрокаСуммы) и начинать заполнение с позиции Смещение + 1. Иначе сумма «прилипнет» к левому краю бланка вместо правого.

Сравнение способов и их ограничения

Выбор между строковым и арифметическим методом зависит от контекста. Ниже — сопоставление по практическим критериям.

КритерийСтроковый методАрифметический метод
Читаемость кодаВысокая, легко сопровождатьТребует понимания целочисленного деления
Зависимость от форматаЕсть, нужен контроль ЧГ и ЧДЦНет, работает с числом напрямую
Дробная частьТребует замены разделителяОтсекается функцией Цел()
Отрицательные числаМинус попадает в строкуЦикл не выполнится, нужен модуль
Типичное применениеПечатные формы, посимвольный выводРасчёты, контрольные суммы, разряды

Оба метода имеют общее ограничение: точность типа «Число» в 1С ограничена (максимум 38 знаков, из них не более 32 в целой части в типичных конфигурациях). Для очень длинных последовательностей цифр — например, штрихкодов или номеров карт — исходное значение лучше хранить и обрабатывать как строку с самого начала, не превращая его в число.

Типичные ошибки
01
Использование Строка(Число) без Формат(): в результат попадают пробелы-разделители или экспоненциальная запись, и массив цифр искажается
02
Отсутствие ветки для нуля в арифметическом методе: цикл не выполняется, функция возвращает пустой массив
03
Забытый СтрЗаменить() для десятичного разделителя: запятая или точка превращается в лишний элемент массива
04
Прямое обращение к области макета без проверки на Неопределено: ошибка исполнения при печати документа
05
Добавление цифр в конец массива при арифметическом разборе: порядок цифр получается перевёрнутым

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

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

Минимальный проверочный набор: 0 (должен дать массив из одного нуля), однозначное число, число с нулями внутри (например, 1002 — здесь легко потерять нули при неаккуратной обработке), большое число с разделителями по умолчанию (1000000), отрицательное число и сумма с копейками. Для каждого случая сверьте и количество элементов массива, и их значения, и порядок.

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

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

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

Число 1002 после разбора
Норма

Массив из 4 элементов: 1, 0, 0, 2

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

Нули потеряны или заменены пробелами

Число 1000000 без параметра ЧГ=0
Норма

Строка без пробелов, 7 цифр

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

Строка "1 000 000", в массиве лишние элементы

Сборка числа обратно из массива
Норма

Собранное значение равно исходному

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

Значение перевёрнуто или отличается — ошибка в порядке вставки

Нулевое исходное число
Норма

Массив содержит один элемент 0

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

Пустой массив — пропущена ветка для нуля

Частые вопросы

Как разбить число на цифры без массива, сразу в цикле?

Используйте арифметический вариант: внутри цикла Пока Число > 0 выражение Число % 10 сразу даёт очередную цифру (справа налево), которую можно обработать на месте — вывести, просуммировать или записать в таблицу значений. Промежуточный массив не нужен.

Почему вместо цифр получаются пробелы или буква E?

Это следствие форматирования по умолчанию: платформа группирует разряды пробелами, а для больших чисел может использовать экспоненциальную запись. Решение — явный формат: Формат(Число, "ЧГ=0") отключает группировку, а добавление "ЧДЦ=0" отсекает дробную часть.

Как разбить сумму на рубли и копейки отдельными цифрами?

Разделите значение на две части: Цел(Сумма) — рубли, Окр((Сумма - Цел(Сумма)) * 100, 0) — копейки. Каждую часть разбивайте на цифры отдельно, копейки при необходимости дополните ведущим нулём до двух знаков.

Можно ли разбить число на разряды (тысячи, миллионы), а не на цифры?

Да, используйте деление на степень десяти: Цел(Число / 1000) % 1000 даст группу тысяч, Цел(Число / 1000000) % 1000 — миллионов. Это удобно для сумм прописью, где число обрабатывается тройками разрядов.

Где разместить функцию разбора, чтобы использовать её в нескольких местах?

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

Что делать, если исходное значение — строка с цифрами, а не число?

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

Итог

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

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