Получение дерева подчиненности.
Одна функция и 3 процедуры, которые следует разместить в общем модуле (клиент, сервер). Возвращает дерево значений родительских и подчиненных документов от переданного документа через входной параметр "Ссылка". Выполняться может на сервере.
- Описание
- Подробнее
Описание
// Получение дерева подчиненности (родительские и подчиненные документы)
Функция ДеревоПодчиненности(Ссылка) Экспорт
ДеревоДокументов = Новый ДеревоЗначений;
ДеревоДокументов.Колонки.Добавить(«Ссылка»);
ДеревоДокументов.Колонки.Добавить(«ДокументПредставление»);
ДеревоДокументов.Колонки.Добавить(«Проведен»);
ДеревоДокументов.Колонки.Добавить(«ПометкаУдаления»);
ДеревоДокументов.Колонки.Добавить(«ВидДокумента»);
мУжеВСписке = Новый Соответствие;
мДерево = ДеревоДокументов;
ВывестиРодительскиеДокументы(Ссылка, мУжеВСписке, мДерево);
ВывестиПодчиненныеДокументы(мДерево, мУжеВСписке);
Возврат ДеревоДокументов;
КонецФункции
//
Процедура ВывестиРодительскиеДокументы(ДокументСсылка, мУжеВСписке, мДерево)
МетаданныеДокумента = ДокументСсылка.Метаданные();
СписокРеквизитов = Новый СписокЗначений;
Для Каждого Реквизит ИЗ МетаданныеДокумента.Реквизиты Цикл
ТипыРеквизита = Реквизит.Тип.Типы();
Для Каждого ТекущийТип ИЗ ТипыРеквизита Цикл
МетаданныеРеквизита = Метаданные.НайтиПоТипу(ТекущийТип);
Если МетаданныеРеквизита<>Неопределено И Метаданные.Документы.Содержит(МетаданныеРеквизита)
И ПравоДоступа(«Чтение», МетаданныеРеквизита) Тогда
Попытка
ЗначениеРеквизита = ДокументСсылка[Реквизит.Имя];
Исключение
Прервать;
КонецПопытки;
ЕСли ЗначениеРеквизита<>Неопределено И НЕ ЗначениеРеквизита.Пустая() И ТипЗнч(ЗначениеРеквизита) = ТекущийТип
И мУжеВСписке[ЗначениеРеквизита] = Неопределено И СписокРеквизитов.НайтиПоЗначению(ДокументСсылка[Реквизит.Имя]) = Неопределено Тогда
СписокРеквизитов.Добавить(ЗначениеРеквизита,Формат(ЗначениеРеквизита.Дата,«ДФ=yyyyMMddЧЧММсс»));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Для Каждого ТЧ Из МетаданныеДокумента.ТабличныеЧасти Цикл
СтрРеквизитов = «»;
Попытка
СодержимоеТЧ = ДокументСсылка[ТЧ.Имя].Выгрузить();
Исключение
Прервать;
КонецПопытки;
Для Каждого Реквизит ИЗ ТЧ.Реквизиты Цикл
ТипыРеквизита = Реквизит.Тип.Типы();
Для Каждого ТекущийТип ИЗ ТипыРеквизита Цикл
МетаданныеРеквизита = Метаданные.НайтиПоТипу(ТекущийТип);
Если МетаданныеРеквизита<>Неопределено И Метаданные.Документы.Содержит(МетаданныеРеквизита)
И ПравоДоступа(«Чтение», МетаданныеРеквизита) Тогда
СтрРеквизитов = СтрРеквизитов + ?(СтрРеквизитов = «», «», «, «) + Реквизит.Имя;
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
СодержимоеТЧ.Свернуть(СтрРеквизитов);
Для Каждого КолонкаТЧ ИЗ СодержимоеТЧ.Колонки Цикл
Для Каждого СтрокаТЧ ИЗ СодержимоеТЧ Цикл
Попытка
ЗначениеРеквизита = СтрокаТЧ[КолонкаТЧ.Имя];
Исключение
Продолжить;
КонецПопытки;
МетаданныеЗначения = Метаданные.НайтиПоТипу(ТипЗнч(ЗначениеРеквизита));
Если МетаданныеЗначения = Неопределено Тогда
// базовый тип
Продолжить;
КонецЕсли;
ЕСли ЗначениеРеквизита<>Неопределено И НЕ ЗначениеРеквизита.Пустая()
И Метаданные.Документы.Содержит(МетаданныеЗначения)
И мУжеВСписке[ЗначениеРеквизита] = Неопределено Тогда
Если СписокРеквизитов.НайтиПоЗначению(ЗначениеРеквизита) = Неопределено Тогда
СписокРеквизитов.Добавить(ЗначениеРеквизита,Формат(ЗначениеРеквизита.Дата,«ДФ=yyyyMMddЧЧММсс»));
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
СписокРеквизитов.СортироватьПоПредставлению();
мУжеВСписке.Вставить(ДокументСсылка, Истина);
Если СписокРеквизитов.Количество() = 1 Тогда
ВывестиРодительскиеДокументы(СписокРеквизитов[0].Значение, мУжеВСписке, мДерево);
ИначеЕсли СписокРеквизитов.Количество() > 1 Тогда
ВывестиБезРодителей(СписокРеквизитов, мУжеВСписке, мДерево);
КонецЕсли;
СтрокаДерева = мДерево.Строки.Добавить();
Запрос = Новый Запрос(«ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Проведен, ПометкаУдаления, Представление, «»» + МетаданныеДокумента.Имя + «»» КАК Метаданные
| ИЗ Документ.»+МетаданныеДокумента.Имя + » ГДЕ Ссылка = &Ссылка»);
Запрос.УстановитьПараметр(«Ссылка», ДокументСсылка);
Выборка = Запрос.Выполнить().Выбрать();
Если Выборка.Следующий() Тогда
СтрокаДерева.Ссылка = Выборка.Ссылка;
СтрокаДерева.ДокументПредставление = Выборка.Ссылка.Метаданные().Синоним + » » + Выборка.Ссылка.Номер;
СтрокаДерева.Проведен = Выборка.Проведен;
СтрокаДерева.ПометкаУдаления = Выборка.ПометкаУдаления;
СтрокаДерева.ВидДокумента = Выборка.Метаданные;
Иначе
СтрокаДерева.Ссылка= ДокументСсылка;
КонецЕсли;
мДерево = СтрокаДерева;
КонецПроцедуры
//
Процедура ВывестиПодчиненныеДокументы(СтрокаДерева, мУжеВСписке)
ТекущийДокумент = СтрокаДерева.Ссылка;
ТипДокумента = ТипЗнч(ТекущийДокумент);
СтруктураРеквизитов = Новый ТаблицаЗначений;
СтруктураРеквизитов.Колонки.Добавить(«ПутьКДанным»);
СтруктураРеквизитов.Колонки.Добавить(«ИмяРеквизита»);
Для каждого Док ИЗ Метаданные.Документы Цикл
Если НЕ ПравоДоступа(«Чтение», Док) Тогда
Продолжить;
КонецЕсли;
Для Каждого Реквизит Из Док.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(ТипДокумента) Тогда
НовСтр = СтруктураРеквизитов.Добавить();
НовСтр.ПутьКДанным = Док.Имя;
НовСтр.ИмяРеквизита = Реквизит.Имя;
КонецЕсли;
КонецЦикла;
Для Каждого ТЧ ИЗ Док.ТабличныеЧасти Цикл
Для Каждого Реквизит Из ТЧ.Реквизиты Цикл
Если Реквизит.Тип.СодержитТип(ТипДокумента) Тогда
НовСтр = СтруктураРеквизитов.Добавить();
НовСтр.ПутьКДанным = Док.Имя+«.»+ТЧ.Имя;
НовСтр.ИмяРеквизита = Реквизит.Имя;
КонецЕсли;
КонецЦикла;
КонецЦикла;
КонецЦикла;
ТекстЗапроса = «»;
Для Каждого КлючИЗначение Из СтруктураРеквизитов Цикл
Если Найти(КлючИЗначение.ПутьКДанным, «.») = 0 Тогда
ТекстЗапроса = ТекстЗапроса + «
|Выбрать » + ?(ТекстЗапроса=«», «РАЗРЕШЕННЫЕ «, «») + «Ссылка, Ссылка.Дата Как ДатаДок, Представление, Проведен, ПометкаУдаления, «»»+ КлючИЗначение.ПутьКДанным +«»» КАК ВидДокумента ИЗ Документ.»+КлючИЗначение.ПутьКДанным+«
|ГДЕ «+КлючИЗначение.ИмяРеквизита+«=&ДокументОснование
|ОБЪЕДИНИТЬ ВСЕ
|»;
Иначе
ПозицияТочки = Найти(КлючИЗначение.ПутьКДанным, «.»);
ТекстЗапроса = ТекстЗапроса + «
|Выбрать » + ?(ТекстЗапроса=«», «РАЗРЕШЕННЫЕ «, «») + «Ссылка, Ссылка.Дата Как ДатаДок, Ссылка.Представление, Ссылка.Проведен, Ссылка.ПометкаУдаления, «»»+ Лев(КлючИЗначение.ПутьКДанным, ПозицияТочки—1) +«»» КАК ВидДокумента ИЗ Документ.»+КлючИЗначение.ПутьКДанным+«
|ГДЕ «+КлючИЗначение.ИмяРеквизита+«=&ДокументОснование
|ОБЪЕДИНИТЬ ВСЕ
|»;
КонецЕсли;
КонецЦикла;
Если ТекстЗапроса=«» Тогда
Возврат;
КонецЕсли;
ТекстЗапроса = Лев (ТекстЗапроса, СтрДлина(ТекстЗапроса)-15);
ТекстЗапроса = ТекстЗапроса+ «
|УПОРЯДОЧИТЬ ПО ДатаДок»;
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр(«ДокументОснование», ТекущийДокумент);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если мУжеВСписке[Выборка.Ссылка] = Неопределено Тогда
НоваяСтрока = СтрокаДерева.Строки.Добавить();
НоваяСтрока.Ссылка = Выборка.Ссылка;
НоваяСтрока.ДокументПредставление = Выборка.Ссылка.Метаданные().Синоним + » » + Выборка.Ссылка.Номер;
НоваяСтрока.Проведен = Выборка.Проведен;
НоваяСтрока.ПометкаУдаления = Выборка.ПометкаУдаления;
НоваяСтрока.ВидДокумента = Выборка.ВидДокумента;
мУжеВСписке.Вставить(Выборка.Ссылка, Истина);
ВывестиПодчиненныеДокументы(НоваяСтрока, мУжеВСписке);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
//
Процедура ВывестиБезРодителей(СписокДокументов, мУжеВСписке, мДерево)
Для Каждого ЭлементСписка Из СписокДокументов Цикл
МетаданныеДокумента = ЭлементСписка.Значение.Метаданные();
Запрос = Новый Запрос(«ВЫБРАТЬ РАЗРЕШЕННЫЕ Ссылка, Проведен, ПометкаУдаления, Представление, «»» + МетаданныеДокумента.Имя + «»» КАК Метаданные
| ИЗ Документ.»+МетаданныеДокумента.Имя + » ГДЕ Ссылка = &Ссылка»);
Запрос.УстановитьПараметр(«Ссылка», ЭлементСписка.Значение);
Выборка = Запрос.Выполнить().Выбрать();
ЕСли Выборка.Следующий() Тогда
Если мУжеВСписке[Выборка.Ссылка] = Неопределено Тогда
СтрокаДерева = мДерево.Строки.Добавить();
СтрокаДерева.Ссылка= Выборка.Ссылка;
СтрокаДерева.ДокументПредставление = Выборка.Ссылка.Метаданные().Синоним + » » + Выборка.Ссылка.Номер;
СтрокаДерева.Проведен = Выборка.Проведен;
СтрокаДерева.ПометкаУдаления = Выборка.ПометкаУдаления;
СтрокаДерева.ВидДокумента = Выборка.Метаданные;
мУжеВСписке.Вставить(Выборка.Ссылка, Истина);
КонецЕсли;
КонецЕсли;
КонецЦикла;
мДерево = СтрокаДерева;
КонецПроцедуры

