Организация выбора месяца из списка


Пришлось столкнуться с такой проблемой, как выбор месяца из ниспадающего списка (с элементами вида «НазваниеМесяца Год») с возможностью изменения года. Хочу предложить вариант реализации данного механизма, может кому и пригодится)

Итак, мы имеем некий объект с реквизитом «Месяц» с типом «Строка», который находится у нас на управляемой форме, куда и будет вписываться название месяца и год. Прежде всего, при открытии формы необходимо сформировать список выбора (например, на текущий год):

&НаКлиенте
Процедура ПриОткрытии(Отказ)


СформироватьСписокВыбораМесяца(Год(ТекущаяДата()));


КонецПроцедуры

Сама процедура формирования будет следующей:

Процедура СформироватьСписокВыбораМесяца(Год)

Элементы.Месяц.СписокВыбора.Очистить();
Элементы.Месяц.СписокВыбора.Добавить(Формат(Год-1, "ЧГ=0")); //для смены года
Для к = 1 По 12  Цикл
СформДата = Дата(Год, к, 1);
Наим = Формат(СформДата, "ДФ = ММММ_гггг");
Наим = СтрЗаменить(Наим, "_", " ");
Элементы.Месяц.СписокВыбора.Добавить(Наим);
КонецЦикла;
Элементы.Месяц.СписокВыбора.Добавить(Формат(Год+1, "ЧГ=0")); //для смены года


КонецПроцедуры

Далее организуем выбор из списка. Для этого нам понадобится событие нашего элемента «НачалоВыбораИзСписка»:

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


Если Объект.Месяц  "" Тогда

//реквизит уже заполнен, нужно формировать список для года, соответствующего заполнению
ВыбрГод = Число(Прав(Объект.Месяц, 4));
СформироватьСписокВыбораМесяца(ВыбрГод);
КонецЕсли;

СтандартнаяОбработка = Ложь;
ВыбранноеЗначение = Строка(ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент));
Если ВыбранноеЗначение  "" Тогда
Если СтрДлина(ВыбранноеЗначение)=4 Тогда

//выбрано значение, которое соответствует смене года в списке
Пока СтрДлина(ВыбранноеЗначение) = 4 Цикл

//цикл продолжается до тех пор, пока мы не выберем месяц
ВыбрГод = Число(ВыбранноеЗначение);
СформироватьСписокВыбораМесяца(ВыбрГод);
ВыбранноеЗначение = Строка(ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент));
КонецЦикла;
КонецЕсли;
Если ВыбранноеЗначение  "" Тогда

//выбрали месяц, а не пустое значение, запишем его

//если выбрали пустое значение, то в реквизите месяц сохранится значение, которое было до выбора
Объект.Месяц = ВыбранноеЗначение;
КонецЕсли;
КонецЕсли;
КонецПроцедуры

Далее можно делать с этим значением, что угодно. Например, нам нужно в некий реквизит подставить конец выбранного месяца. Тогда мы имеем реквизит объекта «КонецМесяца» с типом дата, создаем реквизит формы «Месяц» с типом строка и помещаем связанный с ним элемент на форму. Далее реализуем вышеописанный механизм с некоторыми изменениями:

&НаКлиенте
Процедура ПриОткрытии(Отказ)


Если ЗначениеЗаполнено(Объект.КонецМесяца) Тогда
Месяц = Формат(Объект.КонецМесяца, "ДФ = ММММ");

//формируем список на год, соответствующий заполненному реквизиту

СформироватьСписокВыбораМесяца(Год(Объект.КонецМесяца));
Иначе
Месяц = "";

//формируем список на текущий год

СформироватьСписокВыбораМесяца(Год(ТекущаяДата()));
КонецЕсли;


КонецПроцедуры

Событие «НачалоВыбораИзСписка» изменяем так, чтобы заполнялся реквизит «КонецМесяца». Помним, что «Месяц» — реквизит формы, а не объекта, поэтому убираем перед ним «Объект.» и заполняем реквизит «КонецМесяца»:

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


