Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема Уровень элемента справочника (число прочтений - 5140 )
КилоГрамм
Senior Member
****
Отсутствует


Таити, Таити...

Сообщений: 434
Зарегистрирован: 14. Июня 2006
Пол: Мужской
Уровень элемента справочника
27. Июня 2006 :: 07:14
Печать  
Когда не было необходимости, об этом и не задумывался. А теперь...
Можно получить уровень элемента справочника после выполнения запроса, методом перебора строк выходной таблицы. Хорошо когда их не тысячи. А как его (уровень) в запросе получить?
  

Константин
Наверх
 
IP записан
 
DrACe
1c++ donor
1c++ power user
Отсутствует


1С++ любитель

Сообщений: 447
Местоположение: г. Новосибирск
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Уровень элемента справочника
Ответ #1 - 27. Июня 2006 :: 08:18
Печать  
Всем, ПРИВЕТ!!!
С возвращением меня из отпуска!!! Класс

вообще тут надо бы конечно ХП писать, но вот такой составной запрос вроде адекватно себя ведет (только что набросал, мог чего напутать, сорри...)...
Код
Выбрать все
	RS = СоздатьОбъект("ODBCRecordSet");

	Вид = ВыбСпр.Вид();

	ТекстСложения = "";
	ТекстПрисоединения = "";
	Для Сч = 1 По Метаданные.Справочник(Вид).КоличествоУровней Цикл
		ТекстСложения = ТекстСложения + "
			|" + ?(Сч = 1,"(","+")+ " COUNT(Спр" + Сч + ".ID)";
		ПредыдСч = Сч - 1;
		ТекстПрисоединения = ТекстПрисоединения + "
			|" + ?(Сч = 1,"FROM","LEFT JOIN") + " $Справочник." + Вид + " as Спр" + Сч + " (NOLOCK)"
				+ ?(Сч = 1,""," ON (Спр" + ПредыдСч + ".ParentID = Спр" + Сч + ".ID)");
	КонецЦикла;
	ТекстСложения = ТекстСложения + "
		|)	as Уровень";
	ТекстЗапроса = "
		|SELECT " + ТекстСложения + ТекстПрисоединения + "
		|WHERE 	(Спр1.ID = :ВыбИд)
		|";
	RS.УстановитьТекстовыйПараметр("ВыбИд",ВыбСпр);
	Сообщить(ТекстЗапроса);
	Сообщить(RS.ВыполнитьСкалярный(ТекстЗапроса));
 


а вот сам запросец
Код
Выбрать все
SELECT
( COUNT(Спр1.ID)
+ COUNT(Спр2.ID)
+ COUNT(Спр3.ID)
+ COUNT(Спр4.ID)
)	as Уровень
FROM $Справочник.Пользователи as Спр1 (NOLOCK)
LEFT JOIN $Справочник.Пользователи as Спр2 (NOLOCK) ON (Спр1.ParentID = Спр2.ID)
LEFT JOIN $Справочник.Пользователи as Спр3 (NOLOCK) ON (Спр2.ParentID = Спр3.ID)
LEFT JOIN $Справочник.Пользователи as Спр4 (NOLOCK) ON (Спр3.ParentID = Спр4.ID)
WHERE 	(Спр1.ID = :ВыбИд)
 

  

SprUroven.ert ( 17 KB | Загрузки )
Наверх
 
IP записан
 
kms
1c++ power user
1c++ moderator
Отсутствует


я хочу, чтоб сюда проложили
дорогу оттуда...

Сообщений: 4632
Зарегистрирован: 19. Мая 2006
Re: Уровень элемента справочника
Ответ #2 - 27. Июня 2006 :: 08:30
Печать  
DrACe писал(а) 27. Июня 2006 :: 08:18:
Всем, ПРИВЕТ!!!
С возвращением меня из отпуска!!! Класс

Ну, че ж ты раньше не сказал, мы б тебя и с возвращением в отпуск поздравили! Улыбка

На itland в какой-то из тем, то ли о предложениях, то ли в обсуждении какого-то релиза мы с Quan'ом тестировали разные варианты алгоритмов типа "УложитьСписокОбъектов()".

