Top.Mail.Ru

Расширение механизма представлений под универсальный вывод иерархии подразделений

Кому полезно: любому, кто пишет отчеты в ЗУП 3.1

На данный момент веду разработку в ЗУП 3.1. В последнее время при разработке часто стал сталкиваться с необходимостью вывести в отчет или обработку иерархию подразделений в виде таблицы.

Подразделение КореньУровень 5
Подразделение 1Уровень 4
Подразделение 2Уровень 3
Подразделение 3Уровень 4
Подразделение 4Уровень 3
Подразделение 5Уровень 2
Подразделение 6Уровень 1
Иерархия подразделений
ПодразделениеУровень 1Уровень 2Уровень 3Уровень 4Уровень 5
Подразделение Корень    Подразделение Корень
Подразделение 1   Подразделение 1Подразделение Корень
Подразделение 2  Подразделение 2Подразделение 1Подразделение Корень
Подразделение 3   Подразделение 3Подразделение Корень
Подразделение 4  Подразделение 4Подразделение 3Подразделение Корень
Подразделение 5 Подразделение 5Подразделение 4Подразделение 3Подразделение Корень
Подразделение 6Подразделение 6Подразделение 5Подразделение 4Подразделение 3Подразделение Корень
Необходимая таблица

Чтобы не писать каждый раз новый запрос я решил расширить механизм представлений, с которым сталкивается каждый, кто пишет отчеты в ЗУП 3. Провел анализ кода и появилось понимание, что механизм представлений очень легко расширяется.

Механизм представлений запускается функцией: ЗарплатаКадрыОбщиеНаборыДанных.ЗаполнитьОбщиеИсточникиДанныхОтчета(Объект, ДополнительныеПоляПредставлений = Неопределено, ТолькоРазрешенные = Истина), где Объект – наш отчет.

Представления заменяются конкретными запросами в функции «ПолучитьЗапросПоПредставлению» модуля «ЗарплатаКадрыОбщиеНаборыДанныхРасширенный», ее то я и доработал.

Функция обрабатывает имена временных таблиц представлений и возвращает запрос с текстом и параметрами. В нашем случае параметры заполнять не будем, т.к. вернем текст с полной таблицей иерархии. Я решил свою временную таблицу обозвать «Представления_ИерархияПодразделений». Добавляем формирование запроса после всех проверок:

Чтобы получить динамически количество колонок, не прописывая в тексте запроса СКД каждую, в функции «ЗарплатаКадрыОбщиеНаборыДанных.ЗаменитьЗапросыКПредставлениямВиртуальныхТаблиц» добавляем код:

ТекстЗапросаПриемник = МОЙ_ОбщегоНазначенияСервер.ВывестиВсеГруппыВИтоговомЗапросе(ТекстЗапросаПриемник);

Перед убиранием подчеркиваний в представлениях:

В модуле же «МОЙ_ОбщегоНазначенияСервер» прописал следующие процедуры и функции:

Функция ЗапросПредставленияИерархияПодразделений() Экспорт 
	
	МаксУровень = ГлубинаИерархииПодразделенийОрганизаций();
	
	ТекстЗапроса = 
	"ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение КАК Подразделение,
	|	&МаксУровень - КОЛИЧЕСТВО(ПодчиненностьПодразделенийОрганизаций.ВышестоящееПодразделение) КАК Уровень
	|ПОМЕСТИТЬ ВТУровни
	|ИЗ
	|	РегистрСведений.ПодчиненностьПодразделенийОрганизаций КАК ПодчиненностьПодразделенийОрганизаций
	|
	|СГРУППИРОВАТЬ ПО
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение КАК Подразделение,
	|	МАКСИМУМ(ИСТИНА) КАК Уровень1
	|ПОМЕСТИТЬ Представления_ИерархияПодразделений
	|ИЗ
	|	РегистрСведений.ПодчиненностьПодразделенийОрганизаций КАК ПодчиненностьПодразделенийОрганизаций
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТУровни КАК ВТУровни
	|		ПО ПодчиненностьПодразделенийОрганизаций.ВышестоящееПодразделение = ВТУровни.Подразделение
	|
	|СГРУППИРОВАТЬ ПО
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение
	|
	|ИНДЕКСИРОВАТЬ ПО
	|	Подразделение
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|УНИЧТОЖИТЬ ВТУровни";
	
	ПоляУровней = Новый Массив;
	Для Инд = 1 По МаксУровень Цикл
		
		ПоляУровней.Добавить(СтрШаблон(" 
		|МАКСИМУМ(ВЫБОР
		|		КОГДА ВТУровни.Уровень = %1
		|			ТОГДА ВТУровни.Подразделение
		|		ИНАЧЕ ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка)
		|	КОНЕЦ) КАК Уровень%2",
		Инд-1, Инд));
		
	КонецЦикла;
	
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "	МАКСИМУМ(ИСТИНА) КАК Уровень1", СтрСоединить(ПоляУровней, ","));
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&МаксУровень", МаксУровень);
	Запрос = Новый Запрос(ТекстЗапроса);
	
	Возврат Запрос;
	
