gifts2017

Формы предмета исчисления

Опубликовал rtnm rtnm (rtnm) в раздел Программирование - Практика программирования

Иногда возникает задача склонения предмета исчисления, но ее не пытаются решить правильно. Есть простое решение.

Задача.

Например, необходимо в интерфейсе отображать количество проданных за день яблок естественной фразой "Продано 1 яблоко" ("Продано 2 яблока", "Продано 5 яблок"). Обращаю внимание, что количество проданных яблок указывается числом, а не прописью.

Неправильные решения.

Обычно необходимость склонения предмета исчисления обходят следующими способами:

- Игнорирование.
В итоге получаем "Продано 1 яблоков" или "Продано 2 яблоко".

- Использование сокращений.
В итоге получаем "Продано 3 ябл."

- Использование всех форм сразу.
В итоге получаем "Продано 3 яблоко(ка,ок)" или "Продано 7 яблоко/яблока/яблок"

- Использование только одной формы.
В итоге получаем "Продано яблок: 3"

Последний вариант выглядит неплохо, но не всегда есть возможность использовать его.

Правильное решение.

Правильное решение заключается в выборе нужной формы предмета исчисления в зависимости от количества предмета.
Для русского языка это решается с помощью следующей функции.

Функция ПолучитьФормуПредметаИсчисления(Количество, Форма1, Форма2, Форма5) Экспорт
    
    Перем Формы, К;    
    
    Формы = Новый Массив();
    Формы.Добавить(Форма1);
    Формы.Добавить(Форма2);
    Формы.Добавить(Форма5);
    
    К = ?(Количество >= 0, Количество, -Количество);
    
    ИндексФормы = ?(К%10 = 1 И К%100 <> 11, 0, ?(К%10 >= 2 И К%10 = 20), 1, 2));
    
    Возврат Формы[ИндексФормы];
    
КонецФункции

В описанном примере решение может быть следующим.

"Продано " + Продано + " " + ПолучитьФормуПредметаИсчисления(Продано, "яблоко", "яблока", "яблок")

Для того, чтобы правильно определить каждую из трех форм, вы должны проговорить их для 1, 2 и 5 - этого будет достаточно.

Если потребуется определять форму предмета исчисления для других языков, то формулы можно подсмотреть здесь.

Заключение.

Старался быть кратким. Спасибо за внимание.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Dima Neumoichev (Ndochp) 14.05.14 10:09
А в 1С это разве не через Сумма прописью логично сделать?
kostik_love; +1 Ответить
2. Татьяна Шавлак (Stety) 14.05.14 11:23
По аналогии с "ленивыми голубцами" это сойдет. Мы же все хотим побыстрее. Но и юзер тоже хочет побыстрее. Надо оно ему: каждый раз падежи вбивать? А программист на что?
На самом деле, если уж перекладывать ответственность за грамотность документов на юзера, то надо предусмотреть реквизиты для хранения наименований в падежах стоило бы во всех справочниках. Однако, как это раздует базу? Вот в чем вопрос...
3. Руслан (lrs) 14.05.14 23:44
Я так делал:
СтрЗаменить(ЧислоПрописью(Продано,"","яблоко, яблока, яблок,,,,,,0"), ЧислоПрописью(Продано,"",",,,,,,,,0"), "")
BigB; romankoav; AlX0id; zqzq; ВРедная; userGJ; jsuh; rtnm; +8 Ответить 1
4. Константин Воробьёв (kostik_love) 17.05.14 13:54
Задача: 1 рубль, 3 рубля, 5 рублей
- Вы тоже так будете решать)?
5. rtnm rtnm (rtnm) 18.05.14 18:42
6. Константин Воробьёв (kostik_love) 19.05.14 12:35
(5) rtnm, я попробую так- как это сделано в типовых
7. dima_gsv (dima_gsv) 01.09.15 12:24
(6) kostik_love, в типовых сделано как писал (3) lrs. На мой взгляд, не очень читаемо получается.