В принципе, такой мульти-джойн весьма неплох, но Quan'у удалось найти даже более эффективные варианты.
Правда, не такие понятные.
  

De quelle planète es-tu?
Наверх
 
IP записан
 
КилоГрамм
Senior Member
****
Отсутствует


Таити, Таити...

Сообщений: 434
Зарегистрирован: 14. Июня 2006
Пол: Мужской
Re: Уровень элемента справочника
Ответ #3 - 27. Июня 2006 :: 08:57
Печать  
Все гениальное - просто. Спасибо.
Только одна мысль не дает мне покоя: где в БД лежит информация об уровне, ведь даже при простой выборке элементов спокойно виден Уровен()? В какой таблице и как ее оттуда выцарапатьбез переборки справочника по всем уровням?
  

Константин
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Уровень элемента справочника
Ответ #4 - 27. Июня 2006 :: 08:59
Печать  
Вот тоже вариант:
Код
Выбрать все
DECLARE @MaxNestLv as int -- максимальный уровень вложенности
DECLARE @NestLv as int -- счетчик
DECLARE @CurID as char(9) -- текущий идентификатор, его уровень нужно найти

SET @MaxNestLv = 3
SET @NestLv = 0
SET @CurID = '   9DG   '

WHILE (@@ROWCOUNT > 0) OR (@NestLv <= @MaxNestLv) BEGIN

	SELECT @CurID=parentid FROM SC196 (NOLOCK) WHERE id = @CurID
	IF @@ROWCOUNT = 0 BEGIN
 		--SET @NestLv = 0 -- вот хз здесь как быть, если сюда попали, значит либо при первом проходе, либо если есть элементы с неверными идентификаторами родителя
		BREAK;
	END
	ELSE IF @CurID = '     0   ' BEGIN
		SET @NestLv = @NestLv + 1
		BREAK;
	END

	SET @NestLv = @NestLv + 1
END

PRINT 'nested level = [' + CAST(@NestLv as varchar) + ']' -- результат
 

  
Наверх
ICQ  
IP записан
 
DrACe
1c++ donor
1c++ power user
Отсутствует


1С++ любитель

Сообщений: 447
Местоположение: г. Новосибирск
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Уровень элемента справочника
Ответ #5 - 27. Июня 2006 :: 09:09
Печать  
Цитата:
Все гениальное - просто. Спасибо.
Только одна мысль не дает мне покоя: где в БД лежит информация об уровне, ведь даже при простой выборке элементов спокойно виден Уровен()? В какой таблице и как ее оттуда выцарапатьбез переборки справочника по всем уровням?

я такой таблицы не знаю и всегда думал, что Уровень() вычисляется динамически, вот как именно - это вопрос...

kms
в случае с таким отпуском как у меня нужно поздравлять именно с его окончанием - занимался потаскунско-носильнической деятельностью... на даче с отцом дом строили из бруса!  Улыбка
  
Наверх
 
IP записан
 
КилоГрамм
Senior Member
****
Отсутствует


Таити, Таити...

Сообщений: 434
Зарегистрирован: 14. Июня 2006
Пол: Мужской
Re: Уровень элемента справочника
Ответ #6 - 27. Июня 2006 :: 10:01
Печать  
Динамически, так динамически.
И вовсе несложно, даже для DBF (почему-то она не "в почете"):
Код
Выбрать все
ТекстЗапроса = "
|SELECT
|	ICASE(CAST(Ном2.ID as FLOAT) <> 0,3,CAST(Ном1.ID as FLOAT) <> 0,2,1) as Уровень,
|	Ном0.ID  as [Товар $Справочник.Номенклатура]
|FROM
|	$Справочник.Номенклатура as Ном0
|LEFT JOIN $Справочник.Номенклатура as Ном1
|ON (Ном0.ParentID = Ном1.ID)
|LEFT JOIN $Справочник.Номенклатура as Ном2
|ON (Ном1.ParentID = Ном2.ID)
|ORDER BY
|	Уровень
|";
 


Это для 3-х уровней, если надо - добавим.
  

Константин
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать