Склонение числительных 1С: 1 год, 2 года, 5 лет

Дата: 19.09.2026 09:47:59
Строки
Числа
Печатные формы
Встроенный язык
Общие модули
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Склонение числительных в 1С — это выбор формы слова после числа: 1 год, 2 года, 5 лет, 11 лет, 21 год. Строго говоря, склоняется не числительное, а согласованное с ним существительное, но в поиске задачу называют так. Ниже правило выбора формы, общий модуль для любого слова, штатные ЧислоПрописью и СтрокаСЧислом, функции БСП и ошибки, из-за которых в документах появляются «11 год» и «двадцать один штука».

Код рассчитан на платформу 8.3. Общий модуль из статьи работает в любом режиме совместимости, а метод СтрокаСЧислом требует платформы 8.3.10 или новее.

Где встречается задача

  • Печатные формы. Срок договора «3 (три) года», гарантия «12 месяцев», стаж в справке, количество листов прописью.
  • Сообщения и оповещения. «Загружено 25 документов», «Осталось 3 дня до окончания срока оплаты».
  • Надписи на формах. «Выбрано 2 строки», «Найдено 11 позиций».
  • Отчёты и письма клиентам. «Просрочка 21 день», «Задолженность 14 дней».

Самый частый баг в таком коде — форму выбирают только по последней цифре, и в договор попадает «11 год».

Склонение числительных в 1С: правило 1, 2–4, 5–20 и исключение 11–14

У слова после целого числа три формы: как после единицы (год), как после двойки (года) и как после пятёрки (лет). Форму определяют две последние цифры числа, и проверять их нужно в таком порядке:

  1. Две последние цифры от 11 до 14 — форма «пять»: 11 лет, 12 лет, 114 лет. Это исключение проверяется первым.
  2. Последняя цифра 1 — форма «один»: 1 год, 21 год, 101 год.
  3. Последняя цифра 2, 3 или 4 — форма «два»: 2 года, 23 года, 104 года.
  4. Остальное (последняя цифра 0 или 5–9) — форма «пять»: 0 лет, 5 лет, 20 лет, 100 лет.

После дробного числа слово стоит в родительном падеже единственного числа: 0,5 года, 1,5 года, 7,5 года. На письме эта форма совпадает с формой «два», поэтому четвёртый вариант передавать не нужно.

ЧислоДве последние цифрыПоследняя цифраФормаРезультат
0000пять0 лет
1011один1 год
3033два3 года
11111пять (исключение)11 лет
12122пять (исключение)12 лет
21211один21 год
24244два24 года
111111пять (исключение)111 лет
122222два122 года
1,5два (дробное число)1,5 года

Универсальная функция: склонение слова после числа

Функции удобно держать в клиент-серверном общем модуле, чтобы вызывать их из формы, из печати и из фонового задания. Создайте общий модуль СклонениеПоЧислуКлиентСервер, включите флажки «Клиент (управляемое приложение)», «Сервер» и «Внешнее соединение» и вставьте код. Формы слова передаются одной строкой через запятую в порядке «для 1, для 2, для 5»: "год,года,лет", "день,дня,дней", "штука,штуки,штук".

// Общий модуль СклонениеПоЧислуКлиентСервер
// Флажки: Клиент (управляемое приложение), Сервер, Внешнее соединение;
// в конфигурации на обычных формах добавьте Клиент (обычное приложение).
// Работает в любом режиме совместимости: СтрРазделить и СтрШаблон не используются.

// Номер формы слова для числа:
// 1 - как после 1 (год), 2 - как после 2 (года), 3 - как после 5 (лет).
Функция НомерФормыСлова(Знач Число) Экспорт

    Если Число < 0 Тогда
        Число = -Число;
    КонецЕсли;

    // Дробные числа: 0,5 года, 1,5 года, 7,5 года
    Если Число <> Цел(Число) Тогда
        Возврат 2;
    КонецЕсли;

    // 11-14, 111-114, 211-214 - всегда "лет", какой бы ни была последняя цифра
    ДвеПоследние = Число % 100;
    Если ДвеПоследние >= 11 И ДвеПоследние <= 14 Тогда
        Возврат 3;
    КонецЕсли;

    Последняя = Число % 10;
    Если Последняя = 1 Тогда
        Возврат 1;
    ИначеЕсли Последняя >= 2 И Последняя <= 4 Тогда
        Возврат 2;
    КонецЕсли;

    Возврат 3;

