Как задать дату без указания дня для отнесения документа к месяцу в 1С

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

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

Ограничения типа Дата в платформе 1С

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

  1. Дата и время
  2. Дата
  3. Время

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

Почему опасно обрезать стандартный реквизит Дата

Иногда разработчики пытаются принудительно изменить стандартный реквизит документа Дата в обработчике события перед записью:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Дата = НачалоМесяца(Дата);
КонецПроцедуры

Проанализируем последствия такого подхода. Если все документы за месяц получают одинаковую дату и время (например, 01.05.2026 00:00:00), это влечет за собой серьезные архитектурные проблемы:

  1. Нарушение хронологии: документы теряют естественный порядок следования во времени.
  2. Искажение Момента времени: могут некорректно работать механизмы проведения по партиям, расчет себестоимости и контроль остатков, где крайне важна последовательность проведения.
  3. Сложности в журналах документов: пользователям становится трудно ориентироваться в списке однотипных документов с одинаковой датой.

Рекомендуемый подход: отдельный реквизит периода

Рассмотрим типовое решение (Best Practice), которое применяется в конфигурациях 1С:Зарплата и Управление Персоналом, 1C:ERP и 1С:Бухгалтерия:

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

Посмотрим на пример заполнения реквизита при создании или изменении документа:


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

Настройка отображения даты без дня на форме

Чтобы пользователь видел только месяц и год, а не конкретный день, настроим свойства элемента формы. Важно указать не только формат отображения, но и формат редактирования:

  1. В свойстве Формат элемента формы указываем: ДФ='ММММ гггг' (например, «Май 2026») или ДФ=MM.yyyy (например, «05.2026»).
  2. В свойстве ФорматРедактирования задаем аналогичный шаблон: ДФ=MM.yyyy или ДФ='ММММ гггг'. Если не заполнить это свойство, в момент редактирования платформа покажет стандартное поле ввода с днем.

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


ПредставлениеМесяца = Формат(Объект.ПериодРегистрации, "ДФ='ММММ гггг'");
// Результат: "Май 2026 г."

Выбор периода через диалог

Чтобы пользователю было удобно выбирать месяц без использования календаря с днями, в обработчике события НачалоВыбора поля ввода можно открыть стандартный диалог настройки периода:


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

Таким образом, сочетание отдельного реквизита с нормализацией через НачалоМесяца() и правильной настройки свойств Формат и ФорматРедактирования позволяет корректно отнести документ к месяцу без риска нарушить хронологию проведения в базе данных.

← На главную