При разработке собственных документов в конфигурациях, базирующихся на библиотеках 1С:ERP или 1С:ЗУП, программисты часто сталкиваются с необходимостью реализовать поле выбора месяца, аналогичное типовому реквизиту Месяц начисления. В типовых решениях это поле выглядит как строка (например, «Сентябрь 2018»), имеет стрелки регулирования и форму выбора периода, но при этом в самом объекте документа строкового реквизита с таким названием нет. Разберем подробно, как устроен этот механизм и как правильно реализовать его в своем расширении или новой конфигурации.
Первое, что важно понять: в базе данных месяц начисления никогда не хранится как строка. Использование строкового реквизита (например, «Сентябрь 2018») для хранения периода — это грубая методическая ошибка. Рассмотрим причины, по которым следует избегать хранения периода в виде текста:
Дата автоматически подстраивается под региональные настройки системы, в то время как строка останется неизменной.В типовых документах (например, «Премия» или «Начисление зарплаты») для хранения месяца используется реквизит с типом Дата, который обычно называется ПериодРегистрации. Стандартом разработки 1С принято записывать в этот реквизит первое число выбранного месяца. Например, для «Сентября 2018» в базе будет храниться значение 01.09.2018 00:00:00.
Если вам нужно просто вывести дату в красивом формате в форме списка или в поле на форме документа, не обязательно создавать дополнительные реквизиты формы. Проанализируем возможности свойства Формат.
Для колонки в списке документов или для поля ввода на форме достаточно установить свойство Формат. Чтобы дата отображалась как «Месяц Год», используйте следующую строку формата:
ДФ='ММММ гггг'
В этом случае система будет хранить полноценную дату, позволяя правильно сортировать и фильтровать документы, но пользователь будет видеть только название месяца и год. Однако у этого способа есть ограничение: если это поле ввода, пользователю придется вводить дату целиком (число, месяц, год), что не всегда удобно для задач кадрового учета или расчета зарплаты.
Разберем по шагам, как реализовать полноценное поле с кнопками регулирования и выбором месяца через форму, используя типовые механизмы. Для этого нам понадобится связать реквизит объекта (тип Дата) и реквизит формы (тип Строка).
Шаг 1. Настройка реквизитов
В объекте документа (например, Документ.МойДокумент) создаем реквизит ПериодРегистрации с типом Дата. На форме документа создаем реквизит формы (не реквизит объекта!) с именем МесяцНачисленияСтрокой и типом Строка.
Шаг 2. Настройка элемента формы
Размещаем реквизит МесяцНачисленияСтрокой на форме. В свойствах элемента (поля ввода) устанавливаем следующие флаги:
Шаг 3. Обработка событий на сервере
Чтобы при открытии документа в строковом поле отобразилось правильное значение, проанализируем процедуру ПриЧтенииНаСервере или ПриСозданииНаСервере. Нам нужно заполнить текстовое поле на основании даты:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Преобразуем дату документа в строку формата "Месяц ГГГГ"
Если ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
МесяцНачисленияСтрокой = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
КонецЕсли;
КонецПроцедуры
Шаг 4. Подключение типовых функций (библиотека ЗУП)
Если вы работаете в среде ERP или ЗУП, воспользуйтесь функциями общего модуля ЗарплатаКадрыКлиент. Рассмотрим примеры обработчиков событий для нашего строкового поля:
&НаКлиенте
Процедура МесяцНачисленияСтрокойПриИзменении(Элемент)
// Типовая процедура, которая парсит введенную строку и обновляет дату в Объекте
ЗарплатаКадрыКлиент.ВводМесяцаПриИзменении(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Модифицированность);
КонецПроцедуры
&НаКлиенте
Процедура МесяцНачисленияСтрокойНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Вызывает специальное окно выбора месяца (календарик)
ЗарплатаКадрыКлиент.ВводМесяцаНачалоВыбора(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Модифицированность);
КонецПроцедуры
&НаКлиенте
Процедура МесяцНачисленияСтрокойРегулирование(Элемент, Направление, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
// Позволяет менять месяц стрелками "вверх-вниз"
ЗарплатаКадрыКлиент.ВводМесяцаРегулирование(ЭтаФорма, "Объект.ПериодРегистрации", "МесяцНачисленияСтрокой", Направление, Модифицированность);
КонецПроцедуры
Выясним причину частой ошибки начинающих разработчиков, когда значение в поле вроде бы меняется, но после записи документа исчезает. Это происходит, если вы пытаетесь напрямую записывать значение в строковый реквизит формы в процедуре ПередЗаписьюНаСервере, забывая обновить основной реквизит объекта ПериодРегистрации.
Важное правило: Источником истины всегда является Объект.ПериодРегистрации. Реквизит формы МесяцНачисленияСтрокой — это лишь визуальное представление. При любых манипуляциях на форме (вводе текста, нажатии стрелок) код должен в первую очередь рассчитывать и записывать дату в Объект.ПериодРегистрации. При записи документа система сохранит именно дату. При следующем открытии формы процедура ПриСозданииНаСервере снова прочитает эту дату и сформирует из нее строку для отображения.
Рассмотрим, как правильно отобразить месяц в списке документов. Вместо создания вычисляемых полей или отдельных строковых реквизитов в таблице БД, проанализируем настройки динамического списка:
ПериодРегистрации.ДФ='ММММ гггг'.Таким образом, мы получаем элегантное решение: в базе данных хранится компактная и удобная для индексов Дата, а пользователь во всем интерфейсе (и в формах, и в списках) видит привычное название месяца и года.