КонецФункции

// Слово в форме, согласованной с числом.
// Формы - строка "год,года,лет": формы для 1, для 2 и для 5 через запятую.
Функция ФормаСлова(Знач Число, Знач Формы) Экспорт

    Варианты = ТриФормы(Формы);
    Возврат Варианты[НомерФормыСлова(Число) - 1];

КонецФункции

// Число цифрами и слово: "0 дней", "21 день", "1 024 штуки".
Функция ЧислоСоСловом(Знач Число, Знач Формы) Экспорт

    // Без ЧН=0 функция Формат для нуля возвращает пустую строку
    Возврат Формат(Число, "ЧН=0") + " " + ФормаСлова(Число, Формы);

КонецФункции

// Число прописью и слово: "одиннадцать лет", "двадцать одна штука".
// Род - "м", "ж" или "с": один год, одна штука, одно место.
Функция ЧислоПрописьюСоСловом(Знач Число, Знач Формы, Знач Род = "м") Экспорт

    Текст = ЧислоПрописью(Цел(Число), "Л=ru_RU", ПараметрыПредмета(Формы, Род));
    Возврат СтрочнаяПерваяБуква(СокрЛП(Текст));

КонецФункции

// Для договоров и справок: "3 (три) года",
// с Род = "ж" - "21 (двадцать одна) штука".
Функция ЧислоЦифрамиИПрописью(Знач Число, Знач Формы, Знач Род = "м") Экспорт

    Число = Цел(Число);

    // НП=Ложь - только числительное, без предмета исчисления
    Прописью = ЧислоПрописью(Число, "Л=ru_RU; НП=Ложь", ПараметрыПредмета(Формы, Род));

    Возврат Формат(Число, "ЧН=0") + " (" + СтрочнаяПерваяБуква(СокрЛП(Прописью)) + ") "
        + ФормаСлова(Число, Формы);

КонецФункции

// Служебные функции

// Разбирает "год, года, лет" в массив из трёх обрезанных строк.
Функция ТриФормы(Знач Формы)

    Текст = СтрЗаменить(Формы, ",", Символы.ПС);
    Если СтрЧислоСтрок(Текст) <> 3 Тогда
        ВызватьИсключение "Нужны три формы слова через запятую, например ""год,года,лет"". Передано: "
            + Формы;
    КонецЕсли;

    Результат = Новый Массив;
    Для НомерСтроки = 1 По 3 Цикл
        Результат.Добавить(СокрЛП(СтрПолучитьСтроку(Текст, НомерСтроки)));
    КонецЦикла;

    Возврат Результат;

КонецФункции

// Параметры предмета исчисления для ЧислоПрописью, дробная часть не выводится.
Функция ПараметрыПредмета(Знач Формы, Знач Род)

    Варианты = ТриФормы(Формы);
    Возврат Варианты[0] + ", " + Варианты[1] + ", " + Варианты[2] + ", " + Род + ", , , , , 0";

КонецФункции

Функция СтрочнаяПерваяБуква(Знач Текст)

    Возврат НРег(Лев(Текст, 1)) + Сред(Текст, 2);

КонецФункции

Проверьте модуль на граничных числах: цикл от 0 до 25 проходит через исключения 11–14 и через 21–24, где правило снова работает.

&НаКлиенте
Процедура ПроверитьСклонение(Команда)

    Для Количество = 0 По 25 Цикл
        Сообщить(СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(Количество, "год,года,лет"));
    КонецЦикла;
    // 0 лет, 1 год, 2 года, 5 лет, 11 лет, 14 лет, 21 год, 22 года, 25 лет

    Сообщить(СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(111, "год,года,лет"));  // 111 лет
    Сообщить(СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(1.5, "год,года,лет"));  // 1,5 года

    Сообщить(СклонениеПоЧислуКлиентСервер.ЧислоПрописьюСоСловом(21, "штука,штуки,штук", "ж"));
    // двадцать одна штука

    Сообщить(СклонениеПоЧислуКлиентСервер.ЧислоЦифрамиИПрописью(3, "год,года,лет"));
    // 3 (три) года

КонецПроцедуры

Разбор ключевых строк

  • Знак снимается в первых строках. Остаток от деления отрицательного числа тоже отрицательный: -21 % 10 равно −1. Без этой проверки вышло бы «−21 дней».
  • Дробь проверяется до остатков. Правило по последним цифрам имеет смысл только для целых чисел, поэтому при Число <> Цел(Число) функция сразу возвращает вторую форму.
  • 11–14 проверяются раньше последней цифры. У 111 остаток от деления на 100 равен 11: функция возвращает «лет» и до проверки единицы не доходит. Сравнение с самим числом 11 вместо остатка сломало бы 111, 211 и 1011.
  • ТриФормы заменяет запятые переводами строк и читает их через СтрПолучитьСтроку: эти функции есть в любой версии платформы, в отличие от СтрРазделить. Пробелы обрезаются, так что "год, года, лет" тоже подходит, а результат — обычный массив. Если форм не три, функция вызывает исключение: лучше упасть при отладке, чем напечатать клиенту «5 года».
  • Род нужен только прописи. Он меняет само числительное: один год, одна штука, одно место. На запись цифрами род не влияет.
  • Цел() перед ЧислоПрописью. Функции с прописью рассчитаны на целые числа: в параметрах предмета ноль знаков дробной части. Цел отбрасывает дробь без округления, поэтому округляйте до вызова.

Как вызывать: сообщения и печатные формы

С числом согласуется и глагол: «Загружен 1 документ», «Загружено 5 документов», «Осталась 1 минута», «Осталось 2 минуты». Три формы глагола передаются так же, как формы существительного. В печатной форме готовая строка уходит в параметр макета вместе с остальными параметрами области.

// Модуль формы обработки загрузки
&НаКлиенте
Процедура СообщитьИтогЗагрузки(Загружено)

    // Глагол тоже согласуется с числом
    Текст = СклонениеПоЧислуКлиентСервер.ФормаСлова(Загружено, "Загружен,Загружено,Загружено")
        + " " + СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(Загружено, "документ,документа,документов");

    ПоказатьОповещениеПользователя("Загрузка завершена", , Текст);
    // Загружен 1 документ, Загружено 3 документа, Загружено 11 документов

КонецПроцедуры

// Серверный код печати: модуль менеджера документа или общий модуль печати
Процедура ЗаполнитьСрокДоговора(ОбластьМакета, СрокЛет)

    ОбластьМакета.Параметры.СрокДоговора =
        СклонениеПоЧислуКлиентСервер.ЧислоЦифрамиИПрописью(СрокЛет, "год,года,лет");
    // 3 (три) года, 11 (одиннадцать) лет, 21 (двадцать один) год

КонецПроцедуры

Предмет исчисления прописью: функция ЧислоПрописью

Платформенная функция ЧислоПрописью(Число, ФорматнаяСтрока, ПараметрыПредметаИсчисления) знает правила склонения сама: ею печатают сумму прописью в счетах и актах. Третий параметр, предмет исчисления, задаёт слово после числа. Для русского языка это строка из девяти элементов через запятую:

ПозицияЧто задаётРублиГоды
1Форма целой части для 1рубльгод
2Форма для 2рублягода
3Форма для 5рублейлет
4Род целой части: м, ж или смм
5–7Три формы дробной частикопейка, копейки, копеекпусто
8Род дробной частижпусто
9Число знаков дробной части20
// Количество лет прописью
Текст = ЧислоПрописью(21, "Л=ru_RU", "год, года, лет, м, , , , , 0");
// Двадцать один год

// Женский род меняет само числительное
Текст = ЧислоПрописью(22, "Л=ru_RU", "штука, штуки, штук, ж, , , , , 0");
// Двадцать две штуки

// Сумма с копейками, как в счёте
Текст = ЧислоПрописью(251.30, "Л=ru_RU",
    "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2");
// Двести пятьдесят один рубль 30 копеек

// Копейки тоже прописью
Текст = ЧислоПрописью(251.30, "Л=ru_RU; ДП=Истина",
    "рубль, рубля, рублей, м, копейка, копейки, копеек, ж, 2");
