Как в 1С запросом получить всех родителей элемента справочника?

Доброго времени суток, коллеги! Уже не раз на этом сайте затрагивалась тема запросов в 1С. И в очередной раз нужно коснуться этой темы, так как необходимо получить всех родителей элемента справочника одним запросом. В сети предлагаются разные варианты и есть даже с использованием рекурсивной функции, но этот вариант довольно долгий, поэтому предлагаю вам на суд, мой вариант. Посмотрите.

Функция ПолучитьРодителейЭлемента(Элемент) Экспорт
	Уровень = Элемент.Уровень();
	Объединить = "";
	Родитель = "";
	Текст = "";
	Для Номер = 1 По Уровень Цикл
		Родитель = Родитель + ".Родитель";
		Если Номер <> 1 Тогда
			Объединить = "
			|	
			|	ОБЪЕДИНИТЬ ВСЕ
			|";
		КонецЕсли;
		Текст = Текст + Объединить + "
		|ВЫБРАТЬ
		|		Номенклатура" + Родитель + " КАК Родитель
		|	ИЗ
		|		Справочник.Номенклатура КАК Номенклатура
		|	ГДЕ
		|		Номенклатура.Ссылка = &Элемент";
	КонецЦикла;
	Запрос = Новый Запрос;
	Запрос.Текст = "
	|ВЫБРАТЬ
	|	База.Родитель КАК Родитель
	|ИЗ
	|	(" + Текст + ") КАК База";
	Запрос.УстановитьПараметр("Элемент", Элемент);
	РезультатЗапроса = Запрос.Выполнить();
	Выборка = РезультатЗапроса.Выбрать();
	Пока Выборка.Следующий() Цикл
		Сообщит(Выборка.Родитель);
	КонецЦикла;
КонецФункции

Как видите, в этой функции сначала получаем, на каком уровне находится элемент. Теперь, в зависимости от уровня элемента пишем текст запроса. И в конце концов, выводим всех родителей в окно сообщений.

ПОДПИСКА

9 ответы
  1. Анастасия говорит:

    Процедура КнопкаВыполнитьНажатие(Кнопка)
    //ПолеВвода1 — Здесь ссылка на элемент справочника Номенклатура.
    Сообщить(ПолеВвода1);
    Родитель = ПолеВвода1;
    Если НайтиРодителя(Родитель).Пустая() Тогда
    Сообщить(«Родителя нет!»);
    Возврат;
    КонецЕсли;
    Пока НЕ НайтиРодителя(Родитель).Пустая() Цикл
    Род = НайтиРодителя(Родитель);
    Сообщить(Род);
    Родитель=Род;
    КонецЦикла;
    КонецПроцедуры

    Функция НайтиРодителя(СсылкаНом)
    Запрос = Новый Запрос;
    Запрос.Текст =
    «ВЫБРАТЬ
    | Номенклатура.Родитель
    |ИЗ
    | Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    | Номенклатура.Ссылка = &Ссылка»;
    Запрос.УстановитьПараметр(«Ссылка»,СсылкаНом);
    Результат = Запрос.Выполнить();
    Выборка = Результат.Выбрать();
    Выборка.Следующий();
    Возврат Выборка.Родитель;
    КонецФункции;

  2. softmaker говорит:

    Спасибо, Анастасия! Но одна большая проблема этого алгоритма: запрос в цикле.

  3. Julia говорит:

    Разумеется, сконструированный внутри функции текст запроса не обязательно сразу выполнять. Его можно сделать частью более общего пакетного запроса, в котором будет использоваться получаемая на последнем этапе таблица. Это касается и всех следующих примеров.

  4. elizaweta.fedorova говорит:

    Табличный документ формируется построителем отчета. Как для всех выводимых числовых показателей установить вывод без дробной части?

  5. Timtim говорит:

    Мне кажется такой способ проще (Рекурсия)
    Ниже код модуля формы обработки, которая проверяет родителей и
    выводит их в виде Дерева значений:

    &НаСервере
    Процедура ПолучитьРодителяНаСервере()
    Элемент = ЭлементСправочника.ПолучитьОбъект();
    Пстр = «»;
    тДерево = РеквизитФормыВЗначение(«СтруктураПодчиненности»);
    тДерево.Строки.Очистить();
    МассивЭлементов = Новый Массив;
    Пока НЕ Элемент.Ссылка.Пустая() Цикл
    МассивЭлементов.Добавить(Элемент.Наименование);
    Элемент = Элемент.Родитель;
    КонецЦикла;
    Индекс = МассивЭлементов.Количество()-1;
    Пока Индекс >= 0 Цикл
    НоваяСтрока = тДерево.Строки.Добавить();
    НоваяСтрока.Наименование = Пстр+МассивЭлементов[Индекс];
    Пстр = Пстр+»-«;
    Индекс = Индекс-1;
    КонецЦикла;
    ЗначениеВРеквизитФормы(тДерево,»СтруктураПодчиненности»);

    Мд = Метаданные[«Документы»];
    Для Каждого ЭлементКоллекции ИЗ Мд Цикл
    НаименованиеДокумента = «Документ.»+ЭлементКоллекции.Имя;
    //Сообщить(НаименованиеДокумента);
    КонецЦикла;

    КонецПроцедуры

    &НаКлиенте
    Процедура ПолучитьРодителя(Команда)
    ПолучитьРодителяНаСервере();
    КонецПроцедуры

  6. softmaker говорит:

    Тоже вариант, но не проверял. Спасибо!

  7. Салават говорит:

    ВЫБРАТЬ
    СтатьиЗатрат.Ссылка КАК Ссылка
    ИЗ
    Справочник.СтатьиЗатрат КАК СтатьиЗатрат
    ГДЕ
    СтатьиЗатрат.Ссылка = &РодительЭлемента
    ИТОГИ ПО
    Ссылка ТОЛЬКО ИЕРАРХИЯ

  8. softmaker говорит:

    Добрый день, Салават! Спасибо, отличный вариант!

Комментарии закрыты.