При работе с датами в платформе 1С разработчики часто сталкиваются с задачей вывода названия месяца в родительном падеже (например, «января» вместо «Январь»). Разберем, как устроен механизм форматирования встроенной функции Формат().
Важно учитывать ключевую особенность платформы: спецификатор MMMM сам по себе (при строке формата "ДФ=MMMM") всегда возвращает название месяца в **именительном падеже** («Январь»). Однако родительный падеж («января») включается автоматически, если в строке формата присутствуют компоненты дня, такие как d или dd.
Рассмотрим базовое решение, основанное на получении даты с днем и последующем отсечении числа. Если мы применим формат "ДФ=dd.MMMM", платформа сформирует строку вида «15.января» или «01.января» (в зависимости от значения дня).
Посмотрим на пример кода с использованием функции Сред():
МесяцВРодительном = Сред(Формат(ДатаКонтекста, "ДФ=dd.MMMM"), 4);
В данном случае с помощью функции Сред() мы пропускаем первые 3 символа (два символа дня и точку) и получаем наименование месяца в родительном падеже.
Выделение подстроки по фиксированному индексу может быть не всегда наглядным. Разберем более надежный подход с использованием метода СтрРазбить().
Проанализируем пример кода с явным разделителем:
МассивСтрок = СтрРазбить(Формат(ДатаКонтекста, "ДФ='d_MMMM'"), "_");
МесяцВРодительном = МассивСтрок[1];
В этом варианте мы явно задаем разделитель "_" между днем и месяцем. Функция СтрРазбить() помещает день в первый элемент массива, а название месяца в родительном падеже — во второй элемент массива (индекс 1).
В современных версиях платформы 1С присутствуют встроенные механизмы склонения представлений объектов и произвольных строк. Посмотрим, как просклонять полученное название месяца без ухищрений с форматированием дня:
ИменительныйПадеж = Формат(ДатаКонтекста, "ДФ=MMMM");
МассивВариантов = ПолучитьСклоненияСтроки(ИменительныйПадеж, "Л=ru_RU", "ПД=Родительный");
МесяцВРодительном = МассивВариантов[0];
Функция ПолучитьСклоненияСтроки() работает кроссплатформенно (включая серверы под управлением Linux) и возвращает массив просклоненных вариантов.
Так как количество месяцев фиксировано и составляет всего 12 вариантов, мы можем использовать явное сопоставление через массив, соответствие или конструкцию Если ... ИначеЕсли.
Рассмотрим пример с использованием массива наименований:
МассивМесяцев = Новый Массив;
МассивМесяцев.Добавить("января");
МассивМесяцев.Добавить("февраля");
МассивМесяцев.Добавить("марта");
МассивМесяцев.Добавить("апреля");
МассивМесяцев.Добавить("мая");
МассивМесяцев.Добавить("июня");
МассивМесяцев.Добавить("июля");
МассивМесяцев.Добавить("августа");
МассивМесяцев.Добавить("сентября");
МассивМесяцев.Добавить("октября");
МассивМесяцев.Добавить("ноября");
МассивМесяцев.Добавить("декабря");
НомерМесяца = Месяц(ДатаКонтекста);
МесяцВРодительном = МассивМесяцев[НомерМесяца - 1];
При извлечении месяца из формата с днем платформа возвращает слово в нижнем регистре со строчной буквы («января»). В зависимости от требований к оформлению печатных форм, изменим регистр первой буквы или всей строки:
ТРег(): МесяцСЗаглавной = ТРег(МесяцВРодительном);ВРег(): МесяцВВерхнемРегистре = ВРег(МесяцВРодительном);