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

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

