Нестандартная расшифровка СКД или расшифровка одного отчета СКД при помощи другого отчета СКД установкой пользовательских настроек (в управляемых формах, методика + пример для УТ11)


Если требуется расшифровка одного отчета СКД при помощи другого отчета СКД, можно использовать представленный вариант. Казалось-бы все просто, однако дело усложняется тем, что с одной стороны, нужно предусмотреть разделение функционала между клиентом и сервером, с другой, нет достаточно четкого описания поведения передачи параметров расшифровки. В итоге: все решается "элементарно", но чтобы дойти до этого, лично мне пришлось убить уйму времени, так что экономьте своё ))). Под "нестандартной расшифровкой" имеется ввиду расшифровка данных одного вида отчета - другим видом, отличным от первого (с предварительной установкой нужных параметров и отборов в отчете-расшифровке).

Обратите внимание, что добавлены еще два варианта реализации подобного функционала:

1. http://avprog.ru/public/161994/, в реализации он еще проще, но имеет некоторые ограничения.

2. http://avprog.ru/public/165599/, в реализации несколько сложнее, но зато позволяет использовать одновременно как стандартную так и нестандартную расшифровку, кроме того он позволяет устанавливать дополнительные параметры отчета-расшифровки.

Оба эти отчета основаны на текущем.

 

Итак начнем Smile

Предположим, что есть некий отчет, при расшифровке которого нужно использовать другой, отличный от первого отчет, или конкретнее:

При расшифровке отчета «НеликвидыНоменклатуры» хочется использовать отчет «АнализДвиженийТоваровСРезервамиУпак», оба отчета самопальные и внедерены в УТ11 (оба отчета во вложении к теме). Т.е. при клике на ячейке с номенклатурой исходного отчета, должен быть построен отчет-расшифровка уже установленным отбором по этой номенклатуре, до кучи можно установить другие параметры отчета расшифровки (например период и склад)

  1. Прежде всего, чтобы иметь возможность запрограммировать расшифровку нам понадобится ФормаОтчета «НеликвидыНоменклатуры», её необходимо добавить (элементы формы система добавит сама).
  2. Для элемента формы «Результат» в событии «ОбработкаРасшифровки» нужно добавить процедуру, например: «РезультатОбработкаРасшифровки»
  3. В модуле этой формы нужно наполнить процедуру содержимым:

Сначала нужно понять в каком же месте произошло событие, требующее расшифровки  (иначе говоря нужно узнать какую номенклатуру выбрал пользователь), т.к. «РезультатОбработкаРасшифровки» работает на клиенте, тут потребуется вызов серверной функции с передачей в качестве параметра переменной «Расшифровка»

Номенклатура = ПолучитьРасшифровкуНаСервере(Расшифровка, ЭтоГруппа);

Тут передается также переменная ЭтоГруппа – для возврата признака выбранной номенклатуры.

Сама функция:

&НаСервере

Функция ПолучитьРасшифровкуНаСервере(Расшифровка, ЭтоГруппа = Ложь)

               Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки); //Здесь основная «недокументированная фишка»: Переменная ДанныеРасшифровки не описана в хелпе, также не описано что Данные, нужно получать путем извлечения из временного хранилища,

               Поля = Данные.Элементы.Получить(Расшифровка).ПолучитьПоля(); //Тут получаем поля расшифровки, среди которых находим нужное.

               ПолеНоменклатура = Поля.Найти("Номенклатура");

               Если ПолеНоменклатура = Неопределено Тогда

                               Возврат Неопределено;

               Иначе

                               ЭтоГруппа = ПолеНоменклатура.Значение.ЭтоГруппа;

                               Возврат ПолеНоменклатура.Значение;

               КонецЕсли;

КонецФункции

Далее, в основной процедуре, нужно получить форму отчета, которым будем производить расшифровку:

ФормаДТСР = ПолучитьФорму("Отчет.АнализДвиженийТоваровСРезервамиУпак.Форма");

Получить настройки этого отчета:

Настройки = ФормаДТСР.Отчет.КомпоновщикНастроек.Настройки;

Найти и заполнить нужные параметры и отборы отчета-расшифровки:

ИДНастройкиПериод = Настройки.ПараметрыДанных.Элементы.Найти("Период").ИдентификаторПользовательскойНастройки;  //Идентификатор пользовательской настройки "Период"

//Поиск доступных полей отбора по имени: 

ПолеСклад = Настройки.Отбор.ДоступныеПоляОтбора.Элементы.Найти("Склад").Поле;

ПолеНоменклатура = Настройки.Отбор.ДоступныеПоляОтбора.Элементы.Найти("Номенклатура").Поле;

//Поиск идентификаторов пользовательских настроек по доступным полям настроек (к сожалению только перебором):   

ИДЭлмОтбораСклад = "";

Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл

Если Элемент.ЛевоеЗначение = ПолеСклад Тогда ИДЭлмОтбораСклад = Элемент.ИдентификаторПользовательскойНастройки;         Прервать; КонецЕсли;

КонецЦикла;

ИДЭлмОтбораНоменклатура = "";

Для Каждого Элемент Из Настройки.Отбор.Элементы Цикл

Если Элемент.ЛевоеЗначение = ПолеНоменклатура Тогда ИДЭлмОтбораНоменклатура = Элемент.ИдентификаторПользовательскойНастройки;     Прервать; КонецЕсли;

КонецЦикла;

//Установка отбора по Номенклатуре, которая была получена в самом начале процедуры: 

Коллекция = ФормаДТСР.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы; //Пользовательские настройки

ЭлементОтбораНоменклатуры = Коллекция.Найти(ИДЭлмОтбораНоменклатура);

ЭлементОтбораНоменклатуры.ПравоеЗначение = Номенклатура;

