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