// Двести пятьдесят один рубль тридцать копеек

// Только числительное, без слова
Текст = ЧислоПрописью(3, "Л=ru_RU; НП=Ложь", "год, года, лет, м, , , , , 0");
// Три

В форматной строке Л=ru_RU задаёт язык прописи, НП=Ложь отключает вывод предмета исчисления, НД=Ложь — названия дробной части, а ДП=Истина пишет дробную часть прописью. Результат начинается с заглавной буквы. Для суммы в счёте так и надо, а в середине фразы первую букву придётся сделать строчной, как в ЧислоПрописьюСоСловом из модуля.

СтрокаСЧислом: штатный метод с версии 8.3.10

В платформе 8.3.10 появился метод СтрокаСЧислом(Шаблон, Число, Вид, ФорматнаяСтрока). Он выбирает из шаблона фрагмент по правилам языка и подставляет в него число вместо %1. Шаблон состоит из шести фрагментов через точку с запятой, по одному на категорию числа из стандарта Unicode CLDR: zero, one, two, few, many, other. В русском языке используются четыре: one (1, 21, 101), few (2–4, 22–24), many (0, 5–20, 25–30) и other (дробные числа). Фрагменты zero и two оставляют пустыми.

// Платформа 8.3.10 и выше, режим совместимости не ниже 8.3.10
// Порядок фрагментов: zero; one; two; few; many; other
Шаблон = ";%1 год;;%1 года;%1 лет;%1 года";

Текст = СтрокаСЧислом(Шаблон, 21, ВидЧисловогоЗначения.Количественное, "Л=ru_RU");  // 21 год
Текст = СтрокаСЧислом(Шаблон, 11, ВидЧисловогоЗначения.Количественное, "Л=ru_RU");  // 11 лет
Текст = СтрокаСЧислом(Шаблон, 1.5, ВидЧисловогоЗначения.Количественное, "Л=ru_RU"); // 1,5 года

// В шаблон можно вынести всю фразу вместе с глаголом
Текст = СтрокаСЧислом(";Остался %1 день;;Осталось %1 дня;Осталось %1 дней;Осталось %1 дня",
    3, ВидЧисловогоЗначения.Количественное, "Л=ru_RU");
// Осталось 3 дня

Своя функция не нужна, а в мультиязычной конфигурации достаточно перевести шаблон: правила каждого языка платформа знает сама. Минусы — непривычный синтаксис шаблона и требование к версии: на платформе или в режиме совместимости ниже 8.3.10 вызов не скомпилируется.

Что есть в БСП

В модуле СтроковыеФункцииКлиентСервер библиотеки стандартных подсистем давно есть функция ЧислоЦифрамиПредметИсчисленияПрописью(Число, ПараметрыПредметаИсчисления): для 23 и "минуту,минуты,минут" она вернёт «23 минуты». С БСП 2.4.3 эта функция помечена устаревшей и оставлена для совместимости. Взамен разработчики библиотеки предлагают СтрокаСЧисломДляЛюбогоЯзыка из того же модуля — обёртку над СтрокаСЧислом, которая не вызывает исключение, если в шаблоне нет строки для текущего языка. Шаблон в неё передают через НСтр.

// БСП 2.4.3 и новее: шаблон в НСтр, правила берутся по текущему языку
Текст = СтроковыеФункцииКлиентСервер.СтрокаСЧисломДляЛюбогоЯзыка(
    НСтр("ru = ';%1 день;;%1 дня;%1 дней;%1 дня'"), 21);
// 21 день

// Устаревший вариант, встречается в старом коде
Текст = СтроковыеФункцииКлиентСервер.ЧислоЦифрамиПредметИсчисленияПрописью(23, "минуту,минуты,минут");
// 23 минуты

Параметры функций БСП меняются от версии к версии, так что сверьтесь с описанием в модуле своей конфигурации.

СпособРезультатТребованияКогда брать
Своя функция ЧислоСоСловом21 деньЛюбая версия и конфигурацияСообщения, надписи и отчёты в русскоязычной конфигурации
ЧислоПрописьюДвадцать один деньЛюбая версияСуммы и количества прописью в печатных формах
СтрокаСЧисломОстался 21 деньПлатформа и режим совместимости 8.3.10+Мультиязычные конфигурации, фразы целиком
БСП СтрокаСЧисломДляЛюбогоЯзыка21 деньБСП 2.4.3+Конфигурация на БСП, новый код