ЭлементОтбораНоменклатуры.Использование = Истина;

ЭлементОтбораНоменклатуры.ВидСравнения = ?(ЭтоГруппа, ВидСравненияКомпоновкиДанных.ВИерархии, ВидСравненияКомпоновкиДанных.Равно);

               

//Установка отбора по Складу (из текущего отчета)

КоллекцияЗдесь = ЭтаФорма.Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы;

НастройкиЗдесь = ЭтаФорма.Отчет.КомпоновщикНастроек.Настройки;

ПолеСкладЗдесь = НастройкиЗдесь.Отбор.ДоступныеПоляОтбора.Элементы.Найти("Склад").Поле;

ИДЭлмОтбораСкладЗдесь = "";

Для Каждого Элемент Из НастройкиЗдесь.Отбор.Элементы Цикл

Если Элемент.ЛевоеЗначение = ПолеСкладЗдесь Тогда ИДЭлмОтбораСкладЗдесь = Элемент.ИдентификаторПользовательскойНастройки;         Прервать; КонецЕсли;

КонецЦикла;

ЭлементОтбораСкладЗдесь = КоллекцияЗдесь.Найти(ИДЭлмОтбораСкладЗдесь);

ЭлементОтбораСклад = Коллекция.Найти(ИДЭлмОтбораСклад);

ЭлементОтбораСклад.ПравоеЗначение = ЭлементОтбораСкладЗдесь.ПравоеЗначение;

ЭлементОтбораСклад.Использование = ЭлементОтбораСкладЗдесь.Использование;

ЭлементОтбораСклад.ВидСравнения = ЭлементОтбораСкладЗдесь.ВидСравнения;

ИДНастройкиПериодЗдесь = НастройкиЗдесь.ПараметрыДанных.Элементы.Найти("Интервал").ИдентификаторПользовательскойНастройки;

КонецПериодаЗдесь = КоллекцияЗдесь.Найти(ИДНастройкиПериодЗдесь).Значение.ДатаОкончания;

//Установка параметра Период

Коллекция.Найти(ИДНастройкиПериод).Значение = Новый СтандартныйПериод(ДобавитьМесяц(КонецПериодаЗдесь, -12),КонецПериодаЗдесь);

Для заполнения параметров отчета снова придется вызвать серверную функцию:

СтруктураВозврата = ОбработатьРасшифровкуНаСервере(ФормаДТСР.Отчет, ФормаДТСР.Результат, ФормаДТСР.ДанныеРасшифровки, ФормаДТСР.УникальныйИдентификатор);

Текст функции:

&НаСервере

Функция ОбработатьРасшифровкуНаСервере(Знач ОтчетХ, Знач РезультатХ, Знач ДанныеРасшифровкиХ, Знач ИДФормы)

                ОтчетОбъект = ДанныеФормыВЗначение(ОтчетХ, Тип("ОтчетОбъект.АнализДвиженийТоваровСРезервамиУпак")); //Для компоновки результата

                РезультатХ.Очистить();

                ОтчетОбъект.СкомпоноватьРезультат(РезультатХ, ДанныеРасшифровкиХ);                                  //Собственно формирование отчета

                АдресДанныеРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровкиХ, ИДФормы);             //тоже "недокументированная фишка", Запоминаем расшифровку (с ИД формы). Это необходимо, чтобы у отчета расшифровки в свою очередь тоже была расшифровка, но уже стандартная, ИДФормы - нужен, чтобы эта стандартная расшифровка сработала не один раз, а до тех пор пока существует указанная форма.

                Возврат Новый Структура("Результат,ДанныеРасшифровки", РезультатХ, АдресДанныеРасшифровки);         //Возвращаем результат и Адрес расшифровки, чтобы отчет-расшифровку тоже можно было расшифровать, но уже стандартной расшифровкой. Обратим внимание на то, что на клиенте извлечение из временного хранилища НЕ ПРОИЗВОДИТСЯ, система сама извлечет Данные Расшифровки, по мере необходимости.

КонецФункции

Далее, в основной процедуре, заполняем форму отчета-расшифровки и выводим его на экран:

                ФормаДТСР.Результат = СтруктураВозврата.Результат;

                ФормаДТСР.ДанныеРасшифровки = СтруктураВозврата.ДанныеРасшифровки;

                ФормаДТСР.Элементы.Результат.ОтображениеСостояния.Видимость = Ложь;  //Избавление от надписи. "Отчет не сформирован, бла, бла, бла"

                ФормаДТСР.Элементы.Результат.ОтображениеСостояния.ДополнительныйРежимОтображения = ДополнительныйРежимОтображения.НеИспользовать;

                ФормаДТСР.Открыть();

Коротко поясню что здесь делается:

      1. Получаем Номенклатуру, по которой пользователь произвел клик (вызов серверной функции "ПолучитьРасшифровкуНаСервере") 
      2. Получаем ФормуДТСР - отчета-расшифровки, по имени в метаданных
      3. Получаем Настройки ФормыДТСР (формы отчета расшифровки)
      4. По идентификаторам заполняем пользовательские настройки ФормыДТСР (формы отчета расшифровки), Номенклатуру - из п.1., Склад - из настроек исходного отчета, Период - отталкиваясь от Периода исходного отчета
      5. Производим формирование отчета расшифровки (вызов серверной функции "ОбработатьРасшифровкуНаСервере")
      6. Заполнение ФормыДТСР (формы отчета расшифровки) параметрами, которые вернула функция п.5
      7. Легкое наведение "лоска", и отображение заполненной  ФормыДТСР  (формы отчета расшифровки) 

Это собственно все. Все оказалось просто. Реализация во вложении, но комментариев в реализации значительно меньше )).

Файлы обработки:

-