Если Месяц  "" Тогда

//реквизит уже заполнен, нужно формировать список для года, соответствующего заполнению
ВыбрГод = Число(Прав(Месяц, 4));
СформироватьСписокВыбораМесяца(ВыбрГод);
КонецЕсли;

СтандартнаяОбработка = Ложь;
ВыбранноеЗначение = Строка(ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент));
Если ВыбранноеЗначение  "" Тогда
Если СтрДлина(ВыбранноеЗначение)=4 Тогда

//выбрано значение, которое соответствует смене года в списке
Пока СтрДлина(ВыбранноеЗначение) = 4 Цикл

//цикл продолжается до тех пор, пока мы не выберем месяц
ВыбрГод = Число(ВыбранноеЗначение);
СформироватьСписокВыбораМесяца(ВыбрГод);
ВыбранноеЗначение = Строка(ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент));
КонецЦикла;
КонецЕсли;
Если ВыбранноеЗначение  "" Тогда

//выбрали месяц, а не пустое значение, запишем его

//если выбрали пустое значение, то в реквизите месяц сохранится значение, которое было до выбора
Месяц = ВыбранноеЗначение;

НомМесяца = (Найти("янвфевмарапрмайиюниюлавгсеноктноядек",Нрег(Лев(ВыбранноеЗначение,3)))+2)/3; //получаем номер месяца
ВыбрГод = Число(Прав(ВыбранноеЗначение, 4));
Объект.КонецМесяца = КонецМесяца(Дата(ВыбрГод, НомМесяца, 1));


КонецЕсли;
КонецЕсли;
КонецПроцедуры

Собственно вот и все) Вы также можете скачать обработку с примером: //infostart.ru/public/download.php?file=167551

