Blog. Just Blog

Сумма прописью на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Сумма прописью на PHP
Сумма прописью на PHP

В соответствии с нормативными актами, регламентирующими порядок работы с бухгалтерскими документами, при заполнении многих унифицированных форм сумма указывается не только числами, но и прописью. Формат записи принят следующий: рублевая часть суммы указывается прописью в именительном падеже с заглавной буквы, а копейки обозначаются цифрами. При автоматической генерации документов на PHP с цифровыми выражениями проблем в принципе не возникает, а для преобразования чисел в сумму прописью я уже давно написал и использую вот такую функцию.

В процессе преобразования используется функция для склонения числительных, о которой я писал в одной из предыдущих статей. Параметры ее вызова и особенности вы можете посмотреть там же, здесь я это дублировать не буду.
  1. //--------------------------------------------------------
  2. // Функция для склонения числительных
  3. //--------------------------------------------------------
  4. function num2word($n,$words) {
  5.     return ($words[($n=($n=$n%100)>19?($n%10):$n)==1?: (($n>1&&$n<=4)?1:2)]);
  6. }
А вот и сама функция для преобразования числа в сумму прописью. Единственный параметр вызова - число, которое требуется записать словами.
  1. //--------------------------------------------------------
  2. // Функция для преобразования числа в сумму прописью
  3. //--------------------------------------------------------
  4. // Автор: ManHunter / PCL (www.manhunter.ru)
  5. //--------------------------------------------------------
  6. function sum2words($n) {
  7.     $words=array(
  8.         900=>'девятьсот',
  9.         800=>'восемьсот',
  10.         700=>'семьсот',
  11.         600=>'шестьсот',
  12.         500=>'пятьсот',
  13.         400=>'четыреста',
  14.         300=>'триста',
  15.         200=>'двести',
  16.         100=>'сто',
  17.         90=>'девяносто',
  18.         80=>'восемьдесят',
  19.         70=>'семьдесят',
  20.         60=>'шестьдесят',
  21.         50=>'пятьдесят',
  22.         40=>'сорок',
  23.         30=>'тридцать',
  24.         20=>'двадцать',
  25.         19=>'девятнадцать',
  26.         18=>'восемнадцать',
  27.         17=>'семнадцать',
  28.         16=>'шестнадцать',
  29.         15=>'пятнадцать',
  30.         14=>'четырнадцать',
  31.         13=>'тринадцать',
  32.         12=>'двенадцать',
  33.         11=>'одиннадцать',
  34.         10=>'десять',
  35.         9=>'девять',
  36.         8=>'восемь',
  37.         7=>'семь',
  38.         6=>'шесть',
  39.         5=>'пять',
  40.         4=>'четыре',
  41.         3=>'три',
  42.         2=>'два',
  43.         1=>'один',
  44.     );
  45.  
  46.     $level=array(
  47.         4=>array('миллиард''миллиарда''миллиардов'),
  48.         3=>array('миллион''миллиона''миллионов'),
  49.         2=>array('тысяча''тысячи''тысяч'),
  50.     );
  51.  
  52.     list($rub,$kop)=explode('.',number_format($n,2));
  53.     $parts=explode(',',$rub);
  54.  
  55.     for($str=''$l=count($parts), $i=0$i<count($parts); $i++, $l--) {
  56.         if (intval($num=$parts[$i])) {
  57.             foreach($words as $key=>$value) {
  58.                 if ($num>=$key) {
  59.                     // Fix для одной тысячи
  60.                     if ($l==&& $key==1) {
  61.                         $value='одна';
  62.                     }
  63.                     // Fix для двух тысяч
  64.                     if ($l==&& $key==2) {
  65.                         $value='две';
  66.                     }
  67.                     $str.=($str!=''?' ':'').$value;
  68.                     $num-=$key;
  69.                 }
  70.             }
  71.             if (isset($level[$l])) {
  72.                 $str.=' '.num2word($parts[$i],$level[$l]);
  73.             }
  74.         }
  75.     }
  76.  
  77.     if (intval($rub=str_replace(',','',$rub))) {
  78.         $str.=' '.num2word($rub,array('рубль''рубля''рублей'));
  79.     }
  80.  
  81.     $str.=($str!=''?' ':'').$kop;
  82.     $str.=' '.num2word($kop,array('копейка''копейки''копеек'));
  83.  
  84.     return mb_strtoupper(mb_substr($str,0,1,'utf-8'),'utf-8').
  85.          mb_substr($str,1,mb_strlen($str,'utf-8'),'utf-8');
  86. }
В случае необходимости можно заменить валюту или расширить диапазон обрабатываемых чисел, например, добавив по аналогии триллионы и т.п. Мне этого пока не требуется, суммы наших счетов вполне укладываются в обрабатываемый диапазон. Обратите внимание, что используются функции для работы с юникодными строками, для кодировки windows-1251 достаточно использовать штатную функцию ucfirst. Ну и в качестве демонстрации несколько примеров работы функции преобразования числа в сумму прописью:
  1. // Три миллиона девятьсот одиннадцать тысяч семьсот шестьдесят рублей 10 копеек
  2. echo sum2words(3911760.10);
  3. // Двадцать семь рублей 00 копеек
  4. echo sum2words(27);
  5. // Девяносто пять миллиардов одна тысяча рублей 42 копейки
  6. echo sum2words(95000001000.42);
  7. // 15 копеек
  8. echo sum2words(0.15);
Кстати, подобную задачу по записи числа словами очень любят на различных олимпиадах по информатике. Если поймете принцип, то легко справитесь с ее решением.

Поделиться ссылкой ВКонтакте
Просмотров: 6630 | Комментариев: 7

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
Владислав (27.11.2019 в 21:12):
Спасибо, работает!
ManHunter (04.10.2019 в 18:43):
Поправил, спасибо
ivan (04.10.2019 в 18:42):
Неточность в 40 строке:должно быть 4=>'четыре'

было "Сто семьдесят три одна тысячи" у 174000
ManHunter (16.11.2017 в 12:06):
Действительно. Поправил, спасибо!
johser (16.11.2017 в 11:53):
Заметил 2 неточности:
1. на 60 строке должно быть $l==2
2. нужно добить фикс для 2 тысяч, иначе
   echo sum2words(2000); // Два тысячи рублей 00 копеек
ManHunter (09.08.2017 в 17:15):
И? Пятьдесят семь тысяч четыреста восемьдесят два рубля 00 копеек
smaragdus (09.08.2017 в 17:10):
57482

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0071 сек.) / Память: 4.5 Mb
Наверх