Как правильно склонять слово «день» в зависимости от числа в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием IT и автоматизация бизнеса
← На главную

При разработке печатных форм, отчетов или интерфейсных уведомлений в 1С:ERP часто возникает задача корректного вывода текстовых сообщений, содержащих количественные показатели. Одной из самых распространенных задач является склонение слова «день» (например: «1 день», «3 дня», «10 дней»). В этой статье мы подробно разберем все современные и классические способы решения этой задачи, доступные в платформе 1С:Предприятие 8.3.

Способ 1: Использование системной функции «СтрокаСЧислом»

Начиная с версии платформы 8.3.13, разработчикам доступна мощная встроенная функция СтрокаСЧислом. Она позволяет в одну строку кода упаковать логику склонения для разных числовых окончаний. Рассмотрим, как это работает на практике. Функция принимает форматную строку, в которой через точку с запятой перечисляются варианты написания слова для разных количеств.

Проанализируем структуру форматной строки. Она состоит из нескольких секций, которые соответствуют правилам русского языка:

  1. Первая секция: для чисел, оканчивающихся на 1 (например, 1, 21, 101), кроме 11.
  2. Вторая секция: для чисел, оканчивающихся на 2, 3, 4 (например, 2, 23, 44), кроме 12, 13, 14.
  3. Третья секция: для всех остальных чисел (0, 5-9, 11-14).
  4. Четвертая секция: используется для дробных чисел (в случае с днями используется редко, но синтаксис это предусматривает).

Посмотрим на пример реализации, который предложил автор темы для своей задачи:


КоличествоДней = 30; // или любое другое число
РезультатСклонения = СтрокаСЧислом(";Сроком на %1 день;;Сроком на %1 дня;Сроком на %1 дней;Сроком на %1 дня", КоличествоДней, ВидЧисловогоЗначения.Количественное, "L=ru");
// Для 30 вернет: "Сроком на 30 дней"
// Для 4 вернет: "Сроком на 4 дня"

Важно обратить внимание на параметр L=ru. Он явно указывает платформе, что нужно использовать правила русской морфологии. Без этого параметра на серверах с иными региональными настройками логика может отработать некорректно.

Способ 2: Функция «ПолучитьСклоненияСтрокиПоЧислу»

Если нам нужно более гибкое управление или мы не хотим вручную прописывать окончания «день», «дня», «дней», мы можем воспользоваться методом ПолучитьСклоненияСтрокиПоЧислу. Этот метод использует встроенный морфологический словарь платформы.

Рассмотрим алгоритм работы с этой функцией:


ЧислоОбъектов = 22;
ИмяОбъекта = "день";
МассивСклонений = ПолучитьСклоненияСтрокиПоЧислу(ИмяОбъекта, ЧислоОбъектов, "L=ru", "ПД=Именительный");

Если МассивСклонений.Количество() > 0 Тогда
    ТекстРезультат = Строка(ЧислоОбъектов) + " " + МассивСклонений[0];
    // Результат: "22 дня"
КонецЕсли;

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

Способ 3: Использование возможностей БСП в 1С:ERP

Так как конфигурация 1С:ERP построена на базе Библиотеки стандартных подсистем (БСП), нам доступны готовые программные интерфейсы. Выясним, как упростить себе жизнь, используя общий модуль СтроковыеФункцииКлиентСервер. Для быстрого поиска и изучения процедур библиотеки можно воспользоваться справочником по методам БСП с примерами использования.

В БСП существует функция ПредставлениеПериода, которая крайне полезна при работе с датами. Она умеет не просто склонять «дни», но и собирать сложные строки вида «1 год, 2 месяца и 5 дней». Однако для простого склонения одного слова чаще используют функции формирования представлений. Для автоматического расчета и перевода интервалов времени в читаемый текст можно использовать решение для расчета разницы между датами с корректным склонением единиц.

Рассмотрим пример использования функций БСП для формирования строк:


// Пример формирования строки через шаблоны БСП
Количество = 5;
Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыПрограммногоИнтерфейса(
    НСтр("ru = '%1 день;%1 дня;%1 дней'"), 
    Количество);

Здесь используется механизм НСтр, который также поддерживает синтаксис множественного числа (plural forms) при наличии соответствующих настроек в конфигурации.

Способ 4: Классический метод через «ЧислоПрописью»

До появления в платформе специализированных функций программисты часто использовали «хакерский» прием с системной функцией ЧислоПрописью. Этот метод до сих пор актуален для старых версий платформы или в случаях, когда нужно получить результат максимально быстро без написания сложных конструкций.

Суть метода заключается в использовании четвертого параметра функции — «ПараметрыПредметаИсчисления». Мы передаем туда строку с вариантами склонения слова, и 1С возвращает нам число вместе с нужным словом.


Количество = 21;
ФорматнаяСтрока = "L=ru; ДП=Ложь";
ПараметрыПредмета = "день, дня, дней, м, , , , , 0";
Результат = ЧислоПрописью(Количество, ФорматнаяСтрока, ПараметрыПредмета);
// Результат будет: "Двадцать один день" (если ДП=Истина) 
// Или можно скомбинировать формат для получения только слова.

Чтобы получить строку вида «21 день», можно использовать настройки формата, отключающие пропись самого числа, или просто выделить существительное из результата.

Способ 5: Самостоятельная реализация алгоритма склонения

Проанализируем математический алгоритм, который лежит в основе всех вышеперечисленных функций. Это полезно понимать для общего развития или в ситуациях, когда вы работаете в крайне ограниченных условиях (например, в очень старых внешних компонентах).

Правило склонения в русском языке для существительных, зависящих от целых чисел, опирается на остаток от деления:

  1. Если число оканчивается на 11, 12, 13, 14 — всегда «дней».
  2. Если последняя цифра 1 — «день».
  3. Если последняя цифра 2, 3, 4 — «дня».
  4. Если последняя цифра 5, 6, 7, 8, 9, 0 — «дней».

Реализуем это программно:


Функция СклонятьДни(ЧислоДней)
    
    Остаток100 = ЧислоДней % 100;
    Остаток10 = ЧислоДней % 10;
    
    Если Остаток100 >= 11 И Остаток100 <= 14 Тогда
        Возврат "дней";
    ИначеЕсли Остаток10 = 1 Тогда
        Возврат "день";
    ИначеЕсли Остаток10 >= 2 И Остаток10 <= 4 Тогда
        Возврат "дня";
    Иначе
        Возврат "дней";
    КонецЕсли;
    
КонецФункции

Подведем итоги

Для современной разработки в среде 1С:ERP наиболее предпочтительным является Способ №1 (СтрокаСЧислом). Он лаконичен, производителен и поддерживается платформой на уровне системного кода. Если же задача стоит шире (например, нужно склонять произвольные названия номенклатуры или должностей), лучше использовать Способ №2 (ПолучитьСклоненияСтрокиПоЧислу), так как он задействует встроенные лингвистические алгоритмы 1С.

Использование любого из этих методов гарантирует, что ваши печатные формы будут выглядеть профессионально, а пользователи не будут спотыкаться о фразы типа «30 день» или «1 дней».

← На главную