Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Как в запросе получить Уровень() (число прочтений - 10381 )
Bagirius
Full Member
***
Отсутствует



Сообщений: 135
Зарегистрирован: 19. Февраля 2008
Пол: Мужской
Как в запросе получить Уровень()
29. Апреля 2008 :: 09:01
Печать  
Как запросом SQL получить Уровень элемента справочника.
Задача такая (может можно по другому) - Делаю выборку Элементов справочника и всех Родительских папок для этих товаров. Но при сортировке по наименованию, например, старшая папка может передвинуться ниже, а младшая, наоборот выше.
Делаю в ТабличномПоле справочник товаров.
Задумка, сделать дополнительное поле УРОВЕНЬ, и сначало сортировать по нему, а потом уже по наименованию и т.п.
  
Наверх
ICQ  
IP записан
 
novichek
Экс-Участник


Re: Как в запросе получить Уровень()
Ответ #1 - 29. Апреля 2008 :: 09:09
Печать  
Уровень как таковой в 1с не хранится, а вычисляется каждый раз рекурсивным перебором родителей. Не самая быстрая операция. Поэтому для твоего случая лучше хранить уровень в реквизите и обновлять при записи элемента в 1с (средствами 1с), либо тригером.
  
Наверх
 
IP записан
 
Bagirius
Full Member
***
Отсутствует



Сообщений: 135
Зарегистрирован: 19. Февраля 2008
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #2 - 29. Апреля 2008 :: 09:46
Печать  
Не знаю на сколько правильно, но группы верхнего уровня добавляю в запрос следующим образом

МД = СоздатьОбъект("MetaDataWork");
УсловиеГрупп = "Номенклатура.ID IN ('" + МД.ЗначениеВСтрокуБД(ТекРодитель) + "'";
ВремРодитель = ТекРодитель;
Для А = 1 По  ТекРодитель.Уровень() Цикл
     ВремРодитель = ВремРодитель.Родитель;
     УсловиеГрупп = УсловиеГрупп + " , '" +  МД.ЗначениеВСтрокуБД(ВремРодитель) + "'";
КонецЦикла;                  
УсловиеГрупп = УсловиеГрупп + ")";

И получается у меня такое вот условие:

WHERE = WHERE + "((Номенклатура.PARENTID = :ТекРодитель) OR ";
WHERE = WHERE + УсловиеГрупп + ")";

Можно ли сразу при переборе групп фиксировать в данных их уровень?
  
Наверх
ICQ  
IP записан
 
Bagirius
Full Member
***
Отсутствует



Сообщений: 135
Зарегистрирован: 19. Февраля 2008
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #3 - 29. Апреля 2008 :: 12:10
Печать  
СДЕЛАЛ!!!
Через CASE
  
Наверх
ICQ  
IP записан
 
ReLock
Full Member
***
Отсутствует



Сообщений: 155
Местоположение: За компом
Зарегистрирован: 01. Февраля 2007
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #4 - 29. Апреля 2008 :: 15:05
Печать  
Результат в студию  Улыбка
  
Наверх
 
IP записан
 
Bagirius
Full Member
***
Отсутствует



Сообщений: 135
Зарегистрирован: 19. Февраля 2008
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #5 - 30. Апреля 2008 :: 10:10
Печать  
SELECT Номенклатура.ID as [Товар $Справочник.Номенклатура]
     , Номенклатура.IsMark as IsMark
     , Номенклатура.IsFolder as IsFolder
     , Номенклатура.PARENTID as [Родитель $Справочник.Номенклатура]
     , (CASE
           WHEN (Номенклатура.ID = '   2TM   ') THEN '2'
           WHEN (Номенклатура.ID = '    3S   ') THEN '1'
           WHEN (Номенклатура.ID = '     0   ') THEN '0'
           ELSE '10'
     END) as Уровень
     , Номенклатура.CODE as Код
     , Номенклатура.DESCR as Наименование
     , $Номенклатура.Артикул as Артикул
     , $Номенклатура.ОригинальныйНомер as [ОЕ $Справочник.OE_Номера]
     , $Номенклатура.БазоваяЕдиницаИзмерения as [ЕдИзм $Перечисление.ЕдиницыИзмерения]            
     , Номенклатура.ID as ИД
     , (ПартииТоваровОстатки.ОстатокТовараОстаток - IsNull(РезервыТоваровОстатки.РезервТовараОстаток, 0)) as Остаток
     , (РезервыТоваровОстатки.РезервТовараОстаток) as Резерв
