Разработка и Конфигурация · 11 мин
Как разбить число на цифры в 1С
Как разбить число на отдельные цифры в 1С: работа со строковым представлением, функции Сред, СтрДлина, математический способ, обработка отрицательных чисел и типичные ошибки.
Задача разбить число на отдельные цифры в 1С встречается чаще, чем кажется: формирование кассовых чеков с посимвольным выводом суммы, заполнение бланков строгой отчётности, где каждая цифра пишется в отдельную клетку, передача данных в оборудование, которое принимает число по одному разряду. Встроенной функции «разбить число на цифры» во встроенном языке 1С нет, поэтому задачу решают двумя рабочими способами: через строковое представление числа и через математические операции.
Оба подхода дают одинаковый результат, но отличаются по скорости, читаемости кода и поведению на граничных значениях — отрицательных числах, дробной части, очень больших значениях. Ниже разобраны готовые функции, которые можно перенести в общий модуль конфигурации, а также ограничения каждого метода и способы проверить корректность результата.
Какие способы существуют и когда какой выбирать
Первый способ — строковый. Число преобразуется в строку, после чего каждый символ вырезается функцией Сред() и при необходимости обратно преобразуется в число. Способ короткий, наглядный и подходит для большинства прикладных задач: печатных форм, обменов, вывода на табло.
Второй способ — математический. Цифры выделяются последовательным взятием остатка от деления на 10 и целочисленным делением. Он работает только с числами, не требует строковых операций и удобен, когда нужно именно арифметически обойти разряды — например, посчитать сумму цифр или контрольную сумму.
Сравнение вариантов
Подходит для печатных форм и обменов, легко обрабатывает ведущие нули после форматирования; требует аккуратности с минусом и разделителем дробной части
Подходит для расчётов с разрядами и контрольных сумм; цифры получаются в обратном порядке — от младшего разряда к старшему
Подходит, когда число нужно дополнить нулями слева до фиксированной длины перед разбором, например для бланков с фиксированным числом клеток
Выбор зависит от задачи. Если цифры нужны для отображения — берите строковый способ. Если для вычислений — математический. Если число должно занимать строго фиксированное количество позиций — сначала примените Формат() с нужной форматной строкой.
Разбор числа через строковое представление
Базовый вариант выглядит так: число переводится в строку, затем в цикле от 1 до длины строки извлекается по одному символу. Функция СтрДлина() возвращает количество символов, Сред(Строка, НомерСимвола, 1) — один символ в указанной позиции.
Функция РазбитьЧислоНаЦифры(Число)
МассивЦифр = Новый Массив;
СтрокаЧисла = Формат(Число, "ЧГ=0");
Для Позиция = 1 По СтрДлина(СтрокаЧисла) Цикл
Символ = Сред(СтрокаЧисла, Позиция, 1);
МассивЦифр.Добавить(Число(Символ));
КонецЦикла;
Возврат МассивЦифр;
КонецФункции
Обратите внимание на форматную строку "ЧГ=0" — она отключает группировку разрядов. Без неё Формат() может вставить в строку неразрывные пробелы между тысячами (например, «1 234 567»), и разбор даст лишние «цифры» из пробелов либо ошибку преобразования. Это самая частая причина некорректной работы подобного кода.
Если цифры нужны как строки, а не как числа — например, для вывода в отдельные ячейки табличного документа — преобразование Число(Символ) можно убрать и добавлять в массив сам символ.
- 1Преобразуйте число в строку через Формат(Число, "ЧГ=0") без группировки разрядов
- 2Проверьте первый символ: если это минус — начните цикл со второй позиции или возьмите модуль числа заранее
- 3В цикле от 1 до СтрДлина(СтрокаЧисла) извлекайте символы функцией Сред()
- 4Преобразуйте каждый символ в число функцией Число() и добавьте в массив
- 5Проверьте результат на контрольном примере: число 407 должно дать массив 4, 0, 7
Обработка отрицательных чисел и дробной части
Отрицательное число в строковом виде начинается с символа «-». Если прогнать его через цикл разбора, преобразование Число("-") вызовет ошибку. Перед разбором возьмите модуль числа функцией Макс(Число, -Число) либо проверьте первый символ и пропустите его.
С дробными числами ситуация сложнее. В строковом представлении дробная часть отделяется точкой или запятой в зависимости от настроек формата, а сама дробная часть может отображаться не полностью, если не задана точность. Если нужно разбить только целую часть, сначала примените Цел(Число). Если нужны и знаки после запятой — задайте точность в форматной строке, например Формат(Число, "ЧГ=0; ЧДЦ=2"), и отдельно обработайте символ разделителя.
Математический способ: остаток от деления
Математический вариант не использует строки вообще. Остаток от деления числа на 10 даёт последнюю цифру, а целочисленное деление на 10 отсекает её. Повторяя операцию, получаем все цифры, но в обратном порядке — от младшего разряда к старшему.
Функция РазбитьЧислоМатематически(Число)
МассивЦифр = Новый Массив;
Текущее = Макс(Число, -Число);
Если Текущее = 0 Тогда
МассивЦифр.Добавить(0);
Возврат МассивЦифр;
КонецЕсли;
Пока Текущее > 0 Цикл
Цифра = Текущее % 10;
МассивЦифр.Добавить(Цифра);
Текущее = Цел(Текущее / 10);
КонецЦикла;
Возврат МассивЦифр;
КонецФункции
Здесь % — оператор остатка от деления, Цел() отбрасывает дробную часть после деления. Отдельная обработка нуля обязательна: без неё цикл Пока Текущее > 0 не выполнится ни разу и функция вернёт пустой массив вместо массива с одной цифрой 0.
Чтобы получить цифры в привычном порядке — от старшего разряда к младшему — переверните массив после цикла или вставляйте элементы в начало через МассивЦифр.Вставить(0, Цифра). Учтите, что вставка в начало массива медленнее добавления в конец на больших объёмах.
Разбор числа с ведущими нулями и фиксированной длиной
Типичная прикладная задача — вывести сумму в бланк, где под число отведено, например, 9 клеток, а недостающие позиции должны быть заполнены нулями. Здесь перед разбором число форматируют с лидирующими нулями: Формат(Сумма, "ЧЦ=9; ЧН=0; ЧГ=0; ЧВН=1") или эквивалентная форматная строка с параметром длины.
После такого форматирования строка всегда имеет заданную длину, и разбор функцией Сред() даёт ровно столько цифр, сколько нужно для бланка. Проверьте поведение на переполнении: если число не помещается в заданную длину, форматная строка не обрежет его автоматически — строка просто станет длиннее. При необходимости добавьте явную проверку СтрДлина() результата.
Куда поместить функцию и как её вызывать
Функцию разбора числа на цифры логично разместить в общем модуле — например, в модуле работы со строками или числами, если он есть в конфигурации. Для вызова с клиента модуль должен иметь флажки «Клиент (обычное приложение)» или «Клиент (управляемое приложение)», для серверных вызовов — «Сервер». Экспортная функция объявляется с ключевым словом Экспорт.
Если функция нужна только в одном месте — например, в модуле менеджера печати конкретного документа — не выносите её в общий модуль без необходимости: лишний экспортный интерфейс усложняет поддержку. Для разовой задачи достаточно локальной функции в том же модуле.
В типовых конфигурациях уже есть похожие механизмы посимвольного вывода сумм в печатных формах (например, в модулях формирования платёжных поручений и кассовых документов). Прежде чем писать свою функцию, поищите существующий код через глобальный поиск по словам «Сред(» в модулях печати — часто можно переиспользовать готовое решение.
Частые ошибки и как их избежать
Ошибки при разборе числа на цифры почти всегда связаны не с логикой цикла, а с подготовкой данных: неожиданные символы в строке, потерянные нули, неверный порядок разрядов. Ниже собраны типичные случаи.
Ещё одна ловушка — приведение к строке через Строка(Число) вместо Формат(). Прямое преобразование зависит от региональных настроек сеанса и может дать непредсказуемый вид числа. Для служебной обработки всегда используйте Формат() с явной форматной строкой.
Как проверить корректность результата
Минимальный набор контрольных примеров: положительное число без нулей (1234), число с нулями внутри (4007), ноль, однозначное число (5), отрицательное число (-89), число с ведущими нулями после форматирования. Для каждого случая сверьте длину массива и значения элементов с ожидаемыми.
Быстрый способ убедиться, что разбор работает, — собрать число обратно: пройти по массиву цифр и сложить их с весами степеней десяти, либо склеить в строку и преобразовать в число. Совпадение с исходным значением (по модулю) подтверждает корректность разбора.
Как проверить результат
Массив из трёх элементов: 4, 0, 7
Пустой массив, пропущенный ноль или лишние элементы
Массив из одного элемента 0
Пустой массив
Массив 8, 9 без ошибки преобразования
Ошибка на символе минуса или лишний элемент
Семь цифр без пробелов
Лишние элементы из пробелов группировки
Что важно запомнить
Число в 1С разбивают на цифры либо через строку функциями Формат(), СтрДлина() и Сред(), либо математически — остатком от деления на 10 и целочисленным делением. Всегда отключайте группировку разрядов, отдельно обрабатывайте ноль, минус и дробную часть, а ведущие нули сохраняйте через форматную строку.
Частые вопросы
Можно ли разбить число на цифры без цикла?
Нет, во встроенном языке 1С нет функции, которая одним вызовом возвращает массив цифр числа. Любое решение сводится к циклу по символам строки или по разрядам числа. Можно лишь вынести этот цикл в общую функцию и вызывать её одной строкой.
Как получить цифры в обратном порядке?
Математический способ с остатком от деления уже возвращает цифры от младшего разряда к старшему. Если используется строковый способ, пройдите цикл от конца строки к началу: Для Позиция = -СтрДлина(СтрокаЧисла) По -1 с шагом через конструкцию убывающего цикла либо переверните готовый массив.
Что делать, если число слишком большое?
Числовой тип в 1С имеет ограниченную разрядность, и очень длинные значения (длинные идентификаторы, номера карт, хеши) следует хранить как строки с самого начала. Тогда разбор делается только строковым способом, без преобразования в число и без риска потери точности.
Как разбить на цифры сумму с копейками?
Разделите значение на целую и дробную части: рубли — Цел(Сумма), копейки — Цел((Сумма - Цел(Сумма)) * 100 + 0,5) с округлением. Затем разбейте каждую часть отдельно, при необходимости дополнив копейки ведущим нулём до двух позиций через форматную строку.
Почему Число(Символ) выдаёт ошибку, хотя символ выглядит как цифра?
Чаще всего в строке оказался неразрывный пробел из группировки разрядов, знак минуса или разделитель дробной части. Проверьте форматную строку и код символа через КодСимвола() — у неразрывного пробела код отличается от обычного пробела, и визуально их не различить.
Работает ли этот код на клиенте и на сервере одинаково?
Да, функции Формат(), Сред(), СтрДлина() и арифметические операции доступны и на клиенте, и на сервере. Различие возможно только в результатах Формат() без явной форматной строки, если региональные настройки клиента и сервера различаются — ещё один довод всегда задавать формат явно.