Как реализовать ввод и отображение даты только как года в управляемых формах 1С

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

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

Способ 1. Настройка свойств «Формат» и «Формат редактирования»

Самый простой путь, который часто первым приходит в голову — это использование встроенных возможностей оформления элементов формы. Если наш реквизит имеет тип Дата, мы можем попытаться ограничить его отображение только годом. Для интерактивной проверки и настройки свойств элементов формы в пользовательском сеансе подойдёт обработка для редактирования свойств элементов открытых форм.

Разберем по шагам, как это настроить в конфигураторе:

  1. Выделим элемент формы (поле ввода), связанный с реквизитом.
  2. В палитре свойств найдем пункт Формат. Установим значение ДФ=гггг. Это обеспечит корректное отображение (например, «2023» вместо «01.01.2023»).
  3. Найдем свойство Формат редактирования. Здесь также укажем ДФ=гггг.

Проанализируем ситуацию: на первый взгляд, решение идеально. Однако у него есть существенный недостаток. При нажатии на кнопку выбора (три точки) пользователю все равно откроется стандартный календарь. Даже если пользователь выберет 15 мая, в поле отобразится только год, но сам факт открытия календаря для выбора года крайне неудобен. Чтобы минимизировать это, рекомендуется в свойствах поля ввода установить флаг КнопкаВыбора = Нет. В этом случае пользователь сможет вводить цифры года только с клавиатуры.

Способ 2. Использование списка выбора (Drop-down list)

Если диапазон лет, доступных для выбора, ограничен (например, текущий год плюс-минус 5 лет), мы можем предложить пользователю выбор из выпадающего списка. Это значительно ускоряет работу и исключает ошибки ввода.

Для реализации этого метода выполним следующие действия:

  1. Установим у элемента формы свойство РежимВыбораИзСписка в значение Истина.
  2. В модуле формы, в процедуре ПриСозданииНаСервере, программно заполним этот список.

    Рассмотрим пример кода:

    
    &НаСервере
    Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
        
        // Определяем диапазон лет
        ТекущийГод = Год(ТекущаяДата());
        Для текГод = (ТекущийГод - 10) По (ТекущийГод + 1) Цикл
            // Добавляем значение: сама дата на начало года и представление в виде строки
            Элементы.ПериодГод.СписокВыбора.Добавить(Дата(текГод, 1, 1), Строка(текГод));
        КонецЦикла;
        
    КонецПроцедуры
    

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

    Способ 3. Вспомогательный числовой реквизит на форме (Рекомендуемый)

    Как отмечали участники обсуждения на форуме, наиболее надежный и гибкий метод — это разделение хранения данных и их представления. Мы создаем на форме реквизит с типом Число (длина 4, точность 0), а в объекте (документе или справочнике) оставляем реквизит Дата.

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

    Рассмотрим алгоритм реализации:

    1. Создаем реквизит формы ГодЧислом (тип Число).
    2. Размещаем его на форме. В свойствах элемента включаем КнопкаРегулирования = Истина.
    3. Настраиваем синхронизацию между этим числом и реальной датой объекта.

    Для синхронизации нам понадобится написать код в событиях формы:

    
    &НаСервере
    Процедура ПриЧтенииНаСервере(ТекущийОбъект)
        // Извлекаем год из даты объекта при открытии формы
        Если ЗначениеЗаполнено(Объект.ДатаПериода) Тогда
            ГодЧислом = Год(Объект.ДатаПериода);
        Иначе
            ГодЧислом = Год(ТекущаяДата());
        КонецЕсли;
    КонецПроцедуры
    
    &НаСервере
    Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
        // Записываем дату обратно в объект, формируя её из числа
        ТекущийОбъект.ДатаПериода = Дата(ГодЧислом, 1, 1);
    КонецПроцедуры
    

    Важный момент: если вы меняете число прямо на форме и хотите, чтобы другие элементы (например, динамические списки) реагировали мгновенно, добавьте обработчик события ПриИзменении для поля ГодЧислом, где принудительно обновляйте дату объекта.

    Способ 4. Перехват события окончания ввода текста

    Если заказчик настаивает на сохранении типа Дата и хочет «свободный ввод», мы можем использовать событие ОкончаниеВводаТекста. Это позволит пользователю написать «2024», а системе — автоматически превратить это в «01.01.2024».

    Проанализируем, как реализовать такой перехват:

    
    &НаКлиенте
    Процедура ПериодГодОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
        
        // Пытаемся преобразовать введенный текст в число
        Попытка
            ВведенныйГод = Число(Текст);
            Если ВведенныйГод > 1900 И ВведенныйГод < 2100 Тогда
                Объект.ДатаПериода = Дата(ВведенныйГод, 1, 1);
                СтандартнаяОбработка = Ложь; // Отменяем стандартную обработку 1С
            КонецЕсли;
        Исключение
            // Если ввели не число, сработает стандартный механизм
        КонецПопытки;
        
    КонецПроцедуры
    

    Сравнение подходов

    Посмотрим на сравнительную таблицу методов, чтобы выбрать оптимальный для вашего случая:

    • Форматирование (гггг): Самый быстрый в реализации, но неудобен из-за выскакивающего календаря. Подходит для простых отчетов.
    • Список выбора: Идеален для фиксированных периодов. Максимальная защита от ошибок ввода.
    • Числовое поле + Синхронизация: Самый профессиональный подход. Позволяет использовать кнопки «больше/меньше» и полностью контролировать поведение интерфейса.
    • Программный вызов диалога: Если в конфигурации используется БСП (Библиотека стандартных подсистем), можно использовать функции работы с периодами, но это требует более глубокого погружения в код библиотеки.

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

    В завершение отметим, что выбор метода зависит от требований постановщика задачи. Если требуется строгое соответствие формату — используйте ФорматРедактирования. Если требуется удобство пользователя — используйте СписокВыбора или Число с кнопками регулирования.

← На главную