Расширение механизма представлений под универсальный вывод иерархии подразделений
Кому полезно: любому, кто пишет отчеты в ЗУП 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!