При разработке печатных форм и отчетов в системе 1С программисты часто сталкиваются с задачей вывода суммы прописью. Однако стандартные функции могут вести себя неочевидно. Типичная ситуация: в выражении задано округление до двух знаков после запятой, но в результате получается странная конструкция, например: 3 217,5 (три тысячи двести восемнадцать) рублей. Как мы видим, в числовой части присутствуют десятые доли, а в текстовой расшифровке число округлилось до целого. В этой статье мы подробно разберем, почему так происходит, и как правильно настроить форматную строку для корректного отображения копеек.
Рассмотрим исходный код, который вызвал проблему у автора вопроса:
ПрописьЧисла = НРег(((Строка(СИ)+" ( "+ЧислоПрописью(Число(СИ),"Л=RU_RU; ЧДЦ=2; ДП=Истина",") рубль,) рубля,) рублей,м,копейка,копейки,копеек,м,0"))));
Проанализируем ситуацию и выясним причину странного поведения функции ЧислоПрописью. В данной функции форматная строка разделена на две части. Первая часть задает общие параметры (язык, точность), а вторая — параметры предмета исчисления (названия валют, падежи и род).
Многие разработчики полагают, что параметра ЧДЦ=2 (Число Десятичных Цифр) достаточно для управления точностью. Однако это не совсем так. Самым важным здесь является последний параметр в строке описания единиц измерения. В коде автора он равен 0:
") рубль,) рубля,) рублей,м,копейка,копейки,копеек,м,0"
Именно эта цифра 0 в самом конце сообщает системе, сколько десятичных знаков нужно учитывать при формировании текстового представления дробной части. Если там стоит ноль, 1С принудительно округляет число до целого при выводе слов, игнорируя настройки ЧДЦ. Чтобы исправить ошибку и увидеть копейки в скобках, необходимо заменить этот параметр на 2.
Давайте подробно разберем структуру строки, описывающей единицы измерения. Она состоит из полей, разделенных запятыми, и имеет строго определенный порядок. Посмотрим на пример для российского рубля:
Важный нюанс: если вы используете стандартную валюту (рубли, доллары, евро), совсем не обязательно прописывать все эти слова вручную. Платформа 1С позволяет использовать предопределенные файлы настроек. Например, вместо длинной строки можно указать путь к XML-файлу: "ru_RU.xml". Это поможет избежать ошибок в склонениях и родах.
В приведенном выше примере кода автор объединяет результат ЧислоПрописью с результатом Строка(СИ). Рассмотрим подробнее, почему использование функции Строка() для вывода сумм — это плохая практика.
Функция Строка() работает крайне непредсказуемо, так как она опирается на региональные настройки операционной системы конкретного пользователя или сервера. Это может привести к следующим проблемам:
Строка(), скорее всего, вернет "3 217,5", отбросив значащий ноль в конце, что недопустимо для финансовых документов.Вместо этого проанализируем и внедрим использование функции Формат(). Она позволяет жестко зафиксировать правила отображения числа независимо от настроек Windows.
Пример правильного кода для формирования суммы с числовой частью и прописью:
Сумма = 3217.5;
ФорматнаяСтрока = "ЧЦ=15; ЧДЦ=2; ЧГ=0"; // 2 знака после запятой, без группировки разрядов пробелами
ЧисловаяЧасть = Формат(Сумма, ФорматнаяСтрока);
ПараметрыПрописи = "Л=RU_RU; ЧДЦ=2; ДП=Истина";
ЕдиницыИзмерения = "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2";
ТекстоваяЧасть = ЧислоПрописью(Сумма, ПараметрыПрописи, ЕдиницыИзмерения);
Результат = ЧисловаяЧасть + " ( " + ТекстоваяЧасть + " )";
// Результат: "3217,50 ( три тысячи двести семнадцать рублей 50 копеек )"
Разберем еще несколько полезных параметров, которые могут пригодиться при работе с ЧислоПрописью:
Параметр ДП (Выводить пустое): в коде автора было указано ДП=Истина. Это полезная настройка для финансовых документов. Если у вас сумма без копеек (например, ровно 100 рублей), при ДП=Истина система выведет "00 копеек". Если установить ДП=Ложь, то дробная часть будет просто опущена, и в строке останется только "сто рублей".
Параметр НД (Название дробной части): по умолчанию копейки выводятся цифрами (например, "05 копеек"). Если бизнес-процесс требует вывода копеек словами ("пять копеек"), в первую часть форматной строки нужно добавить НД=Истина.
Посмотрим на ситуацию, когда число имеет более двух знаков после запятой (например, результат сложного расчета налогов). Функция ЧислоПрописью выполняет стандартное арифметическое округление. Это значит, что значение 3217,505 при точности "2" превратится в 3217,51.
Если ваша задача — просто "отрезать" лишние знаки без округления в большую сторону, число необходимо предварительно подготовить до того, как оно попадет в функцию прописи. Для этого можно использовать комбинацию функций Цел() или математические формулы:
// Пример отсечения без округления до 2 знаков
СуммаДляПрописи = Цел(Сумма * 100) / 100;
Для того чтобы избежать ошибок при выводе сумм прописью, всегда придерживайтесь следующих правил:
1. Проверяйте девятый параметр: всегда убеждайтесь, что в строке единиц измерения последняя цифра соответствует желаемому количеству знаков (обычно это 2 для валют).
2. Откажитесь от Строка(): используйте только Формат() для вывода числовых значений, чтобы гарантировать наличие двух знаков после запятой и стабильные разделители.
3. Следите за родом: помните, что рубль — мужского рода (м), а копейка — женского (ж). Ошибки в указании рода приведут к неверным окончаниям числительных (например, "два рубля" против "две копейки").
4. Тестируйте на граничных значениях: обязательно проверяйте, как ваш код обрабатывает 0 копеек, 1 копейку и суммы более миллиона.