Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Очень популярная тема (более 25 ответов) Как запросом получить наименование всех уровней? (число прочтений - 8316 )
admin spb
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 150
Зарегистрирован: 26. Апреля 2007
Пол: Мужской
Как запросом получить наименование всех уровней?
02. Августа 2009 :: 10:48
Печать  
Есть код:

ТабНоменктурара = СоздатьОбъект("ТаблицаЗначений");
База = СоздатьОбъект("SQLiteBase");
База.Открыть(":memory:");
Запрос = база.НовыйЗапрос();
Запрос.ВыполнитьЗапрос("SELECT * FROM Справочник_Номенклатура AS Спр",ТабНоменктурара);
СпНоменклатура = СоздатьОбъект("Справочник.Номенклатура");


ТабНоменктурара.НоваяКолонка("Уровень1");
ТабНоменктурара.НоваяКолонка("Уровень2");
ТабНоменктурара.НоваяКолонка("Уровень3");
ТабНоменктурара.НоваяКолонка("Уровень4");


Для а = 1 По ТабНоменктурара.КоличествоСтрок()  Цикл
ТабНоменктурара.ПолучитьСтрокуПоНомеру(а);
сли СпНоменклатура.НайтиПоКоду(ТабНоменктурара.Code,0) = 1 Тогда

     Если СпНоменклатура.Уровень() = 1  Тогда
                                   ТабНоменктурара.Уровень1 = "";
                                   ТабНоменктурара.Уровень2 = "";
                                   ТабНоменктурара.Уровень3 = "";
                                   ТабНоменктурара.Уровень4 = "";
                       КонецЕсли;
                       Если СпНоменклатура.Уровень() = 2 Тогда
                                   ТабНоменктурара.Уровень1 = СокрЛП(СпНоменклатура.Родитель.Наименование);
                                   ТабНоменктурара.Уровень2 = "";
                                   ТабНоменктурара.Уровень3 = "";
                                   ТабНоменктурара.Уровень4 = "";
                       КонецЕсли;            
                             
                       Если СпНоменклатура.Уровень() = 3 Тогда
                                   ТабНоменктурара.Уровень1 = СокрЛП(СпНоменклатура.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень2 = СокрЛП(СпНоменклатура.Родитель.Наименование);
                                   ТабНоменктурара.Уровень3 = "";
                                   ТабНоменктурара.Уровень4 = "";
                                   
                       КонецЕсли;            
                             
                       Если СпНоменклатура.Уровень() = 4 Тогда
                                   ТабНоменктурара.Уровень1 = СокрЛП(СпНоменклатура.Родитель.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень2 = СокрЛП(СпНоменклатура.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень3 = СокрЛП(СпНоменклатура.Родитель.Наименование);
                                   ТабНоменктурара.Уровень4 = "";
                                   
                       КонецЕсли;                  
                             
                       
                             
                             Если СпНоменклатура.Уровень() = 5 Тогда
                                   ТабНоменктурара.Уровень1 = СокрЛП(СпНоменклатура.Родитель.Родитель.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень2 = СокрЛП(СпНоменклатура.Родитель.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень3 = СокрЛП(СпНоменклатура.Родитель.Родитель.Наименование);
                                   ТабНоменктурара.Уровень4 = СокрЛП(СпНоменклатура.Родитель.Наименование);
                                   
                       КонецЕсли;      
     
     
           КонецЕсли;      
     

     
КонецЦикла;




Код работает, хотелось бы узнать, можно ли все это сделать, в одном запросе... т.к. НайтиПоКоду очень долго работает...
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Как запросом получить наименование всех уровней?
Ответ #1 - 02. Августа 2009 :: 13:34
Печать  
не уверен как правильно для SQLLite, просто для sql как то так
Код
Выбрать все
select
 спр.id  Элемент,
 спр1.id Группа1,
 спр2.id Группа2,
 спр3.id Группа3,
....и тд

from
 $Справочник.Номенклатура спр
left join
 $Справочник.Номенклатура спр1 on спр1.id = спр.parentid
left join
 $Справочник.Номенклатура спр2 on спр2.id = спр1.parentid
left join
 $Справочник.Номенклатура спр3 on спр3.id = спр2.parentid 

  
Наверх
 
IP записан
 
admin spb
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 150
Зарегистрирован: 26. Апреля 2007
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #2 - 02. Августа 2009 :: 13:53
Печать  
Спасибо за пример!
и я правильно не знаю, как сделать на sqllife(
  
Наверх
 
IP записан
 
admin spb
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 150
Зарегистрирован: 26. Апреля 2007
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #3 - 03. Августа 2009 :: 10:54
Печать  
Помогите плз, примером!!!
  
Наверх
 
IP записан
 
leov-001
Full Member
***
Отсутствует


1C++ rocks!

Сообщений: 150
Зарегистрирован: 05. Марта 2009
Re: Как запросом получить наименование всех уровней?
Ответ #4 - 03. Августа 2009 :: 12:17
Печать  
Код
Выбрать все
Select
  Спр.Descr  Элемент
, Спр1.Descr Группа1
, Спр2.Descr Группа2
, Спр3.Descr Группа3
From
  Справочник_Номенклатура Спр
  Left Join Справочник_Номенклатура Спр1 on Спр1.id = Спр.ParentId  and Спр1.IsFolder = 1
  Left Join Справочник_Номенклатура Спр2 on Спр2.id = Спр1.ParentId and Спр2.IsFolder = 1
  Left Join Справочник_Номенклатура Спр3 on Спр3.id = Спр2.ParentId and Спр3.IsFolder = 1
Where Спр.IsFolder = 2 

  
Наверх
 
IP записан
 
admin spb
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 150
Зарегистрирован: 26. Апреля 2007
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #5 - 03. Августа 2009 :: 14:37
Печать  
Огромное спасибо! Но все же это не много не то...
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #6 - 03. Августа 2009 :: 14:51
Печать  
(0) Храни уровень в реквизите справочника.
Тогда subj очень легко решается простым запросом.
Если так будешь делать надо переписывать перенос элемента или
группы в другую группу.
  
Наверх
 
IP записан
 
grayrat
Junior Member
**
Отсутствует



Сообщений: 99
Местоположение: Russia, Moscow
Зарегистрирован: 20. Мая 2006
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #7 - 03. Августа 2009 :: 16:01
Печать  
Если все элементы сидят в папках самого нижнего уровня, то подойдет вот такой запрос:

Код
Выбрать все
Select
  nom.Descr Элемент,
  n1.Descr Уровень1,
  isNull(n2.Descr,'') Уровень2,
  isNull(n3.Descr,'') Уровень3,
  isNull(n4.Descr,'') Уровень4,
  isNull(n5.Descr,'') Уровень5
from $Справочник.Номенклатура n1 (nolock)
Left Join $Справочник.Номенклатура n2 (nolock) on n1.Id = n2.ParentId And n2.isFolder=1
Left Join $Справочник.Номенклатура n3 (nolock) on isNull(n2.Id,n1.id)=n3.ParentId And n3.isFolder=1
Left Join $Справочник.Номенклатура n4 (nolock) on isNull(n3.Id,isNull(n2.Id,n1.id))=n4.ParentId  And n4.isFolder=1
Left Join $Справочник.Номенклатура n5 (nolock) on isNull(n4.Id,isNull(n3.Id,isNull(n2.Id,n1.id)))=n5.ParentId  And n5.isFolder=1
Inner Join $Справочник.Номенклатура nom (nolock) on isNull(n5.Id,isNull(n4.Id,isNull(n3.Id,isNull(n2.Id,n1.id))))=nom.ParentId And nom.isFolder=2
Where n1.isFolder=1 And n1.ParentId = '     0'
 

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



Сообщений: 99
Местоположение: Russia, Moscow
Зарегистрирован: 20. Мая 2006
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #8 - 04. Августа 2009 :: 05:57
Печать  
А вот так все попадает:

Код
Выбрать все
Select
  nom.Descr Элемент,
  u.Уровень1,
  u.Уровень2,
  u.Уровень3,
  u.Уровень4,
  u.Уровень5
From
(
    Select '     0' Id, '' Уровень1, '' Уровень2, '' Уровень3, '' Уровень4, '' Уровень5
  UNION
    Select n1.Id, n1.Descr, '', '', '', ''
    From $Справочник.Номенклатура n1 (nolock)
    Where n1.isFolder=1 And n1.ParentId = '     0'
  UNION
    Select n2.Id, n1.Descr, n2.Descr, '', '', ''
    From $Справочник.Номенклатура n1 (nolock)
    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
    Where n1.isFolder=1 And n1.ParentId = '     0'
  UNION
    Select n3.Id, n1.Descr, n2.Descr, n3.Descr, '', ''
    From $Справочник.Номенклатура n1 (nolock)
    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
    Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
    Where n1.isFolder=1 And n1.ParentId = '     0'
  UNION
    Select n4.Id, n1.Descr, n2.Descr, n3.Descr, n4.Descr, ''
    From $Справочник.Номенклатура n1 (nolock)
    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
    Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
    Inner Join $Справочник.Номенклатура n4 (nolock) On n3.Id = n4.ParentId And n4.isFolder=1
    Where n1.isFolder=1 And n1.ParentId = '     0'
  UNION
    Select n5.Id, n1.Descr, n2.Descr, n3.Descr, n4.Descr, n5.Descr
    From $Справочник.Номенклатура n1 (nolock)
    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
    Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
    Inner Join $Справочник.Номенклатура n4 (nolock) On n3.Id = n4.ParentId And n4.isFolder=1
    Inner Join $Справочник.Номенклатура n5 (nolock) On n4.Id = n5.ParentId And n5.isFolder=1
    Where n1.isFolder=1 And n1.ParentId = '     0'
) u
Inner Join $Справочник.Номенклатура nom (nolock) on u.Id = nom.ParentId And nom.isFolder=2
 

  
Наверх
 
IP записан
 
admin spb
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 150
Зарегистрирован: 26. Апреля 2007
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #9 - 04. Августа 2009 :: 07:36
Печать  
Огромное Вам спасибо, что ответили.

Я не работал с прямыми запросами... только на sqllife

Делаю так:
Код
Выбрать все
RS = СоздатьОбъект("ODBCRecordset");
RS.УстБД1С();
ТекстЗапроса = ("Select
	|  nom.Descr Элемент,
	|  u.Уровень1,
	|  u.Уровень2,
	|  u.Уровень3,
	|  u.Уровень4,
	|  u.Уровень5
	|From
	|(
	|Select '     0' Id, '' Уровень1, '' Уровень2, '' Уровень3, '' Уровень4, '' Уровень5
	|  UNION
	|    Select n1.Id, n1.Descr, '', '', '', ''
	|    From $Справочник.Номенклатура n1 (nolock)
	|    Where n1.isFolder=1 And n1.ParentId = '     0'
	|  UNION
	|    Select n2.Id, n1.Descr, n2.Descr, '', '', ''
	|    From $Справочник.Номенклатура n1 (nolock)
	|    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
	|    Where n1.isFolder=1 And n1.ParentId = '     0'
	|  UNION
	|    Select n3.Id, n1.Descr, n2.Descr, n3.Descr, '', ''
	|    From $Справочник.Номенклатура n1 (nolock)
	|    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
	|   Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
	|    Where n1.isFolder=1 And n1.ParentId = '     0'
	|  UNION
	|    Select n4.Id, n1.Descr, n2.Descr, n3.Descr, n4.Descr, ''
	|    From $Справочник.Номенклатура n1 (nolock)
	|    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
	|    Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
	|    Inner Join $Справочник.Номенклатура n4 (nolock) On n3.Id = n4.ParentId And n4.isFolder=1
	|    Where n1.isFolder=1 And n1.ParentId = '     0'
	|  UNION
	|    Select n5.Id, n1.Descr, n2.Descr, n3.Descr, n4.Descr, n5.Descr
	|    From $Справочник.Номенклатура n1 (nolock)
	|    Inner Join $Справочник.Номенклатура n2 (nolock) On n1.Id = n2.ParentId And n2.isFolder=1
	|    Inner Join $Справочник.Номенклатура n3 (nolock) On n2.Id = n3.ParentId And n3.isFolder=1
	|    Inner Join $Справочник.Номенклатура n4 (nolock) On n3.Id = n4.ParentId And n4.isFolder=1
	|	Inner Join $Справочник.Номенклатура n5 (nolock) On n4.Id = n5.ParentId And n5.isFolder=1
	|    Where n1.isFolder=1 And n1.ParentId = '     0'
	|) u
	|Inner Join $Справочник.Номенклатура nom (nolock) on u.Id = nom.ParentId And nom.isFolder=2");



ТЗ = RS.ВыполнитьИнструкцию(ТекстЗапроса);
Сообщить(ТЗ);
 



В ответ получаю = 0.
Что я не так делаю?
  
Наверх
 
IP записан
 
VoditelKobyly
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 22
Зарегистрирован: 13. Февраля 2009
Пол: Мужской
Re: Как запросом получить наименование всех уровней?
Ответ #10 - 04. Августа 2009 :: 08:29
Печать  
На первый взгляд все должно работать.

1. Поменяй Сообщить(ТЗ) на ТЗ.ВыбратьСтроку() должен увидеть таблицу.
2. Если таблица будет пустой отлаживай почастям. Комментируй части запроса. Например получи для начала наименования первого уровня, потом туда же второго и т.д.
  
Наверх
 
IP записан
 
mrgreen
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 32
Зарегистрирован: 01. Августа 2009
Re: Как запросом получить наименование всех уровней?
Ответ #11 - 20. Августа 2009 :: 11:32
Печать  
задам вопрос тут Улыбка

необходимо проверить вхождение элемента в группу (это может быть и группа более верхнего уровня чем непосредственный родитель) как это сделать быстро, как отрабатывает метод "в ОбъектГруппа" в самой 1це ?

дело в том что пробовал через соединение с таблицей аналогом сдешней (и отбором по необходмой группе в любом поле из групп) - отрабатывает медленнее чем метод 1це

пробовал хранимой функцией - ещё раз в пять дольше получается

как 1це это делает так быстро ?!!!
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Как запросом получить наименование всех уровней?
Ответ #12 - 20. Августа 2009 :: 11:45
Печать  
mrgreen писал(а) 20. Августа 2009 :: 11:32:
как 1це это делает так быстро ?!!!

профайлер в зу руки и смотреть как она это делаетУлыбка Тут пару дней назад постили функцию для проверки вхождения в группу
  
Наверх
 
IP записан
 
mrgreen
Junior Member
**
Отсутствует


1C++ rocks!

Сообщений: 32
Зарегистрирован: 01. Августа 2009
Re: Как запросом получить наименование всех уровней?
Ответ #13 - 20. Августа 2009 :: 11:57
Печать  
Код
Выбрать все
Тут пару дней назад постили функцию для проверки вхождения в группу  



это ту что я постил ? Улыбка она безбожно тупит если элементов за лимон (это же по каждому надо выбрать все группы вверх и вернуть ответ)

Код
Выбрать все
профайлер  



эээ... простите за тупизм а подробнее  ?


пысы... не ну проблема то решаема при помощи передачи списка элементов полученных простым 1це запросом по справочнику и выгрузкой его ИД-ов в строку подстановки при формировании текста запроса но это ведь некрасиво и насколько я помню IN таки ограничен по быстродействию
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Как запросом получить наименование всех уровней?
Ответ #14 - 20. Августа 2009 :: 12:02
Печать  
Миллион элементов в 7ке? Нехилый справочник.
Профайлер - EM в меню Tools(Profiler) или в меню пуск в группе Microsoft SQL Server. Настраиваете отборы, запускаете трасу и смотрите какие запросы кидает 1С серверу. Я честно говоря сам не знаю как она уровень получает
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать