В практике программирования на платформе 1С:Предприятие часто возникает задача вывода чисел прописью. Если с целыми числами и суммами в валюте (рубли, копейки) встроенные средства справляются отлично, то специфические требования, такие как вывод 12 знаков после запятой для учета драгоценных металлов в форме Инв-8а, требуют особого подхода. Рассмотрим подробнее, как реализовать вывод дробной части прописью, начиная от стандартных функций и заканчивая сложными алгоритмами ручного разбора.
Прежде всего, разберем возможности встроенного языка 1С. Функция ЧислоПрописью() является мощным инструментом, который позволяет форматировать числа согласно правилам выбранного языка. Синтаксис функции выглядит следующим образом: ЧислоПрописью(Число, ФорматнаяСтрока, ПараметрыПредметаИсчисления).
Для вывода дробной части нам необходимо правильно настроить второй и третий параметры. Проанализируем пример, где нам нужно вывести число с двумя знаками после запятой (например, для веса в граммах):
// Пример для вывода веса в граммах (3 знака после запятой)
ФормСтрока = "Л = ru_RU; ДП = Истина";
ПарПредмета = "грамм, грамма, граммов, м, миллиграмм, миллиграмма, миллиграмм, м, 3";
Результат = ЧислоПрописью(15.425, ФормСтрока, ПарПредмета);
// Результат: "Пятнадцать граммов четыреста двадцать пять миллиграммов"
Важные параметры форматной строки:
Однако стандартная функция имеет ограничение: она эффективно работает, когда мы заранее знаем разрядность и именование единиц. Если же нам нужно вывести число в формате "десятых", "сотых" или "тысячных" долей без привязки к конкретным единицам измерения (метрам, граммам), настройка усложняется.
Если задача стоит в выводе числа в математическом виде (например, "ноль целых пять десятых"), мы можем столкнуться с тем, что стандартные параметры 1С выдают "громоздкий" результат. Выясним причину: 1С пытается согласовать числительное с предметом исчисления. Для решения задачи с небольшим количеством знаков (до 3-х) можно использовать следующую функцию:
Функция ЧислоСДробьюПрописью(пЧисло) Экспорт
Стр = "";
пЦелое = Цел(пЧисло);
// Получаем дробную часть как строку без "0."
пДробь = СтрЗаменить(Формат((пЧисло - пЦелое),"ЧРД=.; ЧН=0; ЧГ=0"),"0.","");
Стр = ЧислоПрописью(пЦелое, , ",,,,,,,,0") + " целых ";
Если СтрДлина(пДробь) = 1 Тогда
Стр = Стр + ЧислоПрописью(Число(пДробь), , "десятая, десятых, десятых, ж, 0") + " десятых";
ИначеЕсли СтрДлина(пДробь) = 2 Тогда
Стр = Стр + ЧислоПрописью(Число(пДробь), , "сотая, сотых, сотых, ж, 0") + " сотых";
ИначеЕсли СтрДлина(пДробь) = 3 Тогда
Стр = Стр + ЧислоПрописью(Число(пДробь), , "тысячная, тысячных, тысячных, ж, 0") + " тысячных";
КонецЕсли;
Возврат Стр;
КонецФункции
В данном примере мы используем параметр предмета исчисления для управления родом (женский род: одна сотая, а не один сотая). Мы передаем пустые значения для целой части и указываем названия для дробной.
Ситуация значительно усложняется, когда речь идет о драгоценных металлах, где точность составляет 12 знаков. Стандартная функция ЧислоПрописью() при такой разрядности может выдать результат типа "триллионные доли", что не всегда удобно для чтения в бухгалтерских документах. Посмотрим на алгоритм ручного разбора числа, который позволяет гибко управлять выводом.
Разберем по шагам, как разделить число на составляющие и обработать каждую часть:
Процедура ВывестиДрагметаллыПрописью(ВашеЧисло)
// 1. Преобразуем число в строку для точного разделения
СтрокаЧисла = Формат(ВашеЧисло, "ЧРД=.; ЧГ=0");
ПозицияРазделителя = Найти(СтрокаЧисла, ".");
Если ПозицияРазделителя = 0 Тогда
ЦелаяЧастьСтрокой = СтрокаЧисла;
ДробнаяЧастьСтрокой = "";
Иначе
ЦелаяЧастьСтрокой = Лев(СтрокаЧисла, ПозицияРазделителя - 1);
ДробнаяЧастьСтрокой = Прав(СтрокаЧисла, СтрДлина(СтрокаЧисла) - ПозицияРазделителя);
КонецЕсли;
// 2. Обработка целой части
Результат = ЧислоПрописью(Число(ЦелаяЧастьСтрокой), "Л=ru_RU", "целая, целых, целых, ж") + " ";
// 3. Обработка дробной части (логика деления по разрядам)
Если СтрДлина(ДробнаяЧастьСтрокой) > 0 Тогда
// Пример: берем первые 6 знаков как миллионные
МиллионнаяЧасть = Число(Лев(ДробнаяЧастьСтрокой, 6));
Результат = Результат + ЧислоПрописью(МиллионнаяЧасть, "Л=ru_RU", "миллионная, миллионных, миллионных, ж") + " ";
// Если знаков больше, продолжаем разбор для оставшихся
Если СтрДлина(ДробнаяЧастьСтрокой) > 6 Тогда
ОстатокДроби = Число(Прав(ДробнаяЧастьСтрокой, СтрДлина(ДробнаяЧастьСтрокой) - 6));
Результат = Результат + ЧислоПрописью(ОстатокДроби, "Л=ru_RU", "триллионная, триллионных, триллионных, ж");
КонецЕсли;
КонецЕсли;
Сообщить(Результат);
КонецПроцедуры
Важный технический нюанс: при работе с типом Число в 1С при операциях вычитания (например, Число - Цел(Число)) может возникнуть погрешность представления чисел с плавающей точкой (так называемый "дребезг"). Чтобы избежать появления лишних цифр в конце строки (типа 0.0000000000000001), всегда используйте функцию Формат() или Окр() перед обработкой дробной части.
Проанализируем правильные наименования разрядов в русском языке, которые могут понадобиться вам для составления форматных строк при работе с большой точностью:
Практический совет: Если бухгалтер требует выводить 12 знаков, но стандартная запись "триллионных" кажется слишком сложной, предложите "бухгалтерский" способ записи. В этом случае целая часть пишется словами, а дробная — цифрами в виде простой дроби. Например: "Двадцать шесть целых и 422557738907/1000000000000". Этот вариант часто более предпочтителен, так как исключает двусмысленность при чтении документа.
Мы рассмотрели несколько способов решения задачи. Для простых случаев (2-3 знака) идеально подходит стандартная функция ЧислоПрописью() с настроенными параметрами предмета исчисления. Для сложных случаев с высокой разрядностью (как в случае с драгметаллами) оптимальным будет ручной разбор числа через строковые функции с последующим форматированием каждого блока разрядов отдельно. Это обеспечит максимальную точность и соответствие лингвистическим нормам русского языка.