FROM $Справочник.Номенклатура AS Номенклатура
     LEFT OUTER JOIN $РегистрОстатки.ПартииТоваров(,
           RIGHT OUTER JOIN $Справочник.Номенклатура AS Номенклатура
           ON Номенклатура.ID = Товар,(Склад = :ВыбСклад) AND (Фирма = :ВыбФирма),(Фирма, Товар, Склад),) AS ПартииТоваровОстатки
                 ON Номенклатура.ID = ПартииТоваровОстатки.Товар
     LEFT OUTER JOIN $РегистрОстатки.РезервыТоваров(,
           RIGHT OUTER JOIN $Справочник.Номенклатура AS Номенклатура ON Номенклатура.ID = Товар,,
           (Фирма, Товар, Склад),) AS РезервыТоваровОстатки
     ON Номенклатура.ID = РезервыТоваровОстатки.Товар
     AND ПартииТоваровОстатки.Фирма = РезервыТоваровОстатки.Фирма
     AND ПартииТоваровОстатки.Склад = РезервыТоваровОстатки.Склад
WHERE (($Номенклатура.Фирма = :ВыбФирма) OR ($Номенклатура.Фирма = $ПустойИд)) AND (((ПартииТоваровОстатки.ОстатокТовараОстаток - IsNull(РезервыТоваровОстатки.РезервТовараОстаток, 0)) <> 0) OR (Номенклатура.IsFolder = 1)) AND ((Номенклатура.PARENTID = :ТекРодитель) OR Номенклатура.ID IN ('   2TM   ' , '    3S   ' , '     0   '))



Так я строил часть текста запроса

WHERE = WHERE + "((Номенклатура.PARENTID = :ТекРодитель) OR ";
МД = СоздатьОбъект("MetaDataWork");
УсловиеГрупп = "Номенклатура.ID IN ('" + МД.ЗначениеВСтрокуБД(ТекРодитель) + "'";
УровниГрупп = "WHEN (Номенклатура.ID = '" + МД.ЗначениеВСтрокуБД(ТекРодитель) + "') THEN '" + (ТекРодитель.Уровень()) + "'";
ВремРодитель = ТекРодитель;
Для А = 1 По  ТекРодитель.Уровень() Цикл
     ВремРодитель = ВремРодитель.Родитель;
     УровниГрупп = УровниГрупп + "
           |WHEN (Номенклатура.ID = '" + МД.ЗначениеВСтрокуБД(ВремРодитель) + "') THEN '" + ВремРодитель.Уровень() + "'";
     УсловиеГрупп = УсловиеГрупп + " , '" +  МД.ЗначениеВСтрокуБД(ВремРодитель) + "'";
КонецЦикла;                  
УсловиеГрупп = УсловиеГрупп + ")";
WHERE = WHERE + УсловиеГрупп + ")";      
  
Наверх
ICQ  
IP записан
 
sml
Full Member
***
Отсутствует


I Love 1С++!

Сообщений: 186
Зарегистрирован: 28. Февраля 2008
Re: Как в запросе получить Уровень()
Ответ #6 - 07. Мая 2008 :: 12:26
Печать  
Код
Выбрать все
     , (CASE
	     WHEN (Номенклатура.ID = '   2TM   ') THEN '2'
	     WHEN (Номенклатура.ID = '    3S   ') THEN '1'
	     WHEN (Номенклатура.ID = '     0   ') THEN '0'
	     ELSE '10'  



а разве у тебя в справочнике Номенклатуры только 3 группы, причем каждая на своем уровне, а остальные - элементы?
  
Наверх
 
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #7 - 18. Мая 2008 :: 18:05
Печать  
Примерно так:
Код
Выбрать все
CREATE FUNCTION ufn_getLevelSpr (@IDSpr Char(9))
RETURNS  Int
BEGIN
DECLARE @R Char(9)
DECLARE @Lev Int
	SET @Lev = 0
	SET @R = @IDSpr
	WHILE (@R <> '     0   ') AND (@R IS NOT NULL)
	BEGIN
		SELECT
		@R = PARENTID, @Lev = @Lev + 1
		FROM SC148
		WHERE
			(ID = @R)
	END
	RETURN @Lev
END

GO

SELECT ID, dbo.ufn_getLevelSpr(ID) AS Level FROM SC148

 

  
Наверх
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #8 - 20. Мая 2008 :: 08:29
Печать  
Только что пришлось лечить базу, в которой была цикличная группировка (грА.Родитель=грБ и грБ.Родитель=грА), МОД чего то там накосячил, так что не исключайте и такую возможность
  
Наверх
ICQ  
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #9 - 20. Мая 2008 :: 10:48
Печать  
Ну тогда:
Код
Выбрать все
CREATE FUNCTION ufn_getLevelSpr (@IDSpr Char(9))
RETURNS  Int
BEGIN
DECLARE @R Char(9)
DECLARE @Lev Int
	SET @Lev = 0
	SET @R = @IDSpr
	WHILE (@R <> '     0   ') AND (@R IS NOT NULL) AND (@Lev <=11)
	BEGIN
		SELECT
		@R = PARENTID, @Lev = @Lev + 1
		FROM SC148
		WHERE
			(ID = @R)
	END
	RETURN @Lev
END 


В 1С макс 10 уровней.
  
Наверх
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Как в запросе получить Уровень()
Ответ #10 - 20. Мая 2008 :: 12:59
Печать  
"В 1С макс 10 уровней. " - програмно можно сколько хочешь сделать.
"(@Lev <=11)"  почему тогда не "(@Lev <11)" ?
"(@R IS NOT NULL)" - родитель не может быть NULL-ом.
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #11 - 21. Мая 2008 :: 05:07
Печать  
Для пользователей МОД-а и создателей разных видов обмена... Вести с полей Улыбка
Структура папок была - "Пиво пр-во Россия"<-"Продукция Хайнекен"(подчиненный). Начали приводить структуру в соответствие с советами консультантов (типа в Масскве лучше знают), создали новые папки под Пиво, раскидали туда товары, а эти папки стали переименовывать и раскидывать по новому, в результате оказалось "Кондитерка"<-"Мучные изделия (Бывший Ханекен)"<-"Круассаны (бывшее Пиво Россия)". Все бы ничего, но в пакете выгрузки "Пиво Россия" выгружено раньше, в результате при приеме данных сначала загрузилось оно (и создалась циклическая ссылка), а уже потом должен был прогрузится "Хайнекен" и цикличность была бы разорвана...
Решилось созданием отложенной записи: при смене родителя - смотрим, не подчинен ли новый родитель этому элементу, если подчинен, то ничего не меняем, просто закидываем эту инфу в спец ТЗ, и далее если при загрузке цикл будет разорван, то производим смену Родителя, если же нет, значит инфа о смене Родителя "отправится фтопку"
Вот такие вот грабли.
  
Наверх
ICQ  
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #12 - 21. Мая 2008 :: 06:30
Печать  
sadovnikov писал(а) 20. Мая 2008 :: 12:59:
"В 1С макс 10 уровней. " - програмно можно сколько хочешь сделать.
"(@Lev <=11)"  почему тогда не "(@Lev <11)" ?
"(@R IS NOT NULL)" - родитель не может быть NULL-ом.

В 1С - да, но ведь можно и свой справочник сделать, по типу 1С и там уже можно NULL разрешить.
Если программно можно - тогда можно поставить 100 например, или 255.
  
Наверх
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Как в запросе получить Уровень()
Ответ #13 - 21. Мая 2008 :: 06:53
Печать  
pvase писал(а) 21. Мая 2008 :: 06:30:
В 1С - да, но ведь можно и свой справочник сделать, по типу 1С и там уже можно NULL разрешить.
Если программно можно - тогда можно поставить 100 например, или 255.


Не понял. Что есть "свой справочник по типу 1С"?
Если создавать будешь свою таблицу - кто мешает сразу туда заложить поле Уровень?
  
Наверх
 
IP записан
 
pvase
God Member
*****
Отсутствует



Сообщений: 923
Местоположение: Киев
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Как в запросе получить Уровень()
Ответ #14 - 21. Мая 2008 :: 07:07
Печать  
sadovnikov писал(а) 21. Мая 2008 :: 06:53:
Не понял. Что есть "свой справочник по типу 1С"?
Если создавать будешь свою таблицу - кто мешает сразу туда заложить поле Уровень?

Есть разные задачи и разное их решения, оба решения имеют право на применение.
  
Наверх
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать