Оглавление
Постановка задачи
Реализация
Размещение дополнительных реквизитов для доп. настроек.
Размещение дополнительной команды по открытию формы списка регистра накопления с отборами
Реализация собственной расшифровки
P.S. Весь код с примерами
Постановка задачи
Предположим ситуацию, мы разрабатываем относительно простой отчет, который выводит остатки расчетов с партнерами и дополнительно данные по товарам к отгрузке. В качестве расшифровки нужно открыть типовой отчет "Расчеты с клиентами". Так же необходимо разместить на форме флаг для настройки вывода дополнительных данных по товарам к отгрузке, и команду открытия формы списка регистра накопления "Расчеты с клиентами" с отбором по партнеру указанному в параметре (вот так захотел наш гипотетический заказчик):
Реализация
Размещение дополнительных реквизитов для доп. настроек.
Флаг "Выводить данные по товарам" не являются параметром запроса, но его можно добавить в параметры СКД вручную и указать «Использование» = Всегда. В пользовательских настройках поднимаем флаг включения в пользовательские настройки и режим редактирования - «Быстрый доступ».
Теперь флаг появится на форме, а необходимые изменения в зависимости от его значения можно реализовать в методе «ПриКомпоновкеРезультата» модуля объекта отчета.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
Настройки = КомпоновщикНастроек.ПолучитьНастройки();
ПараметрДанных = Настройки.ПараметрыДанных.Элементы.Найти("ВыводитьДанныеПоТоварам");
Если ПараметрДанных <> Неопределено Тогда
Настройки.Структура[1].Использование = ПараметрДанных.Значение;
КонецЕсли;
КомпоновщикНастроек.ЗагрузитьНастройки(Настройки);
КонецПроцедуры
Так же такой параметр для настроек удобно использовать в условном оформлении СКД.
Первая часть задачи, по выводу дополнительных реквизитов для доп. настроек, решается достаточно просто. От разработчика требуется корректно продумать параметры и добавить код в метод «ПриКомпоновкеРезультата» модуля объекта разрабатываемого отчета для реализации нестандартного поведения оформления и/или наложения дополнительных параметров и отборов.
Размещение дополнительной команды по открытию формы списка регистра накопления с отборами
Данная задача уже интереснее, т.к. в СКД нет возможности добавлять команды, прибегнем к небольшому изменению общей формы отчета в расширении.
Добавим реквизит формы "ДополнительныеНастройкиОтчета" типа "Произвольный", в нем будем хранить структуру с нашими настройками.
Расширим процедуру «ПриСозданииНаСервере» &После, нам не важно что было в типовой обработке. В ней инициализируем и заполним наши настройки отчета и создадим дополнительные команды.
&НаСервере
Процедура АОФОПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
ИнициализироватьДополнительныеНастройкиОтчета();
Если ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ИспользуютсяДополнительныеКоманды Тогда
Элементы.Вставить("АОФОГруппаДопКоманды", Тип("ГруппаФормы"),, Элементы.Найти("ОтчетТабличныйДокумент"));
МассивПараметровКоманд = Новый Массив;
Выполнить "МассивПараметровКоманд = " + ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ОбщийМодуль + "." + ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ИмяЭкспортногоМетода + "(ЭтаФорма)";
АОФОПрограммноеРедактированиеФорм.СоздатьДопКоманды(ЭтотОбъект, Элементы, МассивПараметровКоманд);
КонецЕсли;
КонецПроцедуры
Настройки отчета можно хранить в макете. Это удобно, т.к. определить их наличие легко можно с помощью метаданных. В настройках определяем необходимость добавления команд и выполнения нестандартной расшифровки.
Дополнительно укажем путь к методу формирования описания команд и методу расшифровки.
&НаСервере
Процедура ИнициализироватьДополнительныеНастройкиОтчета()
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
ОтчетМетаданные = ОтчетОбъект.Метаданные();
ДополнительныеНастройкиОтчета = Новый Структура;
НастройкиНестандартнаяРасшифровка = Новый Структура;
НастройкиНестандартнаяРасшифровка.Вставить("НужнаНестандартнаяРасшифровка", Ложь);
НастройкиНестандартнаяРасшифровка.Вставить("ОбщийМодуль", "");
НастройкиНестандартнаяРасшифровка.Вставить("ИмяЭкспортногоМетода", "");
НастройкиДополнительныеКоманды = Новый Структура;
НастройкиДополнительныеКоманды.Вставить("ИспользуютсяДополнительныеКоманды", Ложь);
НастройкиДополнительныеКоманды.Вставить("ОбщийМодуль", "");
НастройкиДополнительныеКоманды.Вставить("ИмяЭкспортногоМетода", "");
Если ОтчетМетаданные.Макеты.Найти("НастройкиОтчета") <> Неопределено Тогда
МакетНастройкиОтчета = ОтчетОбъект.ПолучитьМакет("НастройкиОтчета");
ОбластьНестандартнаяРасшифровка = МакетНастройкиОтчета.ПолучитьОбласть("НестандартнаяРасшифровка");
НастройкиНестандартнаяРасшифровка.НужнаНестандартнаяРасшифровка = Булево(Число(ОбластьНестандартнаяРасшифровка.Область("R1C2").Текст));
НастройкиНестандартнаяРасшифровка.ОбщийМодуль = ОбластьНестандартнаяРасшифровка.Область("R2C2").Текст;
НастройкиНестандартнаяРасшифровка.ИмяЭкспортногоМетода = ОбластьНестандартнаяРасшифровка.Область("R3C2").Текст;
ОбластьДополнительныеКоманды = МакетНастройкиОтчета.ПолучитьОбласть("ДополнительныеКоманды");
НастройкиДополнительныеКоманды.ИспользуютсяДополнительныеКоманды = Булево(Число(ОбластьДополнительныеКоманды.Область("R1C2").Текст));
НастройкиДополнительныеКоманды.ОбщийМодуль = ОбластьДополнительныеКоманды.Область("R2C2").Текст;
НастройкиДополнительныеКоманды.ИмяЭкспортногоМетода = ОбластьДополнительныеКоманды.Область("R3C2").Текст;
КонецЕсли;
ДополнительныеНастройкиОтчета.Вставить("НастройкиНестандартнаяРасшифровка", НастройкиНестандартнаяРасшифровка);
ДополнительныеНастройкиОтчета.Вставить("НастройкиДополнительныеКоманды", НастройкиДополнительныеКоманды);
КонецПроцедуры
Метод «СоздатьДопКоманды». В качестве параметра передается массив структур с описанием команд, которые надо создать (если одна команда, то массив из одного элемента). Инициализировать команды можно в общем модуле, который по смыслу и содержанию будет относиться к разрабатываемому отчету.
Главным параметром, который требует особого внимания является «ИмяКоманды», он состоит из двух частей разделенных подчеркиванием «_»:
- название выполняемого метода
- название общего клиентского модуля
Остальные параметры можно задать по своему вкусу и техническому заданию
Процедура СоздатьДопКоманды(Форма, Элементы, МассивПараметровКоманд) Экспорт
Для каждого СтруктураПараметровКоманды Из МассивПараметровКоманд Цикл
ИмяКоманды = СтруктураПараметровКоманды.ИмяКоманды;
Если Форма.Команды.Найти(ИмяКоманды) = Неопределено Тогда
Команда = Форма.Команды.Добавить(ИмяКоманды);
Команда.Действие = "ОбработчикКомандыПереопределяемый";
КонецЕсли;
Если Элементы.Найти(ИмяКоманды) = Неопределено Тогда
Кнопка = Элементы.Добавить(ИмяКоманды, Тип("КнопкаФормы"), Элементы.АОФОГруппаДопКоманды);
Кнопка.Заголовок = СтруктураПараметровКоманды.Заголовок;
Кнопка.ИмяКоманды = ИмяКоманды;
Кнопка.Вид = СтруктураПараметровКоманды.Вид;
Кнопка.Отображение = СтруктураПараметровКоманды.Отображение;
Если ЗначениеЗаполнено(СтруктураПараметровКоманды.Картинка) Тогда
Кнопка.Картинка = СтруктураПараметровКоманды.Картинка;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Можно обратить внимание, что «Действие» команды задается фиксировано и не совпадает с тем, что мы указывали на предыдущем шаге при описании команды. На форме добавлен метод «ОбработатьКомандыПереопределяемый». Все добавляемые таким образом команды будут выполнять один общий для всех метод, а в нем уже будет происходить перенаправление в указанный в описании команды общий модуль и нужный метод.
&НаКлиенте
Процедура ОбработчикКомандыПереопределяемый(Команда)
ИмяКоманды = Команда.Имя;
МассивПараметров = СтрРазделить(ИмяКоманды, "_", Ложь);
ДопПараметры = ПолучитьДопПараметрыОповещения();
ОписаниеОповещенияКоманды = Новый ОписаниеОповещения(МассивПараметров[0], Вычислить(МассивПараметров[1]), ДопПараметры);
ВыполнитьОбработкуОповещения(ОписаниеОповещенияКоманды);
КонецПроцедуры
В дополнительных параметрах по умолчанию добавляются текущие настройки отчета из которых можно взять данные по установленным параметрам и использовать их для формирования параметров отбора формы.
&НаСервере
Функция ПолучитьДопПараметрыОповещения()
ДопПараметры = Новый Структура;
ДопПараметры.Вставить("АдресТекущиеНастройки", ПоместитьВоВременноеХранилище(Отчет.КомпоновщикНастроек.ПолучитьНастройки(), ЭтаФорма.УникальныйИдентификатор));
Возврат ДопПараметры;
КонецФункции
Таким образом, для разработчика добавление новой команды заключается в том, что бы указать в макете с настройками необходимость добавления команд и в правильном описании и логичном разнесении методов по общим модулям. При этом дорабатывать общую форму отчета возможно вообще не понадобится и будет достаточно предложенного механизма.
Реализация собственной расшифровки
Для решения этой задачи расширяем метод «Выбор» табличного документа.
Используем директиву «Вместо» без контроля изменения, т.к. если нам не нужна нестандартная расшифровка то будет отрабатывать типовой код.
&НаКлиенте
&Вместо("ОтчетТабличныйДокументВыбор")
Процедура АОФО_ОтчетТабличныйДокументВыбор(Элемент, Область, СтандартнаяОбработка)
Если ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.НужнаНестандартнаяРасшифровка Тогда
ДопПараметры = ПолучитьДопПараметрыРасшифровка();
Попытка
Выполнить ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.ОбщийМодуль + "." + ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.ИмяЭкспортногоМетода + "(ЭтаФорма, Область, ДопПараметры, СтандартнаяОбработка)";
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Иначе
ПродолжитьВызов(Элемент, Область, СтандартнаяОбработка);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ПолучитьДопПараметрыРасшифровка()
ДопПараметры = Новый Структура;
ДопПараметры.Вставить("АдресТекущиеНастройки", ПоместитьВоВременноеХранилище(Отчет.КомпоновщикНастроек.ПолучитьНастройки(), ЭтаФорма.УникальныйИдентификатор));
ДопПараметры.Вставить("АдресДанныеРасшифровки", ОтчетДанныеРасшифровки);
Возврат ДопПараметры;
КонецФункции
Для расшифровки потребуется передать в реализуемые методы данные реквизита формы «ОтчетДанныеРасшифровки», он содержит адрес в хранилище в котором хранятся данные по расшифровке.
Так же в доп. параметры по умолчанию добавляются текущие настройки отчета, по той же причине, что и для команды. Можно использовать данные по установленным параметрам для реализации неспецифической логики.
Работу метода «ПолучитьПараметрыДляРасшифровки» как в примере подробно описывать не буду.
Из основного:
- Получаем данные по текущим настройкам из временного хранилища
- Получаем данные по расшифровке из временного хранилища
- Обрабатываем в соответствии с необходимой логикой, заполняем параметры/отборы
- Готовим настройки для запуска отчета с расшифровкой
- Возвращаем сформированные параметры формы обратно в клиентский метод, где происходит открытие формы отчета с расшифровкой
При реализации нестандартной расшифровки через общую форму отчета разработчику необходимо в макете с настройками указать необходимость использования нестандартной расшифровки и реализовать метод в общем модуле.
Как итог, получаем универсальный механизм при котором можно использовать типовые формы отчета в том числе общую форму настроек (т.к. при создании своей формы отчета просто так вызвать форму настроек не получится, придется вносить дополнительные доработки или создавать свою форму настроек для отчета). Если отчет требует серьезной переработки интерфейса данный механизм может не подойти, но для небольших доработок позволит сохранить типовой функционал без дополнительных трудозатрат.
P.S. Весь код с примерами
Возможно, из-за того, что в статье приведены не все участки коды что-то может показаться непонятным. Для полноты восприятия решил поместить весь код с примером в конце:
#Область ОбработчикиСобытийФормы
&НаСервере
Процедура АОФОПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
ИнициализироватьДополнительныеНастройкиОтчета();
Если ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ИспользуютсяДополнительныеКоманды Тогда
Элементы.Вставить("АОФОГруппаДопКоманды", Тип("ГруппаФормы"),, Элементы.Найти("ОтчетТабличныйДокумент"));
МассивПараметровКоманд = Новый Массив;
Выполнить "МассивПараметровКоманд = " + ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ОбщийМодуль + "." + ДополнительныеНастройкиОтчета.НастройкиДополнительныеКоманды.ИмяЭкспортногоМетода + "(ЭтаФорма)";
АОФОПрограммноеРедактированиеФорм.СоздатьДопКоманды(ЭтотОбъект, Элементы, МассивПараметровКоманд);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиСобытийЭлементовТаблицыФормыТабличныйДокумент
&НаКлиенте
&Вместо("ОтчетТабличныйДокументВыбор")
Процедура АОФО_ОтчетТабличныйДокументВыбор(Элемент, Область, СтандартнаяОбработка)
Если ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.НужнаНестандартнаяРасшифровка Тогда
ДопПараметры = ПолучитьДопПараметрыРасшифровка();
Попытка
Выполнить ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.ОбщийМодуль + "." + ДополнительныеНастройкиОтчета.НастройкиНестандартнаяРасшифровка.ИмяЭкспортногоМетода + "(ЭтаФорма, Область, ДопПараметры, СтандартнаяОбработка)";
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ОписаниеОшибки());
КонецПопытки;
Иначе
ПродолжитьВызов(Элемент, Область, СтандартнаяОбработка);
КонецЕсли;
КонецПроцедуры
#КонецОбласти
#Область ОбработчикиКомандФормы
&НаКлиенте
Процедура ОбработчикКомандыПереопределяемый(Команда)
ИмяКоманды = Команда.Имя;
МассивПараметров = СтрРазделить(ИмяКоманды, "_", Ложь);
ДопПараметры = ПолучитьДопПараметрыОповещения();
ОписаниеОповещенияКоманды = Новый ОписаниеОповещения(МассивПараметров[0], Вычислить(МассивПараметров[1]), ДопПараметры);
ВыполнитьОбработкуОповещения(ОписаниеОповещенияКоманды);
КонецПроцедуры
#КонецОбласти
#Область СлужебныеПроцедурыИФункции
&НаСервере
Функция ПолучитьДопПараметрыОповещения()
ДопПараметры = Новый Структура;
ДопПараметры.Вставить("АдресТекущиеНастройки", ПоместитьВоВременноеХранилище(Отчет.КомпоновщикНастроек.ПолучитьНастройки(), ЭтаФорма.УникальныйИдентификатор));
Возврат ДопПараметры;
КонецФункции
&НаСервере
Функция ПолучитьДопПараметрыРасшифровка()
ДопПараметры = Новый Структура;
ДопПараметры.Вставить("АдресТекущиеНастройки", ПоместитьВоВременноеХранилище(Отчет.КомпоновщикНастроек.ПолучитьНастройки(), ЭтаФорма.УникальныйИдентификатор));
ДопПараметры.Вставить("АдресДанныеРасшифровки", ОтчетДанныеРасшифровки);
Возврат ДопПараметры;
КонецФункции
&НаСервере
Процедура ИнициализироватьДополнительныеНастройкиОтчета()
ОтчетОбъект = РеквизитФормыВЗначение("Отчет");
ОтчетМетаданные = ОтчетОбъект.Метаданные();
ДополнительныеНастройкиОтчета = Новый Структура;
НастройкиНестандартнаяРасшифровка = Новый Структура;
НастройкиНестандартнаяРасшифровка.Вставить("НужнаНестандартнаяРасшифровка", Ложь);
НастройкиНестандартнаяРасшифровка.Вставить("ОбщийМодуль", "");
НастройкиНестандартнаяРасшифровка.Вставить("ИмяЭкспортногоМетода", "");
НастройкиДополнительныеКоманды = Новый Структура;
НастройкиДополнительныеКоманды.Вставить("ИспользуютсяДополнительныеКоманды", Ложь);
НастройкиДополнительныеКоманды.Вставить("ОбщийМодуль", "");
НастройкиДополнительныеКоманды.Вставить("ИмяЭкспортногоМетода", "");
Если ОтчетМетаданные.Макеты.Найти("НастройкиОтчета") <> Неопределено Тогда
МакетНастройкиОтчета = ОтчетОбъект.ПолучитьМакет("НастройкиОтчета");
ОбластьНестандартнаяРасшифровка = МакетНастройкиОтчета.ПолучитьОбласть("НестандартнаяРасшифровка");
НастройкиНестандартнаяРасшифровка.НужнаНестандартнаяРасшифровка = Булево(Число(ОбластьНестандартнаяРасшифровка.Область("R1C2").Текст));
НастройкиНестандартнаяРасшифровка.ОбщийМодуль = ОбластьНестандартнаяРасшифровка.Область("R2C2").Текст;
НастройкиНестандартнаяРасшифровка.ИмяЭкспортногоМетода = ОбластьНестандартнаяРасшифровка.Область("R3C2").Текст;
ОбластьДополнительныеКоманды = МакетНастройкиОтчета.ПолучитьОбласть("ДополнительныеКоманды");
НастройкиДополнительныеКоманды.ИспользуютсяДополнительныеКоманды = Булево(Число(ОбластьДополнительныеКоманды.Область("R1C2").Текст));
НастройкиДополнительныеКоманды.ОбщийМодуль = ОбластьДополнительныеКоманды.Область("R2C2").Текст;
НастройкиДополнительныеКоманды.ИмяЭкспортногоМетода = ОбластьДополнительныеКоманды.Область("R3C2").Текст;
КонецЕсли;
ДополнительныеНастройкиОтчета.Вставить("НастройкиНестандартнаяРасшифровка", НастройкиНестандартнаяРасшифровка);
ДополнительныеНастройкиОтчета.Вставить("НастройкиДополнительныеКоманды", НастройкиДополнительныеКоманды);
КонецПроцедуры
#КонецОбласти
По справедливому замечанию ixijixi, можно не изобретать совой велосипед (а так хотелось) и воспользоваться возможностями БСП.
Для добавления команд на общую форму отчета достаточно выполнить несколько действий:
- В модуле объекта отчета в методе "ОпределитьНастройкиФормы" указать необходимость выполнения события "ПриСозданииНаСервере"
Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт Настройки.События.ПриСозданииНаСервере = Истина; КонецПроцедуры
- Там же в модуле объекта отчета определить метод "ПриСозданииНаСервере" в котором выполнить заполнение описания команд и выведение их на форму
Процедура ПриСозданииНаСервере(Форма, Отказ, СтандартнаяОбработка) Экспорт Команда = Форма.Команды.Добавить("ОткрытьФормуРегистраРасчетыСКлиентамиСОтбором_АОФООтчетТестовыйКлиент"); Команда.Действие = "АОФООтчетТестовыйКлиент.ОткрытьФормуРегистраРасчетыСКлиентамиСОтбором"; Команда.Картинка = БиблиотекаКартинок.РегистрНакопления; Команда.Заголовок = НСтр("ru = 'Расчеты с клиентами'"); Команда.Отображение = ОтображениеКнопки.КартинкаИТекст; Команда.Подсказка = "Расчеты с клиентами"; ОтчетыСервер.ВывестиКоманду(Форма, Команда, "Настройки"); КонецПроцедуры
- Расширить метод "НастроитьВариантыОтчетов" общего модуля "ВариантыОтчетовПереопределяемый" (по стандартам в нем следует вызывать отдельный метод, но в качестве примера позволю себе код разместить прямо там)
&После("НастроитьВариантыОтчетов") Процедура АОФОНастроитьВариантыОтчетов(Настройки) ОписаниеОтчета = ВариантыОтчетов.ОписаниеОтчета(Настройки, Метаданные.Отчеты.АОФООтчетТестовый); ОписаниеОтчета.ОпределитьНастройкиФормы = Истина; ОписаниеВарианта = ВариантыОтчетов.ОписаниеВарианта(Настройки, ОписаниеОтчета, ""); ОписаниеВарианта.Описание = НСтр("ru = 'Тестовый отчет.'; |en = 'Test.report.'"); КонецПроцедуры
В большей степени нас интересует параметр "ОпределитьНастройкиФормы", его значение должно быть Истина, иначе ничего не выйдет.
-
После выполнения описанных выше действие нужно запустить базу с ключом обновления "ЗапуститьОбновлениеИнформационнойБазы". Будут заполнены настройки варината отчета расширения и команда сможет появиться на форме.
При такой реализации в моем примере немного изменятся параметры и содержимое метода "ОткрытьФормуРегистраРасчетыСКлиентамиСОтбором". Первым параметром передается форма, из неё можно обратиться к компоновщику настроек отчета, без использования временного хранилища
Процедура ОткрытьФормуРегистраРасчетыСКлиентамиСОтбором(Форма, КомандаФормы) Экспорт
ПараметрыФормы = Новый Структура;
Отбор = Новый Структура;
Отбор.Вставить("АналитикаУчетаПоПартнерам", АОФООтчетТестовыйСервер.ПолучитьАналитикуУчетаПоПартнеру(Форма.Отчет.КомпоновщикНастроек));
ПараметрыФормы.Вставить("Отбор", Отбор);
ОткрытьФорму("РегистрНакопления.РасчетыСКлиентами.ФормаСписка", ПараметрыФормы);
КонецПроцедуры
Из метода "ИнициализироватьДополнительныеНастройкиОтчета" на общей форме отчета нужно удалить часть кода относящуюся к созданию команд по настройкам макета. В расширенном методе "ПриСозданииНаСервере" удалить часть кода, которая создает эти команды. Методы "ОбработчикКомандыПереопределяемый" и "ПолучитьДопПараметрыОповещения" так же становятся не нужны. В макете с настройками отчета удалить область с настройками по созданию команд.
Проверено на следующих конфигурациях и релизах:
- 1С:ERP Управление предприятием 2, релизы 2.5.16.115, 2.5.7.308