При разработке и оформлении ценников или этикеток в среде «1С:Предприятие» часто возникает эстетическая задача: вывести рубли крупным шрифтом, а копейки — мелким сверху (или просто в отдельной ячейке). Первая логичная мысль, которая приходит разработчику, — использовать стандартную функцию Формат или настроить свойство «Формат» в свойствах ячейки макета. Однако при попытке сделать это стандартным путем мы сталкиваемся с неожиданным поведением платформы.
В этой статье мы подробно разберем, почему чистым форматированием решить эту задачу невозможно, проанализируем внутренние механизмы платформы 1С и рассмотрим несколько надежных, проверенных способов выделения копеек с помощью математических выражений и строковых функций.
Попробуем разобраться, почему стандартный подход с форматированием терпит неудачу. Допустим, у нас есть цена 55.23. Мы хотим настроить форматную строку так, чтобы отображались только две последние цифры дробной части. Казалось бы, можно использовать сдвиг разрядов на два порядка вверх и ограничить длину числа двумя символами:
"ЧЦ=2; ЧДЦ=0; ЧС=-2"
Однако на практике в ячейке макета вместо ожидаемых 23 мы увидим значение 99 (или пустоту/звездочки в зависимости от версии платформы). Выясним причину такого поведения.
Когда мы задаем параметр ЧЦ (Число цифр), платформа 1С строго контролирует общую длину числа, включая его целую часть. Сдвиг разрядов ЧС=-2 умножает исходное число на 100, превращая 55.23 в 5523. Платформа видит, что реальное число состоит из 4 знаков, тогда как мы жестко ограничили вывод двумя знаками через параметр ЧЦ=2. Поскольку число 5523 физически не помещается в два разряда, 1С сигнализирует о переполнении разрядной сетки и выводит максимально возможное для двух разрядов число — 99.
Таким образом, исключительно силами форматной строки «обрезать» левую целую часть числа невозможно. Нам в любом случае придется прибегнуть к предварительным вычислениям.
Самый простой и производительный способ получить копейки — использовать математическую операцию получения остатка от деления на 1. Разберем этот алгоритм по шагам.
Если мы разделим число 55.23 на 1 с остатком, мы получим дробную часть: 0.23. Чтобы превратить ее в целое число копеек, достаточно умножить результат на 100. На языке 1С это выражение выглядит следующим образом:
(Цена % 1) * 100
Однако здесь программиста подстерегает классическая ловушка двоичной арифметики с плавающей точкой (Floating Point). Компьютер представляет дробные числа в двоичном виде, из-за чего некоторые десятичные дроби не могут быть записаны абсолютно точно. На уровне платформы выражение 55.23 % 1 может вернуть результат вроде 0.229999999999997. Если мы просто умножим это число на 100 и отсечем дробную часть функцией Цел(), то на выходе мы получим 22 копейки вместо 23.
Чтобы избежать этой критической ошибки, необходимо обязательно использовать функцию округления Окр() перед получением целого числа. Проанализируем правильный вариант математического расчета:
Копейки = Цел(Окр((Цена % 1) * 100, 2));
Или альтернативный вариант через вычитание целой части:
Копейки = Окр((Цена - Цел(Цена)) * 100);
Оба этих выражения абсолютно надежны и гарантируют корректный результат при любых значениях исходной цены.
Если по каким-то причинам вы не хотите использовать математические операции, можно преобразовать число в строковый тип и извлечь нужные символы с правого конца строки. Посмотрим на пример реализации:
СтрокаЦенника = Строка(Цена);
КопейкиСтрокой = Прав(СтрокаЦенника, 2);
Этот способ кажется привлекательным своей простотой, однако у него есть существенные скрытые недостатки, о которых важно помнить:
150), то функция Строка(Цена) вернет «150» без дробной части, и функция Прав(Строка, 2) вернет некорректные «50» вместо «00».Если и использовать строковый метод, то только с предварительным форматированием:
СтрокаЦенника = Формат(Цена, "ЧДЦ=2; ЧГ=0");
КопейкиСтрокой = Прав(СтрокаЦенника, 2);
В данном случае формат ЧГ=0 отключает группировку триад цифр (чтобы в числе не появились лишние пробелы-разделители тысяч), а ЧДЦ=2 гарантирует наличие двух знаков копеек в конце строки, даже если исходная цена была круглой.
Часто перед разработчиком стоит задача настроить макет этикетки или ценника в режиме управляемого приложения (например, в «1С:Розница» или «1С:УНФ»), где код самого печатного модуля закрыт или находится на поддержке без возможности изменения. В этом случае мы можем настроить вычисление копеек прямо внутри самого макета табличного документа.
Рассмотрим по шагам, как это сделать:
Формат((Цена - Цел(Цена)) * 100, "ЧЦ=2; ЧН=00; ЧВН=")
Разберем подробнее, за что отвечают параметры форматной строки в данном выражении:
ЧЦ=2 — ограничивает длину поля двумя символами (поскольку мы подаем на вход только копейки от 0 до 99, переполнения не возникнет).ЧН=00 — указывает платформе выводить два нуля, если результат вычисления выражения равен нулю (для круглых цен без копеек).ЧВН= — включает режим вывода лидирующих нулей. Это критически важно для цен с копейками меньше десяти. Например, для цены 100.05 выражение (Цена - Цел(Цена)) * 100 вернет число 5. Без флага ЧВН= на ценнике напечатается одинокая цифра 5, а благодаря этому параметру платформа корректно выведет строку 05.Если ваш макет ценников или прайс-листов формируется на базе СКД, оптимальным решением будет создание отдельного вычисляемого поля на уровне схемы компоновки. Это позволит отделить логику расчета от визуального представления.
Рассмотрим последовательность действий:
КопейкиВыразить((Цена - Цел(Цена)) * 100, "Число(2,0)")КопейкиЧВН=; ЧН=00.Теперь в вашем макете СКД достаточно просто привязать созданное поле Копейки к нужной ячейке. Платформа сама вычислит значение и приведет его к красивому двухсимвольному виду.
Подводя итог, отметим: несмотря на то, что стандартная функция Формат не умеет самостоятельно разделять рубли и копейки из одного числа, связка простых арифметических операций с последующим форматированием позволяет решить эту задачу легко, красиво и без ошибок округления.