Получить всех родителей элемента
Возвращает всех родителей элемента, согласно рекомендациям на ИТС
Как говорит ИТС:
В языке запросов не предусмотрено специальных средств для получения всех родителей элемента. Для выполнения задачи можно воспользоваться иерархическими итогами, однако получение иерархических итогов оптимизировано для построения итогов большого количества записей, и не вполне эффективно для получения родителей одного элемента. Для более эффективного получения всех родительских записей элемента, рекомендуется перебирать в цикле его родителей небольшими порциями.
Написал универсальный метод, который позволяет получить массив со всеми родителями элемента, используя рекомендации 1С.
Скорость выполнения достигает х2 по сравнению с обычным запросом с итогами по иерархии👍
Естественно, всё зависит от конкретной ситуации, но будем полагаться на то, что рекомендации 1С написаны верно 👌
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// Возвращает всех родителей элемента, согласно рекомендациям на ИТС:
// "Получение всех родителей элемента" (https://its.1c.ru/db/metod8dev/content/2659/hdoc)
//
// Параметры:
// СсылкаНаЭлемент - СправочникСсылка, ПланВидовХарактеристикСсылка - Ссылка на элемент, родителей которого нужно найти
// КоличествоВыбираемыхЗаПорцию - Число - Количество выбираемых родителей за одно выполнение запроса.
// Используется минимальное число из переданного и ограничения количества уровней в конфигураторе
//
// Возвращаемое значение:
// Массив[СправочникСсылка, ПланВидовХарактеристикСсылка] - массив с родителями элемента
//
&НаСервереБезКонтекста
Функция РодителиЭлемента(СсылкаНаЭлемент, Знач КоличествоВыбираемыхЗаПорцию = 5)
РодителиЭлемента = Новый Массив;
Если НЕ ЗначениеЗаполнено(СсылкаНаЭлемент) Тогда
Возврат РодителиЭлемента;
КонецЕсли;
МетаданныеЭлемента = СсылкаНаЭлемент.Метаданные();
Если МетаданныеЭлемента.ОграничиватьКоличествоУровней Тогда
КоличествоВыбираемыхЗаПорцию = Мин(КоличествоВыбираемыхЗаПорцию, МетаданныеЭлемента.КоличествоУровней);
КонецЕсли;
ВыбираемыеПоля = Новый Массив;
ВыбираемоеПоле = "Родитель";
Для НомерРодителя = 1 По КоличествоВыбираемыхЗаПорцию Цикл
ВыбираемыеПоля.Добавить(ВыбираемоеПоле);
ВыбираемоеПоле = ВыбираемоеПоле + ".Родитель";
КонецЦикла;
ТекстЗапроса = "ВЫБРАТЬ %1 ИЗ %2 ГДЕ Ссылка = &ТекущийЭлемент";
ТекстЗапроса = СтрШаблон(ТекстЗапроса, СтрСоединить(ВыбираемыеПоля, ","), МетаданныеЭлемента.ПолноеИмя());
Запрос = Новый Запрос(ТекстЗапроса);
ТекущийЭлемент = СсылкаНаЭлемент;
Пока ЗначениеЗаполнено(ТекущийЭлемент) Цикл
Запрос.УстановитьПараметр("ТекущийЭлемент", ТекущийЭлемент);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Прервать;
КонецЕсли;
Выборка = Результат.Выбрать();
Выборка.Следующий();
Для НомерКолонки = 0 По Результат.Колонки.Количество() - 1 Цикл
ТекущийЭлемент = Выборка[НомерКолонки];
Если ЗначениеЗаполнено(ТекущийЭлемент) Тогда
РодителиЭлемента.Добавить(ТекущийЭлемент);
Иначе
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Возврат РодителиЭлемента;
КонецФункции