Получить всех родителей элемента

SeiOkami 388 5 7 7

Возвращает всех родителей элемента, согласно рекомендациям на ИТС: "Получение всех родителей элемента" (https://its.1c.ru/db/metod8dev/content/2659/hdoc)

Источник: https://t.me/JuniorOneS

// Возвращает всех родителей элемента, согласно рекомендациям на ИТС:
// "Получение всех родителей элемента" (https://its.1c.ru/db/metod8dev/content/2659/hdoc)
//
// Параметры:
//  СсылкаНаЭлемент  - СправочникСсылка, ПланВидовХарактеристикСсылка - Ссылка на элемент, родителей которого нужно найти
//  КоличествоВыбираемыхЗаПорцию  - Число - Количество выбираемых родителей за одно выполнение запроса. 
//		Используется минимальное число из переданного и ограничения количества уровней в конфигураторе
//
// Возвращаемое значение:
//   Массив[СправочникСсылка, ПланВидовХарактеристикСсылка] - массив с родителями элемента
//
&НаСервереБезКонтекста
Функция РодителиЭлемента(СсылкаНаЭлемент, Знач КоличествоВыбираемыхЗаПорцию = 5)
	
	РодителиЭлемента = Новый Массив;
	Если НЕ ЗначениеЗаполнено(СсылкаНаЭлемент) Тогда
		Возврат РодителиЭлемента;
	КонецЕсли;
	
	МетаданныеЭлемента = СсылкаНаЭлемент.Метаданные();
	Если МетаданныеЭлемента.ОграничиватьКоличествоУровней Тогда
		КоличествоВыбираемыхЗаПорцию = Мин(КоличествоВыбираемыхЗаПорцию, МетаданныеЭлемента.КоличествоУровней);
	КонецЕсли;
	
	ВыбираемыеПоля = Новый Массив;
	ВыбираемоеПоле = "Родитель";
	Для НомерРодителя = 1 По КоличествоВыбираемыхЗаПорцию Цикл
		ВыбираемыеПоля.Добавить(ВыбираемоеПоле);
		ВыбираемоеПоле = ВыбираемоеПоле + ".Родитель";
	КонецЦикла;
	
	ТекстЗапроса = "ВЫБРАТЬ %1 ИЗ %2 ГДЕ Ссылка = &ТекущийЭлемент";
	ТекстЗапроса = СтрШаблон(ТекстЗапроса, СтрСоединить(ВыбираемыеПоля, ","), МетаданныеЭлемента.ПолноеИмя());
	Запрос = Новый Запрос(ТекстЗапроса);
	
	ТекущийЭлемент = СсылкаНаЭлемент;
	Пока ЗначениеЗаполнено(ТекущийЭлемент) Цикл
		
		Запрос.УстановитьПараметр("ТекущийЭлемент", ТекущийЭлемент); 
		Результат = Запрос.Выполнить(); 
		Если Результат.Пустой() Тогда 
			Прервать; 
		КонецЕсли; 
		
		Выборка = Результат.Выбрать(); 
		Выборка.Следующий(); 
		Для НомерКолонки = 0 По Результат.Колонки.Количество() - 1 Цикл 
			ТекущийЭлемент = Выборка[НомерКолонки]; 
			Если ЗначениеЗаполнено(ТекущийЭлемент) Тогда 
				РодителиЭлемента.Добавить(ТекущийЭлемент);
			Иначе 
				Прервать;
			КонецЕсли; 
		КонецЦикла; 
		
	КонецЦикла;
	
	Возврат РодителиЭлемента;
	
КонецФункции
5

Комментарии

Константин Аванесов
#1, 04 февраля 2021 12:36

А если количество уровней не ограничено и надо выбрать всех родителей?
ИМХО рекурсией будет универсальнее


SeiOkami
#2, ред. 04 февраля 2021 13:11

(1) Константин Аванесов, в чём проблема?

*Количество выбираемых родителей за одно выполнение запроса. *

Зачем здесь нужна рекурсия и чем именно это будет "универсальнее" ?

Данный метод и так универсален.


alah
#3, 18 ноября 2021 10:08

(2) SeiOkami, проще же можно:

&НаСервереБезКонтекста
Функция РодителиЭлемента(Знач СсылкаНаЭлемент)
		
		РодителиЭлемента = Новый Массив;

		Пока ЗначениеЗаполнено(СсылкаНаЭлемент.Родитель) Цикл
			РодителиЭлемента.Вставить(0, СсылкаНаЭлемент.Родитель);
			СсылкаНаЭлемент = СсылкаНаЭлемент.Родитель;
		КонецЦикла;
		
		Возврат РодителиЭлемента;
		
КонецФункции;


markers
#4, ред. 18 ноября 2021 10:23

(3) alah, Представьте ситуацию, у вас есть справочник "Номенклатура" в элементы/группы которого, добавлена картинка в высоком разрешении и теперь представьте, сколько будет выполнятся функция получения всех родителей элемента?


SeiOkami
#5, 26 ноября 2021 10:49

(3) alah, это проще, но хуже
https://its.1c.ru/db/metod8dev/content/2659/hdoc


См. также

Быстро получить всех родителей для текущей позиции

ВставитьЭлементHTMLПервымДочернимЭлементом (БСП)

УстановитьРодителяУПапки (БСП)

ПолучитьЭлементОбщаяПроизводительностьСистемы (БСП)

Количество дублей элементов справочника

СменитьРодителяПапок (БСП)

Алгоритм перебора всех возможных сочетаний элементов

Получить (БСП)

Модератору