Как реализовать выбор месяца в формате «Месяц Год» в документах 1С:ERP и ЗУП

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

При разработке собственных документов в конфигурациях, базирующихся на библиотеках 1С:ERP или 1С:ЗУП, программисты часто сталкиваются с необходимостью реализовать поле выбора месяца, аналогичное типовому реквизиту Месяц начисления. В типовых решениях это поле выглядит как строка (например, «Сентябрь 2018»), имеет стрелки регулирования и форму выбора периода, но при этом в самом объекте документа строкового реквизита с таким названием нет. Разберем подробно, как устроен этот механизм и как правильно реализовать его в своем расширении или новой конфигурации.

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

Первое, что важно понять: в базе данных месяц начисления никогда не хранится как строка. Использование строкового реквизита (например, «Сентябрь 2018») для хранения периода — это грубая методическая ошибка. Рассмотрим причины, по которым следует избегать хранения периода в виде текста:

  1. Сортировка в списках: Если вы сохраните месяц как строку, то при попытке отсортировать список документов по этой колонке система будет использовать алфавитный порядок. В результате «Август» окажется выше «Января», что сделает работу пользователя невозможной.
  2. Сложность запросов: Выборка данных за определенный интервал (например, за квартал или год) по строковому полю крайне непроизводительна и требует сложных преобразований типов внутри запроса.
  3. Локализация: Тип Дата автоматически подстраивается под региональные настройки системы, в то время как строка останется неизменной.

В типовых документах (например, «Премия» или «Начисление зарплаты») для хранения месяца используется реквизит с типом Дата, который обычно называется ПериодРегистрации. Стандартом разработки 1С принято записывать в этот реквизит первое число выбранного месяца. Например, для «Сентября 2018» в базе будет храниться значение 01.09.2018 00:00:00.

Способ 1: Использование форматной строки (самый простой вариант)

Если вам нужно просто вывести дату в красивом формате в форме списка или в поле на форме документа, не обязательно создавать дополнительные реквизиты формы. Проанализируем возможности свойства Формат.

Для колонки в списке документов или для поля ввода на форме достаточно установить свойство Формат. Чтобы дата отображалась как «Месяц Год», используйте следующую строку формата:

ДФ='ММММ гггг'

В этом случае система будет хранить полноценную дату, позволяя правильно сортировать и фильтровать документы, но пользователь будет видеть только название месяца и год. Однако у этого способа есть ограничение: если это поле ввода, пользователю придется вводить дату целиком (число, месяц, год), что не всегда удобно для задач кадрового учета или расчета зарплаты.

Способ 2: Программная реализация «как в типовых» (ERP/ЗУП)

Разберем по шагам, как реализовать полноценное поле с кнопками регулирования и выбором месяца через форму, используя типовые механизмы. Для этого нам понадобится связать реквизит объекта (тип Дата) и реквизит формы (тип Строка).

Шаг 1. Настройка реквизитов

В объекте документа (например, Документ.МойДокумент) создаем реквизит ПериодРегистрации с типом Дата. На форме документа создаем реквизит формы (не реквизит объекта!) с именем МесяцНачисленияСтрокой и типом Строка.

Шаг 2. Настройка элемента формы

Размещаем реквизит МесяцНачисленияСтрокой на форме. В свойствах элемента (поля ввода) устанавливаем следующие флаги:

Шаг 3. Обработка событий на сервере

Чтобы при открытии документа в строковом поле отобразилось правильное значение, проанализируем процедуру ПриЧтенииНаСервере или ПриСозданииНаСервере. Нам нужно заполнить текстовое поле на основании даты:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Преобразуем дату документа в строку формата "Месяц ГГГГ"
    Если ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
        МесяцНачисленияСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
    КонецЕсли;
КонецПроцедуры

Шаг 4. Подключение типовых функций (библиотека ЗУП)

Если вы работаете в среде ERP или ЗУП, воспользуйтесь функциями общего модуля ЗарплатаКадрыКлиент. Рассмотрим примеры обработчиков событий для нашего строкового поля:


&НаКлиенте
Процедура МесяцНачисленияСтрокойПриИзменении(Элемент)
    // Типовая процедура, которая парсит введенную строку и обновляет дату в Объекте
    ЗарплатаКадрыКлиент.ВводМесяцаПриИзменении(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Модифицированность);
КонецПроцедуры

&НаКлиенте
Процедура МесяцНачисленияСтрокойНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Вызывает специальное окно выбора месяца (календарик)
    ЗарплатаКадрыКлиент.ВводМесяцаНачалоВыбора(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Модифицированность);
КонецПроцедуры

&НаКлиенте
Процедура МесяцНачисленияСтрокойРегулирование(Элемент, Направление, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    // Позволяет менять месяц стрелками "вверх-вниз"
    ЗарплатаКадрыКлиент.ВводМесяцаРегулирование(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Направление, Модифицированность);
КонецПроцедуры

Почему изменения не сохраняются?

Выясним причину частой ошибки начинающих разработчиков, когда значение в поле вроде бы меняется, но после записи документа исчезает. Это происходит, если вы пытаетесь напрямую записывать значение в строковый реквизит формы в процедуре ПередЗаписьюНаСервере, забывая обновить основной реквизит объекта ПериодРегистрации.

Важное правило: Источником истины всегда является Объект.ПериодРегистрации. Реквизит формы МесяцНачисленияСтрокой — это лишь визуальное представление. При любых манипуляциях на форме (вводе текста, нажатии стрелок) код должен в первую очередь рассчитывать и записывать дату в Объект.ПериодРегистрации. При записи документа система сохранит именно дату. При следующем открытии формы процедура ПриСозданииНаСервере снова прочитает эту дату и сформирует из нее строку для отображения.

Вывод месяца в форме списка

Рассмотрим, как правильно отобразить месяц в списке документов. Вместо создания вычисляемых полей или отдельных строковых реквизитов в таблице БД, проанализируем настройки динамического списка:

  1. Откройте форму списка документа.
  2. Найдите в дереве элементов поле, соответствующее ПериодРегистрации.
  3. В свойствах этого элемента найдите пункт Формат.
  4. Укажите ДФ='ММММ гггг'.

Таким образом, мы получаем элегантное решение: в базе данных хранится компактная и удобная для индексов Дата, а пользователь во всем интерфейсе (и в формах, и в списках) видит привычное название месяца и года.

← На главную