Типичные ошибки

  • «11 год», «12 года», «111 год». Форма выбирается только по последней цифре. Заплатка Если Число % 10 = 1 И Число <> 11 чинит 11, но оставляет «111 год» и «211 год». Проверяйте остаток от деления на 100.
  • «Пять года», «Два лет». Формы в параметрах переставлены. И наша функция, и ЧислоПрописью ждут порядок «для 1, для 2, для 5»: год, года, лет.
  • «Двадцать один штука», «Два штуки». Для слова женского рода указан род м. Для «штука», «неделя» нужен ж, для «место», «наименование» — с.
  • « дней» без числа. Формат(0) без ЧН=0 возвращает пустую строку.
  • «1 года» в печатной форме. Число выведено с округлением, например Формат(1.3, "ЧДЦ=0") даёт «1», а форма выбрана по исходному 1,3. Округлите число один раз и передавайте одно значение и в Формат, и в ФормаСлова.
  • «Процедура или функция с указанным именем не определена (СтрокаСЧислом)». Платформа или режим совместимости конфигурации ниже 8.3.10. Используйте свою функцию или поднимите режим совместимости, если конфигурация это допускает.
  • «Операции сравнения на больше-меньше допустимы только для значений совпадающих примитивных типов (Булево, Число, Строка, Дата)». Количество пришло строкой из файла или HTTP-запроса, и код падает на Число < 0. Приведите значение функцией Число() до вызова, а для ненадёжного источника сначала проверьте тип значения.

Частые вопросы

Как вывести количество лет прописью, например стаж?

Посчитайте полные годы между датами и передайте их в ЧислоСоСловом или ЧислоПрописьюСоСловом. Простая разность годов даёт лишний год, если годовщина в текущем году ещё не наступила.

// Полных лет между датами: стаж, возраст, срок владения
Функция ПолныхЛет(Знач ДатаНачала, Знач ДатаОкончания) Экспорт

    ДатаНачала = НачалоДня(ДатаНачала);
    ДатаОкончания = НачалоДня(ДатаОкончания);

    Лет = Год(ДатаОкончания) - Год(ДатаНачала);
    Если ДобавитьМесяц(ДатаНачала, Лет * 12) > ДатаОкончания Тогда
        Лет = Лет - 1; // годовщина в этом году ещё не наступила
    КонецЕсли;

    Возврат Макс(Лет, 0);

КонецФункции

// Вызов: "Стаж: 11 лет"
// Текст = "Стаж: " + СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(
//     ПолныхЛет(ДатаПриема, ТекущаяДатаСеанса()), "год,года,лет");

Как склонять дни, месяцы и штуки одной функцией?

Передавайте формы нужного слова: "день,дня,дней", "месяц,месяца,месяцев", "позиция,позиции,позиций". Если слово нужно во многих местах, заведите в общем модуле функцию вроде ФормыДень(), которая возвращает эту строку.

Можно ли склонять прямо в запросе или в отчёте на СКД?

В языке запросов подходящих функций нет, а собирать форму через ВЫБОР громоздко. В отчёте на СКД добавьте вычисляемое поле с выражением вида СклонениеПоЧислуКлиентСервер.ЧислоСоСловом(Просрочка, "день,дня,дней"): в выражениях схемы можно вызывать экспортные функции неглобальных общих модулей с флажком «Сервер». В обычном коде склоняйте после выполнения запроса, при выводе результата.

Как быть с английским интерфейсом?

В английском две формы: 1 year, 2 years. Здесь удобнее СтрокаСЧислом с шаблоном ";%1 year;;;;%1 years" и кодом языка Л=en. В многоязычной конфигурации храните шаблоны для всех языков в НСтр и не собирайте фразы из кусков.

Когда проще заказать

Если в договоре, акте или справке нужно поправить склонения, сумму прописью или добавить новые поля, это типовая доработка печатных форм 1С. Опишите, что должно получиться, и разместите задачу на площадке: оценка бесплатная, ответ — в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.