diamond АШ Tlg

Как в 1С ЗУП сделать действие выбора месяца или квартала, выглядящее как в типовых документах

Делаем выбор периодов красиво, как в типовом ЗУПе

Выбор месяца

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

Выбор месяца

Для этого в дизайнере формы 1С нужно создать два реквизита, один со значением типа Дата, второй c типом Строка. Для хранения значения Период я выбрал реквизит формы, но можно и реквизит объекта:

Форма

На форму для отображения пользователю выводим поле с типом строка! У поля отключите свойство редактирование текста. Чтобы отобразилась кнопка с календариком нужно установить следующие свойства (картинку лучше выбрать ПолеВводаКалендарь):

Свойства поля Свойства поля

Вешаем следующую процедуру на событие НачалоВыбора для текстового поля ПериодПредставление:

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

При использовании реквизита объекта применяем такой вариант:

&НаКлиенте
Процедура ПериодПредставлениеНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
        
    ЗарплатаКадрыКлиент.ВводМесяцаНачалоВыбора(ЭтотОбъект, ЭтотОбъект, "Объект.Период", "ПериодПредставление", Истина);
    
КонецПроцедуры    

Чтобы текст поля выбора даты заполнялся при открытии формы нужно добавить следующее:

&НаСервере
Процедура ПриЧтенииНаСервере(ТекущийОбъект)
        
    ЗарплатаКадрыКлиентСервер.ЗаполнитьМесяцПоДате(ЭтотОбъект, "Объект.Период", "ПериодПредставление");
    
КонецПроцедуры    

Выбор квартала

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

// {
// АШ
Процедура ВводКварталаНачалоВыбора(Форма, РедактируемыйОбъект, ПутьРеквизита, ПутьРеквизитаПредставления, ИзменитьМодифицированность = Истина, ОповещениеЗавершения = Неопределено, ЗначениеМесяцаПоУмолчанию = Неопределено) Экспорт
	
    ДополнительныеПараметры = Новый Структура;
    ДополнительныеПараметры.Вставить("Форма", Форма);
    ДополнительныеПараметры.Вставить("РедактируемыйОбъект", РедактируемыйОбъект);
    ДополнительныеПараметры.Вставить("ПутьРеквизита", ПутьРеквизита);
    ДополнительныеПараметры.Вставить("ПутьРеквизитаПредставления", ПутьРеквизитаПредставления);
    ДополнительныеПараметры.Вставить("ИзменитьМодифицированность", ИзменитьМодифицированность);
    ДополнительныеПараметры.Вставить("ОповещениеЗавершения", ОповещениеЗавершения);
	
    Значение = ОбщегоНазначенияКлиентСервер.ПолучитьРеквизитФормыПоПути(РедактируемыйОбъект, ПутьРеквизита);
    Если Значение <= '19000101' Тогда
		
        Если ЗначениеМесяцаПоУмолчанию = Неопределено Тогда
            Значение = НачалоКвартала(ОбщегоНазначенияКлиент.ДатаСеанса());  // замена на НачалоКвартала
        Иначе
            Значение = НачалоКвартала(ЗначениеМесяцаПоУмолчанию);            // замена на НачалоКвартала
        КонецЕсли;
		
    КонецЕсли; 
	
    Оповещение = Новый ОписаниеОповещения("ВводКварталаНачалоВыбораЗавершение", ЭтотОбъект, ДополнительныеПараметры); // замена метода
	
    ОткрытьФорму("ОбщаяФорма.ВыборПериода", 
        Новый Структура("Значение,РежимВыбораПериода,ЗапрашиватьРежимВыбораПериодаУВладельца", Значение, "Квартал", Ложь), // замена Месяц на Квартал
        Форма, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры

Процедура ВводКварталаНачалоВыбораЗавершение(ВыбранноеЗначение, ДополнительныеПараметры) Экспорт

    Форма = ДополнительныеПараметры.Форма;
    РедактируемыйОбъект = ДополнительныеПараметры.РедактируемыйОбъект;
    ПутьРеквизита = ДополнительныеПараметры.ПутьРеквизита;
    ПутьРеквизитаПредставления = ДополнительныеПараметры.ПутьРеквизитаПредставления;
    ИзменитьМодифицированность = ДополнительныеПараметры.ИзменитьМодифицированность;
    ОповещениеЗавершения = ДополнительныеПараметры.ОповещениеЗавершения;
	
    Если ВыбранноеЗначение = Неопределено Тогда
		
        Если ОповещениеЗавершения <> Неопределено Тогда
            ВыполнитьОбработкуОповещения(ОповещениеЗавершения, Ложь);
        КонецЕсли;
		
    Иначе
		
        Значение = ВыбранноеЗначение;
		
        ОбщегоНазначенияКлиентСервер.УстановитьРеквизитФормыПоПути(РедактируемыйОбъект, ПутьРеквизита, Значение);
        Представление = ЗарплатаКадрыКлиентСервер.ПолучитьПредставлениеКвартала(Значение);  // замена на представление квартала
        ОбщегоНазначенияКлиентСервер.УстановитьРеквизитФормыПоПути(РедактируемыйОбъект, ПутьРеквизитаПредставления, Представление);
		
        Если ИзменитьМодифицированность Тогда 
            Форма.Модифицированность = Истина;
        КонецЕсли;
		
        Если ОповещениеЗавершения <> Неопределено Тогда
            ВыполнитьОбработкуОповещения(ОповещениеЗавершения, Истина);
        КонецЕсли;
		
    КонецЕсли;
	
    Если ОповещениеЗавершения = Неопределено Тогда
        Форма.ОбновитьОтображениеДанных();
    КонецЕсли;
	
КонецПроцедуры
// }

Чтобы форматирование работало при открытии формы, требуется в её модуле добавить вызов:

&НаСервере
Процедура ПриСозданииНаСервере()
    ПериодПредставление = ЗарплатаКадрыКлиентСервер.ПолучитьПредставлениеКвартала(Объект.Период);
КонецПроцедуры

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

вычисляемое поле для отображения квартала

Выводим новое поле ПериодПредставление на форму и смотрим результат:

квартал на форме списка

В типовом методе ЗарплатаКадрыКлиентСервер.ПолучитьПредставлениеКвартала() используется функция форматирования платформы 1С, запросов СУБД в цикле не будет.