16 Comments

  1. vipq7

    Спасибо, удобная штука…

    Reply
  2. RocKeR_13

    (1) vipq7, рад, что пригодилось)

    Reply
  3. alexandr851c

    Очень выручили. Огромное спасибо !!!

    Reply
  4. RocKeR_13

    (3) alexandr851c, честно говоря, когда публиковал, не думал, что многих заинтересует)) На здоровье)

    Reply
  5. karapuzzzz

    Спасибо. Идея с переходом между годами мне понравилась. Реализовал у себя с адаптированием под обычное приложение.

    Единственное замечание в том, что обычно за период принимают не конец месяца, а начало.

    Reply
  6. RocKeR_13

    (5) karapuzzzz, пожалуйста) ну как у вас не знаю, сколько ни делал доработок отчетов — везде нужен был именно конец месяца в качестве конца периода

    Reply
  7. nytlenc

    Спасибо! Респект. Очень пригодилось!

    Reply
  8. RocKeR_13

    (7) nytlenc, рад, что пригодилось! Успехов вам)

    Reply
  9. dsitiy

    А при нажатии на строчку с годом ничего не должно происходить?

    Я думал откроются месяца с предыдущим годом.

    Reply
  10. Anchoret

    Спасибо за пример, очень помог.

    (9) Orlanxxx, происходит, если сделать все правильно.

    Я в условиях сначала поставил равенство (=) и у меня тоже ничего не происходило при выборе года.

    Изменил на (<>) и все в порядке стало.

    Reply
  11. Makushimo

    Если выбрать год, потом еще раз год

    то вылетает с ошибкой

    надо в рекурсию заворачивать

    однозначно плюс

    Reply
  12. Yuriy.MW

    Чуток подкорректировал процедуры.

    Месяц — строка, реквизит формы

    ПериодРегистрации — Дата, реквизит объекта

    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
    
    Месяц = Формат(Объект.ПериодРегистрации, «ДФ=’MMMM yyyy'»);
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура СформироватьСписокВыбораМесяца(Год)
    
    Элементы.Месяц.СписокВыбора.Очистить();
    Элементы.Месяц.СписокВыбора.Добавить(Дата(Год-1, 1, 1), Формат(Год-1, «ЧГ=0»)); //для смены года
    Для к = 1 По 12  Цикл
    СформДата = Дата(Год, к, 1);
    Элементы.Месяц.СписокВыбора.Добавить(СформДата, Формат(СформДата, «ДФ=’MMMM yyyy'»));
    КонецЦикла;
    Элементы.Месяц.СписокВыбора.Добавить(Дата(Год+1, 1, 1), Формат(Год+1, «ЧГ=0»)); //для смены года
    
    КонецПроцедуры
    
    &НаКлиенте
    Процедура МесяцНачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
    
    Если ЗначениеЗаполнено(Объект.ПериодРегистрации) Тогда
    текМесяц = Объект.ПериодРегистрации;
    Иначе
    текМесяц = ТекущаяДата();
    КонецЕсли;
    СформироватьСписокВыбораМесяца(Год(текМесяц));
    
    СтандартнаяОбработка = Ложь;
    ВыбранноеЗначение = ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент, Элемент.СписокВыбора.НайтиПоЗначению(текМесяц));
    Пока ВыбранноеЗначение <> Неопределено И СтрДлина(ВыбранноеЗначение.Представление) = 4 Цикл
    //цикл продолжается до тех пор, пока мы не выберем месяц
    СформироватьСписокВыбораМесяца(Год(ВыбранноеЗначение.Значение));
    ВыбранноеЗначение = ЭтаФорма.ВыбратьИзСписка(Элемент.СписокВыбора, Элемент);
    КонецЦикла;
    
    Если ВыбранноеЗначение <> Неопределено Тогда
    Месяц = ВыбранноеЗначение.Представление;
    Объект.ПериодРегистрации = ВыбранноеЗначение.Значение;
    КонецЕсли;
    
    КонецПроцедуры

    Показать

    Reply
  13. Ганс

    УТ11.3 не работает что-то! ((

    Reply
  14. RocKeR_13
    Reply
  15. vnagapov

    Я думаю, что так еще проще

    &НаКлиенте
    Процедура ПриОткрытии(Отказ)
    Месяц = Формат(Объект.ПериодРегистрации, «ДФ=’MMMM yyyy'»);
    СформироватьСписокВыбораМесяца(Год(Объект.ПериодРегистрации));
    КонецПроцедуры
    
    Процедура СформироватьСписокВыбораМесяца(Год)
    
    Элементы.Месяц.СписокВыбора.Очистить();
    Элементы.Месяц.СписокВыбора.Добавить(Формат(Год-1, «ЧГ=0»));
    Для к = 1 По 12  Цикл
    СформДата = Дата(Год, к, 1);
    Наим = Формат(СформДата, «ДФ = ММММ_гггг»);
    Наим = СтрЗаменить(Наим, «_», » «);
    Элементы.Месяц.СписокВыбора.Добавить(Наим);
    КонецЦикла;
    Элементы.Месяц.СписокВыбора.Добавить(Формат(Год+1, «ЧГ=0»));
    КонецПроцедуры
    
    
    &НаКлиенте
    Процедура МесяцПриИзменении(Элемент)
    Если Месяц <> «» Тогда
    Если СтрДлина(Месяц)=4 Тогда
    СформироватьСписокВыбораМесяца(Число(Месяц));
    Объект.ПериодРегистрации = НачалоМесяца(Дата(Число(Месяц), 1, 1));
    Месяц = Формат(Объект.ПериодРегистрации, «ДФ=’MMMM yyyy'»);
    Иначе
    НомМесяца = (Найти(«янвфевмарапрмайиюниюлавгсеноктноядек»,Нрег(Лев(Месяц,3)))+2)/3; //получаем номер месяца
    ВыбрГод = Число(Прав(Месяц, 4));
    Объект.ПериодРегистрации = НачалоМесяца(Дата(ВыбрГод, НомМесяца, 1));
    КонецЕсли;
    КонецЕсли;
    КонецПроцедуры
    

    Показать

    Reply
  16. user805602
    Если Месяц «» Тогда

    Если ВыбранноеЗначение «» Тогда

    Пропущен, знак..

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *