При разработке отчетов, печатных форм или интерфейсов часто возникает задача корректного отображения временных интервалов. Вывод фразы типа "2 лет 1 месяцев 3 дней" выглядит непрофессионально и затрудняет восприятие информации. В русском языке правила склонения существительных, зависящих от числительных (плюрализация), подчиняются определенной логике, которую необходимо закладывать в код. Разберем по шагам, как реализовать правильный вывод: "2 года 1 месяц 3 дня".
Прежде чем использовать готовые функции, важно понять математическую основу задачи. Ошибочно полагать, что достаточно проверить только последнюю цифру числа. Самая распространенная ошибка новичков — вывод "12 года" или "11 день".
Проанализируем правила русского языка для количественных существительных:
Рассмотрим пример функции, которая реализует эту логику. Мы будем использовать оператор % (остаток от деления), чтобы получить нужные разряды числа:
Функция СклонятьСлово(Знач Число, Слово1, Слово2_4, СловоМного)
Число = Цело(Число); // Работаем только с целыми числами
Остаток100 = Число % 100;
Остаток10 = Число % 10;
// Сначала проверяем исключение: диапазон от 11 до 14
Если Остаток100 >= 11 И Остаток100 <= 14 Тогда
Возврат СловоМного;
КонецЕсли;
// Проверяем по последней цифре
Если Остаток10 = 1 Тогда
Возврат Слово1;
ИначеЕсли Остаток10 >= 2 И Остаток10 <= 4 Тогда
Возврат Слово2_4;
Иначе
Возврат СловоМного;
КонецЕсли;
КонецФункции
Используя эту функцию, мы можем подготовить параметры для макета:
ОбластьСправки.Параметры.СтажГод = Строка(Лет) + " " + СклонятьСлово(Лет, "год", "года", "лет");
ОбластьСправки.Параметры.СтажМес = Строка(Мес) + " " + СклонятьСлово(Мес, "месяц", "месяца", "месяцев");
ОбластьСправки.Параметры.СтажДень = Строка(Дней) + " " + СклонятьСлово(Дней, "день", "дня", "дней");
Начиная с версии платформы 8.3.10, в 1С появился встроенный мощный механизм для работы с числовыми представлениями. Функция СтрокаСЧислом позволяет избежать написания громоздких условий Если...КонецЕсли.
Синтаксис функции подразумевает использование форматной строки, в которой через точку с запятой перечисляются формы слова. Разберем структуру форматной строки: ";Форма1;Форма2;Форма5;ФормаДробь".
Посмотрим на пример реализации для дней:
КоличествоДней = 23;
ТекстДней = СтрокаСЧислом(";день;;дня;дней;дня", КоличествоДней, ВидЧисловогоЗначения.Количественное);
// Результат: "23 дня"
В этой строке параметры означают следующее:
Важно: Платформа сама подставит число в строку. Если вам нужно только само слово без числа, вам все равно придется использовать функцию, а затем программно удалять цифры, либо использовать Метод 1.
Если ваша конфигурация разработана на базе современных типовых решений (БСП), то в вашем распоряжении есть готовые программные модули. Выясним, какой метод наиболее эффективен в этом случае.
В общем модуле СтроковыеФункцииКлиентСервер существует метод ЧислоЦифрамиПредметИсчисленияПрописью(). Он удобен тем, что позволяет не изобретать велосипед и использовать стандарт, принятый в продуктах 1С.
// Пример для лет
ТекстЛет = СтроковыеФункцииКлиентСервер.ЧислоЦифрамиПредметИсчисленияПрописью(Лет, "год,года,лет,м", Ложь);
Преимущество этого метода в том, что он централизован. Если правила русского языка или требования к оформлению изменятся (например, добавление рода предмета исчисления), вам не придется править код в десятках мест.
Рассмотрим ситуацию, когда данные выводятся в макет. Часто программисты пытаются вписать условия прямо в ячейку макета, что делать крайне неудобно. Проанализируем правильный алгоритм работы с областью макета:
СтажСтрокой).Пример комплексного формирования строки стажа:
Функция СформироватьПредставлениеСтажа(Лет, Месяцев, Дней) Экспорт
Результат = "";
Если Лет > 0 Тогда
Результат = Результат + СтрокаСЧислом(";%1 год;;%1 года;%1 лет;%1 года", Лет);
КонецЕсли;
Если Месяцев > 0 Тогда
Результат = Результат + ?(ЗначениеЗаполнено(Результат), " ", "")
+ СтрокаСЧислом(";%1 месяц;;%1 месяца;%1 месяцев;%1 месяца", Месяцев);
КонецЕсли;
Если Дней > 0 Тогда
Результат = Результат + ?(ЗначениеЗаполнено(Результат), " ", "")
+ СтрокаСЧислом(";%1 день;;%1 дня;%1 дней;%1 дня", Дней);
КонецЕсли;
Возврат ?(ЗначениеЗаполнено(Результат), Результат, "Стаж отсутствует");
КонецФункции
Затем в коде заполнения макета мы просто пишем:
ОбластьСправки = Макет.ПолучитьОбласть("Подпись");
ОбластьСправки.Параметры.СтажПолный = СформироватьПредставлениеСтажа(Лет, Мес, Дн);
ТабДок.Вывести(ОбластьСправки);
Подведем итог и выберем оптимальный путь решения задачи:
СтрокаСЧислом (Метод 2). Она работает на уровне ядра платформы и выполняется быстрее.Использование правильного склонения — это не просто вопрос красоты, это показатель качества программного продукта и уважения к пользователю. Разбирая подобные задачи, мы учимся писать более чистый, понятный и грамотный код.