Задача: отобразить на форме отчета период отчета, как в типовых документах. В виде месяца с возможностью регулировать и выбирать конкретный месяц.
Давно хотелось создать универсальный механизм работы с добавленными элементами на общую форму «ФормаОтчета», поэтому писал материал с удовольствием.
Для добавления самого элемента формы воспользовался методом БСП — ОпределитьНастройкиФормы(), в котором прописал Настройки.События.ПриСозданииНаСервере = Истина. Это позволило добавить новый элемент при создании на сервере. В общую форму добавил универсальный код для работы с событиями нового элемента.
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_ПриИзменении(Элемент)
ПараметрыСобытия = Новый Структура;
ДанныеСобытия = ОбработатьСобытиеВОтчете("ПриИзменении", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_НачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("НачалоВыбора", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_НачалоВыбораИзСписка(Элемент, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("НачалоВыбораИзСписка", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_Очистка(Элемент, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("Очистка", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_Регулирование(Элемент, Направление, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("Направление", Направление);
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("Регулирование", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("Направление", Направление);
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_Открытие(Элемент, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("Открытие", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_Создание(Элемент, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("Создание", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_ОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("ВыбранноеЗначение", ВыбранноеЗначение);
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("ОбработкаВыбора", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("ВыбранноеЗначение", ВыбранноеЗначение);
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_ИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("Текст", Текст);
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("ИзменениеТекстаРедактирования", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("Текст", Текст);
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_АвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("Текст", Текст);
ПараметрыСобытия.Вставить("ДанныеВыбора", ДанныеВыбора);
ПараметрыСобытия.Вставить("ПараметрыПолученияДанных", ПараметрыПолученияДанных);
ПараметрыСобытия.Вставить("Ожидание", ПараметрыПолученияДанных);
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("АвтоПодбор", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("Текст", Текст);
ПараметрыСобытия.Свойство("ДанныеВыбора", ДанныеВыбора);
ПараметрыСобытия.Свойство("ПараметрыПолученияДанных", ПараметрыПолученияДанных);
ПараметрыСобытия.Свойство("Ожидание", ПараметрыПолученияДанных);
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ДобавленыйЭлемент_ОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)
ПараметрыСобытия = Новый Структура;
ПараметрыСобытия.Вставить("Текст", Текст);
ПараметрыСобытия.Вставить("ДанныеВыбора", ДанныеВыбора);
ПараметрыСобытия.Вставить("ПараметрыПолученияДанных", ПараметрыПолученияДанных);
ПараметрыСобытия.Вставить("СтандартнаяОбработка", СтандартнаяОбработка);
ДанныеСобытия = ОбработатьСобытиеВОтчете("ОкончаниеВводаТекста", Элемент.Имя, ПараметрыСобытия);
Если ДанныеСобытия.РезультатОбработки = Неопределено Тогда
Возврат;
КонецЕсли;
ПараметрыСобытия.Свойство("Текст", Текст);
ПараметрыСобытия.Свойство("ДанныеВыбора", ДанныеВыбора);
ПараметрыСобытия.Свойство("ПараметрыПолученияДанных", ПараметрыПолученияДанных);
ПараметрыСобытия.Свойство("СтандартнаяОбработка", СтандартнаяОбработка);
РезультатОбработки = ДанныеСобытия.РезультатОбработки;
Если РезультатОбработки.Свойство("ВыполнитьКод") Тогда
Выполнить(РезультатОбработки.ВыполнитьКод);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ОбработатьСобытиеВОтчете(Событие, ЭлементИмя, ПараметрыСобытия)
Результат = Новый Структура;
Результат.Вставить("ПараметрыСобытия", ПараметрыСобытия);
Элемент = Элементы[ЭлементИмя];
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
Попытка
Если Событие = "ПриИзменении" Тогда
РезультатОбработки = ОтчетОбъект.ПриИзменении(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "НачалоВыбора" Тогда
РезультатОбработки = ОтчетОбъект.НачалоВыбора(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "НачалоВыбораИзСписка" Тогда
РезультатОбработки = ОтчетОбъект.НачалоВыбораИзСписка(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "Очистка" Тогда
РезультатОбработки = ОтчетОбъект.Очистка(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "Регулирование" Тогда
РезультатОбработки = ОтчетОбъект.Регулирование(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "Открытие" Тогда
РезультатОбработки = ОтчетОбъект.Открытие(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "Создание" Тогда
РезультатОбработки = ОтчетОбъект.Создание(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "ОбработкаВыбора" Тогда
РезультатОбработки = ОтчетОбъект.ОбработкаВыбора(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "ИзменениеТекстаРедактирования" Тогда
РезультатОбработки = ОтчетОбъект.ИзменениеТекстаРедактирования(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "АвтоПодбор" Тогда
РезультатОбработки = ОтчетОбъект.АвтоПодбор(ЭтотОбъект, Элемент, ПараметрыСобытия);
ИначеЕсли Событие = "ОкончаниеВводаТекста" Тогда
РезультатОбработки = ОтчетОбъект.ОкончаниеВводаТекста(ЭтотОбъект, Элемент, ПараметрыСобытия);
Иначе
РезультатОбработки = Неопределено;
КонецЕсли;
Исключение
Сообщение = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
ЗаписьЖурналаРегистрации("Обработка события в отчете", УровеньЖурналаРегистрации.Ошибка, ОтчетОбъект.Метаданные(),
ОтчетОбъект, Сообщение);
РезультатОбработки = Неопределено;
КонецПопытки;
Результат.Вставить("РезультатОбработки", РезультатОбработки);
Возврат Результат;
КонецФункции
Для того чтобы пользоваться событиями важно устанавливать действия для добавленного элемента. Хранить значение для использования в последствии в процедуре «ПриКомпоновкеРезультата» я решил в «Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства» общей формы.
Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
Настройки.События.ПриСозданииНаСервере = Истина;
КонецПроцедуры
Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт
НовыеРеквизиты = Новый Массив;
НовыеРеквизиты.Добавить(Новый РеквизитФормы("МесяцСтрокой", ОбщегоНазначения.ОписаниеТипаСтрока(15), , "Месяц"));
Форма.ИзменитьРеквизиты(НовыеРеквизиты);
НовоеПоле = Форма.Элементы.Добавить("МесяцСтрокой", Тип("ПолеФормы"), Форма.Элементы.ПанельБыстрыхНастроек);
НовоеПоле.ПутьКДанным = "МесяцСтрокой";
НовоеПоле.Вид = ВидПоляФормы.ПолеВвода;
НовоеПоле.КнопкаВыбора = Истина;
НовоеПоле.КнопкаРегулирования = Истина;
НовоеПоле.КартинкаКнопкиВыбора = БиблиотекаКартинок.ПолеВводаКалендарь;
НовоеПоле.Ширина = 13;
НовоеПоле.РастягиватьПоГоризонтали = Истина;
НовоеПоле.УстановитьДействие("ПриИзменении", "Подключаемый_ДобавленыйЭлемент_ПриИзменении");
НовоеПоле.УстановитьДействие("НачалоВыбора", "Подключаемый_ДобавленыйЭлемент_НачалоВыбора");
НовоеПоле.УстановитьДействие("Регулирование", "Подключаемый_ДобавленыйЭлемент_Регулирование");
НовоеПоле.УстановитьДействие("АвтоПодбор", "Подключаемый_ДобавленыйЭлемент_АвтоПодбор");
НовоеПоле.УстановитьДействие("ОкончаниеВводаТекста", "Подключаемый_ДобавленыйЭлемент_ОкончаниеВводаТекста");
Форма.Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.Вставить("ПериодОтчета",
НачалоМесяца(ТекущаяДатаСеанса()));
ЗарплатаКадрыКлиентСервер.ЗаполнитьМесяцПоДате(Форма,
"Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.ПериодОтчета", "МесяцСтрокой");
КонецПроцедуры
Функция ПриИзменении(Форма, Элемент, ПараметрыСобытия) Экспорт
Результат = Новый Структура;
Если Элемент.Имя = "МесяцСтрокой" Тогда
Результат.Вставить("ВыполнитьКод", "
|ЗарплатаКадрыКлиент.ВводМесяцаПриИзменении(ЭтотОбъект,
|""Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.ПериодОтчета"",
|""МесяцСтрокой"", Модифицированность);");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция НачалоВыбора(Форма, Элемент, ПараметрыСобытия) Экспорт
Результат = Новый Структура;
Если Элемент.Имя = "МесяцСтрокой" Тогда
Результат.Вставить("ВыполнитьКод", "
|ЗарплатаКадрыКлиент.ВводМесяцаНачалоВыбора(ЭтотОбъект, ЭтотОбъект,
|""Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.ПериодОтчета"",
|""МесяцСтрокой"");");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция Регулирование(Форма, Элемент, ПараметрыСобытия) Экспорт
Результат = Новый Структура;
Если Элемент.Имя = "МесяцСтрокой" Тогда
Результат.Вставить("ВыполнитьКод", "
|ЗарплатаКадрыКлиент.ВводМесяцаРегулирование(ЭтотОбъект,
|""Отчет.КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.ПериодОтчета"",
|""МесяцСтрокой"", Направление, Модифицированность);");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция АвтоПодбор(Форма, Элемент, ПараметрыСобытия) Экспорт
Результат = Новый Структура;
Если Элемент.Имя = "МесяцСтрокой" Тогда
Результат.Вставить("ВыполнитьКод", "
|ЗарплатаКадрыКлиент.ВводМесяцаАвтоПодборТекста(Текст, ДанныеВыбора, СтандартнаяОбработка);");
КонецЕсли;
Возврат Результат;
КонецФункции
Функция ОкончаниеВводаТекста(Форма, Элемент, ПараметрыСобытияа) Экспорт
Результат = Новый Структура;
Если Элемент.Имя = "МесяцСтрокой" Тогда
Результат.Вставить("ВыполнитьКод", "
|ЗарплатаКадрыКлиент.ВводМесяцаОкончаниеВводаТекста(Текст, ДанныеВыбора, СтандартнаяОбработка);");
КонецЕсли;
Возврат Результат;
КонецФункции
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
МесяцОтчета = КомпоновщикНастроек.ФиксированныеНастройки.ДополнительныеСвойства.ПериодОтчета;
СтандартнаяОбработка = Ложь;
НастройкиКомпоновщика = КомпоновщикНастроек.ПолучитьНастройки();
НастройкиКомпоновщика.ПараметрыДанных.УстановитьЗначениеПараметра("ДатаНачала", МесяцОтчета);
НастройкиКомпоновщика.ПараметрыДанных.УстановитьЗначениеПараметра("ДатаОкончания", КонецМесяца(МесяцОтчета));
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, НастройкиКомпоновщика, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
В этом случае появится поле «Месяц» на форме, как на картинке в начале (со всем функционалом как в типовых документах).
Дополнительный полезный материал по теме: //infostart.ru/1c/articles/2112355/