При разработке интерфейсов и формировании печатных форм часто возникает задача корректного отображения возраста или периодов. В русском языке существительное, стоящее после числительного, склоняется по особым правилам (так называемая плюрализация). Например: «1 год», «2 года», «5 лет». Рассмотрим подробнее, как реализовать этот механизм в среде «1С:Предприятие 8», используя как встроенные функции платформы, так и программные алгоритмы.
Самый известный способ, который исторически применялся в 1С, — это использование функции ЧислоПрописью. Эта функция предназначена для преобразования числа в текстовое представление, но её можно настроить так, чтобы она возвращала правильную форму предмета исчисления.
Проанализируем параметры этой функции. Основной интерес представляет третий параметр — «ПараметрыПредметаИсчисления». Это строка, в которой через запятую указываются формы слова для разных падежей и чисел.
Функция ПолучитьЛетСПадежом(ЧислоЛет) Экспорт
// Параметры: "ед.ч. им.п, ед.ч. род.п, мн.ч. род.п, род"
ПараметрыПредмета = "год, года, лет, м, , , , , 0";
// Форматная строка: Л (локализация), НП (Не выводить название Предмета — Ложь)
ФорматнаяСтрока = "Л = ru_RU; НП = Ложь";
// Получаем результат
Результат = ЧислоПрописью(ЧислоЛет, ФорматнаяСтрока, ПараметрыПредмета);
Возврат Результат;
КонецФункции
Выясним причину, по которой этот метод может быть неудобен. Функция ЧислоПрописью по умолчанию выводит число словами (например, «двадцать один год»). Если нам нужно вывести число цифрами («21 год»), нам придется либо комбинировать строки, либо использовать «хаки» с параметрами. Однако для большинства стандартных задач этот метод является самым надежным, так как опирается на системные механизмы платформы.
Начиная с версии платформы 8.3.10, разработчикам стал доступен более элегантный и современный способ, заимствованный из механизмов интернационализации ПО. Рассмотрим использование функции НСтр со специальным синтаксисом для плюрализации.
Разберем по шагам, как это работает. Вместо того чтобы писать сложные условия Если ... ИначеЕсли, мы можем определить шаблон строки, который платформа обработает самостоятельно в зависимости от переданного значения.
ЧислоЛет = 22;
// Шаблон содержит варианты для разных числительных в формате [число] [форма1|форма2|форма3]
Шаблон = НСтр("ru = '[#] [год|года|лет]'");
Результат = СтрШаблон(Шаблон, ЧислоЛет);
// Результат будет: "22 года"
Этот метод считается наиболее правильным для современных конфигураций на управляемых формах. Он автоматически учитывает все сложности русского языка и легко масштабируется, если программу потребуется перевести на другие языки, где правила склонения отличаются.
Иногда требуется реализовать склонение «вручную», чтобы избежать вызова тяжелых системных функций в циклах или при формировании больших отчетов. Разберем алгоритм, основанный на анализе остатка от деления числа на 10 и 100.
Проанализируем логику: 1. Если число оканчивается на 1 (но не на 11), используется форма «год». 2. Если число оканчивается на 2, 3, 4 (но не на 12, 13, 14), используется форма «года». 3. Во всех остальных случаях (5-9, 0, а также исключения 11-14) используется форма «лет».
Функция ПредставлениеГода(ЧислоЛет)
Остаток100 = ЧислоЛет % 100;
Остаток10 = Остаток100 % 10;
Если Остаток100 > 10 И Остаток100 < 15 Тогда
Форма = "лет";
ИначеЕсли Остаток10 = 1 Тогда
Форма = "год";
ИначеЕсли Остаток10 > 1 И Остаток10 < 5 Тогда
Форма = "года";
Иначе
Форма = "лет";
КонецЕсли;
Возврат Строка(ЧислоЛет) + " " + Форма;
КонецФункции
Посмотрим на пример работы: для числа 21 Остаток10 будет равен 1, вернется «год». Для числа 12 Остаток100 попадет в диапазон 11-14, вернется «лет», что соответствует правилам грамматики.
Если вы работаете в современной конфигурации (например, 1С:ERP, УТ 11 или БП 3.0), в вашем распоряжении есть готовые функции из состава БСП. Разберем наиболее полезные из них.
В общем модуле СтроковыеФункцииКлиентСервер существует функция, которая позволяет получить склонение любого слова по переданному числу. Нам не нужно изобретать велосипед, достаточно передать число и три формы слова.
// Пример использования БСП
Количество = 5;
Представление = СтроковыеФункцииКлиентСервер.СклонениеСуществительныхПоЧислу(Количество, "год", "года", "лет");
// Результат: "5 лет"
Также, если задача стоит в выводе разницы между двумя датами (например, стаж работы), можно воспользоваться функцией ПредставлениеПериода, которая сама рассчитает разницу и добавит нужные слова («2 года 3 месяца»).
Проанализируем ситуацию с производительностью. Если вам нужно склонять значения в динамическом списке или в отчете на десятки тысяч строк, постоянный вызов ЧислоПрописью может замедлить работу интерфейса. В таких случаях лучше использовать кэширование или простую математическую функцию, описанную выше.
Особенности работы с дробными числами:
Выясним, что происходит, если возраст указан не целым числом (например, 1.5 года). В русском языке при наличии дробной части существительное всегда ставится в родительный падеж единственного числа — «года». Математические алгоритмы через % 10 в этом случае не сработают, поэтому для дробных чисел логику нужно дополнять проверкой на наличие остатка от деления на 1.
Выводы:
НСтр (для платформы 8.3.10+).СтроковыеФункцииКлиентСервер.ЧислоПрописью.