КонецФункции

Процедура ПолучитьВТИерархияПодразделений(МВТ, ИмяВременнойТаблицы = "ВТИерархияПодразделений") Экспорт 
	
	Запрос = ЗапросПредставленияИерархияПодразделений();
	Запрос.МенеджерВременныхТаблиц = МВТ;
	
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "ПОМЕСТИТЬ Представления_ИерархияПодразделений",
		ИмяВременнойТаблицы);
	
	Запрос.Выполнить();
	
КонецПроцедуры

Функция ГлубинаИерархииПодразделенийОрганизаций() Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение КАК Подразделение,
	|	КОЛИЧЕСТВО(ПодчиненностьПодразделенийОрганизаций.ВышестоящееПодразделение) КАК Уровень
	|ПОМЕСТИТЬ ВТУровни
	|ИЗ
	|	РегистрСведений.ПодчиненностьПодразделенийОрганизаций КАК ПодчиненностьПодразделенийОрганизаций
	|
	|СГРУППИРОВАТЬ ПО
	|	ПодчиненностьПодразделенийОрганизаций.Подразделение
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	МАКСИМУМ(ВТУровни.Уровень) КАК Уровень
	|ИЗ
	|	ВТУровни КАК ВТУровни";
	
	УстановитьПривилегированныйРежим(Истина);
	Выборка = Запрос.Выполнить().Выбрать();
	Выборка.Следующий();
	УстановитьПривилегированныйРежим(Ложь);
	
	Возврат Выборка.Уровень;
	
КонецФункции

Функция ВывестиВсеГруппыВИтоговомЗапросе(ТекстЗапроса) Экспорт 
	
	МаксУровень = ГлубинаИерархииПодразделенийОрганизаций();
	
	ПоляУровней = Новый Массив;
	Для Инд = 1 По МаксУровень Цикл
		
		ПоляУровней.Добавить(СтрШаблон("
		|	Представления_ИерархияПодразделений.Уровень%1 КАК Уровень_%1",
		Инд));
		
	КонецЦикла;
	
	Возврат СтрЗаменить(ТекстЗапроса, "Представления_ИерархияПодразделений.Уровень1 КАК Уровень_1", СтрСоединить(ПоляУровней, ","));
	
КонецФункции

Осталось понять, как этим всем пользоваться

Добавляем в текст запроса СКД код:

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) КАК Уровень1,
	ЗНАЧЕНИЕ(Справочник.ПодразделенияОрганизаций.ПустаяСсылка) КАК Подразделение
ПОМЕСТИТЬ Представления_ИерархияПодразделений
ИЗ
	РегистрСведений.ПодчиненностьПодразделенийОрганизаций
;
////////////////////////////////////////////////////////////////////////////////

Далее используем, присоединяя в нужном месте. Если необходимо получить все уровни таблицы, при этом мы не понимаем заранее сколько уровней будет, то добавляем код выборку туда, где присоединили таблицу:

Представления_ИерархияПодразделений.Уровень1 КАК Уровень_1,

И тогда функция ВывестиВсеГруппыВИтоговомЗапросе преобразует ее в конечном запросе в вид:

ПредставленияИерархияПодразделений.Уровень1 КАК Уровень_1,
ПредставленияИерархияПодразделений.Уровень2 КАК Уровень_2,
ПредставленияИерархияПодразделений.Уровень3 КАК Уровень_3,
ПредставленияИерархияПодразделений.Уровень4 КАК Уровень_4,
ПредставленияИерархияПодразделений.Уровень5 КАК Уровень_5,
ПредставленияИерархияПодразделений.УровеньN КАК Уровень_N,

Где N максимальная глубина иерархии.

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar