Получение значения расшифровки и значений вышестоящих группировок расшифровки в отчете СКД

Опубликовал Виталий Онянов (Tavalik) в раздел Программирование - Практика программирования

Ниже приводится небольшой кусок кода, позволяющий получить значение расшифровки и значения всех вышестоящих группировок расшифровки в отчете построенном на СКД при использовании обычных форм. Имя поля и значение просто выводится пользователю в сообщении. Соответственно, вы можете вставить свой алгоритм вместо вывода сообщений. Реализовано с помощью рекурсивного вызова процедуры, получающей значения вышестоящей группировки.

В форме для поля "Результат" определим для события "ОбработкаРасшифровки" процедуру "РезультатОбработкиРасшифровки". И, соответствено, тело процедуры будет следующим:

Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)

    СтандартнаяОбработка = Ложь;
 
    //Значение текущего поля     
    Поле = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0];
    Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение);
    
    //Значения всех вышестоящих группировок     
    ВывестиЗначениеГруппировки(Расшифровка);

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

Где процедура "ВывестиЗначениеГруппировки" имеет следующее содержание:

Процедура ВывестиЗначениеГруппировки(ТекРасшифровка)
	
	МассивРодителей = ДанныеРасшифровки.Элементы[ТекРасшифровка].ПолучитьРодителей();
	Для СчРодителей = 1 По МассивРодителей.Количество() Цикл
	
		ПолеРодитель = МассивРодителей[СчРодителей-1];
		Если Число(ПолеРодитель.Идентификатор) > 0 Тогда
			
			//Получим текущее поле
			Если ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
			   МассивПолей = ПолеРодитель.ПолучитьПоля();
			ИначеЕсли ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
			   МассивПолей = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля();
			КонецЕсли; 
			   
			Для СчПолей = 1 По МассивПолей.Количество() Цикл
				
				Поле = МассивПолей[СчПолей-1];
			
				//Выведем значения текущей расшифровки
				Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение);
				
				//Рекурсивный вызов процедуры. 
				РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей()[0].Идентификатор;
				ВывестиЗначениеГруппировки(РасшифровкиВыше);
				
			КонецЦикла;	
			
		КонецЕсли;		
	КонецЦикла;
	
КонецПроцедуры

Пример работы данных процедур можно посмотреть здесь  

См. также

Комментарии
1. Дмитрий Чернов (Chernov_Dmitriy) 77 12.12.13 11:39 Сейчас в теме
Автор спасибо - после 5 часов поисков твой код подошел. Только немного модифицировал - так как не отрабатывал группировки:
Процедура ВывестиЗначениеГруппировки(ТекРасшифровка)

МассивРодителей = ДанныеРасшифровки.Элементы[ТекРасшифровка].ПолучитьРодителей();
Для Сч = 1 По МассивРодителей.Количество() Цикл

ПолеРодитель = МассивРодителей[Сч-1];
Если ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда

//Выведем значения текущей расшифровки
Поле = ПолеРодитель.ПолучитьПоля()[0];
Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение);

//Рекурсивный вызов процедуры.
РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей()[0].Идентификатор;
ВывестиЗначениеГруппировки(РасшифровкиВыше);
ИначеЕсли ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") тогда
Попытка
Поле = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля()[0] ;
Сообщить("Поле: " + Поле.Поле + ", значение: " + Поле.Значение);

//Рекурсивный вызов процедуры.
РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей()[0].Идентификатор;
ВывестиЗначениеГруппировки(РасшифровкиВыше);

Исключение

КонецПопытки;
КонецЕсли;

КонецЦикла;

КонецПроцедуры
2. Виталий Онянов (Tavalik) 366 20.12.13 13:12 Сейчас в теме
Спасибо. В статье исправил и тоже немного оптимизировал :)
3. Андрей Ро (AndrewVVS) 07.02.14 16:26 Сейчас в теме
Поле = ДанныеРасшифровки.Элементы[Расшифровка].ПолучитьПоля()[0],
А если ДанныеРасшифровки = Неопределено, тогда будет ошибка...
Нашел: нужно было в типовой процедуре добавить "ДанныеРасшифровки", по умолчанию там Неопределено!

Процедура ОбновитьОтчет() Экспорт

СформироватьОтчет(ЭтаФорма.ЭлементыФормы.Результат, ДанныеРасшифровки, Ложь);

КонецПроцедуры
4. Сергей Иванов (xten) 38 22.04.14 13:14 Сейчас в теме
Я правильно понимаю, что это фактически универсальный шаблонный код (если можно так выразиться), который можно в много где использовать )) ?
5. Виталий Онянов (Tavalik) 366 23.04.14 07:14 Сейчас в теме
(4) xten,
Да, конечно. Код будет работать в любом отчете на СКД.
6. Екатерина Овчинникова (katunya88) 17 15.05.14 06:12 Сейчас в теме
ты просто супер! то что нужно! спасибо!
7. Василий Пупкин (Cyberhawk) 99 27.10.14 18:54 Сейчас в теме
А кто знает, как получать значения ресурса из расшифровки?
8. Игорь Климов (ig0rec) 17.11.14 13:22 Сейчас в теме
А если родителей несколько на одном уровне ( когда расшифровка и по столбцам и по колонкам), то выберутся только первые группировки, вот мой вариант

Процедура РекурсивноПолучитьРодителей(Элемент, Структура)
	
	Родители = Элемент.ПолучитьРодителей(); 
	Для Каждого Родитель из Родители Цикл
		Если ТипЗнч(Родитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
			Поля = Родитель.ПолучитьПоля();
			Для Каждого Поле из Поля Цикл
				Если Не Поле.Иерархия  Тогда
					Структура.Вставить(Поле.Поле,Поле.Значение);
				КонецЕсли;
			КонецЦикла;
        КонецЕсли;
		РекурсивноПолучитьРодителей(Родитель, Структура)	
	КонецЦикла;
	
КонецПроцедуры
...Показать Скрыть


А использую процедуру так

    
        Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
        Структура = Новый Структура;
	РекурсивноПолучитьРодителей(Данные.Элементы.Получить(Расшифровка), Структура);
...Показать Скрыть


но не могу получить значение ресурса, м.б. кто-нибудь подскажет?
9. Виталий Онянов (Tavalik) 366 23.05.15 12:23 Сейчас в теме
(8) ig0rec,

Спасибо за комментарий.
Столкнулся с подобной проблемой. Оптимизировал код в публикации для вывода всех группировочных полей на каждом уровне группировки.
10. Иван Иванов (Oleg-and-reevich) 3 29.01.16 17:15 Сейчас в теме
Автор, огромное спасибо! Просто не представляете, как выручил Ваш код)!
11. Рифат Нурмухаметов (rif-nrr) 8 16.02.16 23:01 Сейчас в теме
Спасибо за статью! очень выручило
12. Виктория Мирская (Vika260740) 4 14.08.16 10:53 Сейчас в теме
Спасибо за полезный код!
13. Илья Вильчик (TreeDogNight) 14 16.02.17 09:56 Сейчас в теме
Доработал ваш код, добавил возможность получения значений полей детальных записей (до этого получалось только значение текущего поля, откуда вызывалась расшифровка):
&НаКлиенте
Функция ПолучитьСтруктуруРасшифровки(Расшифровка)
	
	СтруктураРасшифровки = Новый Структура;	    
	ЗаполнитьСтруктуруПолейРасшифровки(Расшифровка, СтруктураРасшифровки); 
	
	Возврат СтруктураРасшифровки;
	
КонецФункции 

&НаСервере
Процедура ЗаполнитьСтруктуруПолейРасшифровки(Знач Расшифровка, СтруктураПолей, Знач Данные = "")
	
	Если Данные = "" Тогда
		Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
		
		Если ТипЗнч(Данные.Элементы[Расшифровка]) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
			Поля = Данные.Элементы[Расшифровка].ПолучитьПоля();                   
			Для каждого Поле Из Поля Цикл
				СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение);
			КонецЦикла;
			
			Индекс = Число(Расшифровка);
			Пока Индекс Цикл
				ЭлементРасшифровки = Данные.Элементы[Индекс];
				Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
					Прервать;	
				КонецЕсли;
				
				Индекс = Индекс + 1;
			КонецЦикла;
			
			Индекс = Индекс - 1;
			Пока Индекс Цикл
				ЭлементРасшифровки = Данные.Элементы[Индекс];
				Если ТипЗнч(ЭлементРасшифровки) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
					Поля = ЭлементРасшифровки.ПолучитьПоля();                   
					Для каждого Поле Из Поля Цикл
						Если Не ТипЗнч(Поле.Значение) = Тип("Число") Тогда
							СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение);
						КонецЕсли; 	
					КонецЦикла;
					
					Индекс = Индекс - 1;
				Иначе 
					Прервать;
				КонецЕсли; 
			КонецЦикла; 
		КонецЕсли;
		
		ЗаполнитьСтруктуруПолейРасшифровки(Данные.Элементы[Расшифровка], СтруктураПолей, Данные);
	Иначе 
		МассивРодителей = Расшифровка.ПолучитьРодителей();
		Для каждого ПолеРодитель из МассивРодителей Цикл
			Если Число(ПолеРодитель.Идентификатор) > 0 Тогда
				Если ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхПоля") Тогда
					МассивПолей = ПолеРодитель.ПолучитьПоля();
				ИначеЕсли ТипЗнч(ПолеРодитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
					МассивПолей = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля();
				КонецЕсли; 
				
				Для каждого Поле из МассивПолей Цикл
					СтруктураПолей.Вставить(ПреобразоватьИмяПоляГруппировки(Поле.Поле), Поле.Значение);
					
					РасшифровкиВыше = ПолеРодитель.ПолучитьРодителей();
					Для каждого РодительВыше Из РасшифровкиВыше Цикл
						ЗаполнитьСтруктуруПолейРасшифровки(РодительВыше, СтруктураПолей, Данные);              
					КонецЦикла; 
				КонецЦикла;    
			КонецЕсли;        
		КонецЦикла;
	КонецЕсли; 
		
КонецПроцедуры
...Показать Скрыть
14. Кирилл (queit) 59 13.04.17 07:56 Сейчас в теме
Спасибо за статью. Очень полезная.
Только вот столкнулся с одной проблемкой. Почему-то "Поле.Значение" всегда null, при этом имя поля выводится правильно.
Что это может быть?
15. Николай Орлов (sulfur17) 23.05.17 22:05 Сейчас в теме
Пытаюсь расшифровку таблицы сделать из строки ВСЕГО и вот в этой строке получается ошибка
МассивПолей = ПолеРодитель.ПолучитьРодителей()[0].ПолучитьПоля();

т.к. ПолучитьРодителей() возвращает пустой массив.
Оставьте свое сообщение