Структура подчиненности
Теги: 1С,Структура подчиненности

Эта функция возвращает список документов в структуре подчиненности

# Код реализации

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