Переключение на Главную Страницу Страницы: [1]  ОтправитьПечать
Очень популярная тема (более 25 ответов) Отобрать подчиненные и док. основания (число прочтений - 8191 )
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Отобрать подчиненные и док. основания
29. Января 2008 :: 14:11
Печать  
Есть группа документов, вводимых на основании друг друга, структура подчиненности может быть нелинейной. Как имея один документ любого уровня подчиненности получить список всех взаимосвязанных документов?
Заранее спасибо
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #1 - 29. Января 2008 :: 14:33
Печать  
Если для отчёта, тут неплохой пример:
Граф подчиненности документов
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
JohnyDeath
1c++ power user
1c++ donor
Отсутствует



Сообщений: 3050
Местоположение: Волгоград
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #2 - 29. Января 2008 :: 14:55
Печать  
Или вот ещё одна реализация графа подчиненности от noprogrammera
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #3 - 29. Января 2008 :: 15:16
Печать  
Не видел, как в приведенных выше ссылках сделано, но, чем черт не шутит - может, у меня по другому Улыбка

Код
Выбрать все
	ИдНачДока13	= РадугаСервис.ЗначениеВДлиннуюСтрокуБД(ДокДерева);
	ИдНачДока9	= Прав(ИдНачДока13,9);
	ТабДоковSQL	= глИмяВременнойТаблицы(); //"#ТабДоков"; //

	ОщийРеквизитДокументОснование	= //SP158
	ОщийРеквизитСуммаДокумента		= "SP"+РадугаМД.ИДОбъекта(Метаданные.ОбщийРеквизитДокумента("СуммаДокумента"));

	ТекстЗапроса = "
	| Set NoCount On
	| Declare @ИдТемпДок13 Char(13), @ИдКореньДок13 Char(13), @ИдПустойДок Char(13)
	|
	| Set @ИдПустойДок = '   0     0   '
	| Set @ИдТемпДок13 = '"+ИдНачДока13+"'
	|
	| While @ИдТемпДок13 <> @ИдПустойДок Begin
	| 	Set @ИдКореньДок13 = @ИдТемпДок13
	| 	Set @ИдТемпДок13   =
	| 		(
	| 			Select Top 1 "+ОщийРеквизитДокументОснование+" ДокОснование From _1SJOURN (NoLock)
	| 			Where IDDOC = Right(@ИдКореньДок13,9)
	| 		)
	| End
	|
	| Select Cast(Right(@ИдПустойДок,9) As Char(9)) ИдРодителя9, @ИдПустойДок ИдРодителя13, Cast(Right(@ИдКореньДок13,9) As Char(9)) ИдПодчДок9, @ИдКореньДок13 ИдПодчДок13 Into "+ТабДоковSQL+"
	|
	| While 1 = 1 Begin
	|	  Insert Into "+ТабДоковSQL+" (ИдРодителя9, ИдРодителя13, ИдПодчДок9, ИдПодчДок13)
	| 	Select
	| 		ИдРодителя9, ИдРодителя13, ИдПодчДок9, ИдПодчДок13
	| 	From
	| 	(
	| 	 	Select Right(ИдПодчДок13,9) ИдРодителя9, ИдПодчДок13 ИдРодителя13, Right(CHILD_DATE_TIME_IDDOC, 9) ИдПодчДок9, Журнал.SP810 ИдПодчДок13
	|		  From _1SCRDOC (NoLock)
	| 	 	Inner Join "+ТабДоковSQL+" (NoLock) On MDID = 0 And ParentVal = 'O1'+ИдПодчДок13
	| 		Left Join _1SJOURN Журнал (NoLock) On Журнал.IDDOC = CHILDID
	| 	 	Where
	| 		ИдПодчДок13 Not In (Select ИдРодителя13 From "+ТабДоковSQL+" (NoLock))
	| 	) Выборка
	| 	Where
	| 	ИдПодчДок9 Not In (Select ИдРодителя9 From "+ТабДоковSQL+" (NoLock))
	| 	And ИдПодчДок9 Not In (Select ИдПодчДок9 From "+ТабДоковSQL+" (NoLock))
	| 	And dbo.ВозможностьПодчинения(ИдРодителя9, ИдПодчДок9) = 1
	|
	| 	If @@RowCount = 0
	| 		Break
	| End
	|
	|
	| Select ИдРодителя9, ИдПодчДок9, IdDocDef ВидПодчДок
	| , dbo.ПредставлениеДокумента(ИдПодчДок9,1,1) ПредставлениеДока
	| , (Case When IsMark = 1 Then 3 Else Case When Closed&1 = 1 Then 2 Else 1 End End) Признак
	| , "+ОщийРеквизитСуммаДокумента+" СуммаДокумента
	| From "+ТабДоковSQL+" (NoLock)
	| Left Join _1SJOURN (NoLock) On ИдПодчДок9 = IDDOC
	| Order By Date_Time_IDDOC
	|
	| Drop Table "+ТабДоковSQL+"
	|
	| ";
 

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


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #4 - 29. Января 2008 :: 17:02
Печать  
Спасибо всем, беру таймаут чтобы попробывать
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #5 - 30. Января 2008 :: 07:29
Печать  
Спасибо всем за инфу
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. Я делал также, алгоритм адаптирован к построению дерева, из предложенного взял поиск Документа основания через1С++. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?

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


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #6 - 30. Января 2008 :: 08:03
Печать  
Что есть "список связанных документов"?
  
Наверх
 
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #7 - 30. Января 2008 :: 08:24
Печать  
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Отобрать подчиненные и док. основания
Ответ #8 - 30. Января 2008 :: 08:31
Печать  
Цитата:
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?

+1

Сам исправлял подобное - достаточно много геморроя при исправлении - но потом лафа.
Особенно лафа прочувствовалась когда потребовалось дополнительно вводить сторнирущие
и корректирующие документы - тут по подчиненным не убегаешься.
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #9 - 30. Января 2008 :: 10:43
Печать  
mov68 писал(а) 30. Января 2008 :: 07:29:
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?

Можно сложить все инструкции в один запрос. Скажем, так:
Код
Выбрать все
	рс = СоздатьОбъект("ODBCRecordSet");
	рс.УложитьСписокОбъектов(спВыбДоки, "#docs");
	рс.ВыполнитьИнструкцию("
		|set nocount on
		|while 1=1 begin
		|	insert #docs (val)
		|	select substring(parentval, 7, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on childid = val
		|	where mdid = 0
		|		and substring(parentval, 7, 9) not in (select val from #docs)
		|	if @@rowcount = 0 break
		|end
		|while 1=1 begin
		|	insert #docs (val)
		|	select right(child_date_time_iddoc, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on parentval like 'O1____' + val
		|	where mdid = 0
		|		and right(child_date_time_iddoc, 9) not in (select val from #docs)
		|	if @@rowcount = 0 break
		|end
		|set nocount off
		|");
	спДоки = рс.ВыполнитьИнструкцию("
		|select val [Док $Документ]
		|	, iddocdef Док_вид
		|from #docs
		|	inner join _1sjourn (nolock) on val = iddoc
		|", СоздатьОбъект("СписокЗначений")); 


Или так:
Код
Выбрать все
	рс.ВыполнитьИнструкцию("
		|set nocount on
		|declare @doccount integer
		|set @doccount = 1
		|while @doccount > 0 begin
		|	insert #docs (val)
		|	select right(child_date_time_iddoc, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on parentval like 'O1____' + val
		|	where mdid = 0
		|		and right(child_date_time_iddoc, 9) not in (select val from #docs)
		|	set @doccount = @@rowcount
		|	insert #docs (val)
		|	select substring(parentval, 7, 9)
		|	from _1scrdoc (nolock)
		|		inner join #docs on childid = val
		|	where mdid = 0
		|		and substring(parentval, 7, 9) not in (select val from #docs)
		|	set @doccount = @doccount + @@rowcount
		|end
		|set nocount off
		|"); 


Во втором варианте, в общем случае, количество найденных документов будет больше, чем в первом.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #10 - 30. Января 2008 :: 14:57
Печать  
sadovnikov писал(а) 30. Января 2008 :: 08:03:
Что есть "список связанных документов"?


Документы, вводимые на основании друг друга
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #11 - 30. Января 2008 :: 14:58
Печать  
kiruha писал(а) 30. Января 2008 :: 08:31:
Цитата:
Если хочется ускорить, то может хранить данные в регистре а не выуживать их бегая по десяткам доков? Как считаешь?

+1

Сам исправлял подобное - достаточно много геморроя при исправлении - но потом лафа.
Особенно лафа прочувствовалась когда потребовалось дополнительно вводить сторнирущие
и корректирующие документы - тут по подчиненным не убегаешься.


Поделитесь реализацией, плиз...
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #12 - 30. Января 2008 :: 15:03
Печать  
berezdetsky писал(а) 30. Января 2008 :: 10:43:
mov68 писал(а) 30. Января 2008 :: 07:29:
Все описанные методы используют следующее: поиск документа верхнего уровня, сефинг вниз по подчиненным документам, при этом число запросов в общем случае 2*ЧислоУровнейИерархии. А если дерево подчиненности не нужно, нужен только список связанных документов, можно ли уменьшить общее число запросов (применяю это в модуле проведения, хочется ускорить)?


Можно сложить все инструкции в один запрос. Скажем, так: [code]      Во втором варианте, в общем случае, количество найденных документов будет больше, чем в первом.


Кажется то что нужно, попробую
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #13 - 31. Января 2008 :: 04:40
Печать  
Создать таблицу структуры:
- первый док сделки.
- текущий док сделки.

При записи документа писать в нее. А потом элементарным селектом доставать все документы.
Быстро и дешево.
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #14 - 31. Января 2008 :: 11:38
Печать  
sadovnikov писал(а) 31. Января 2008 :: 04:40:
Создать таблицу структуры:
- первый док сделки.
- текущий док сделки.

При записи документа писать в нее. А потом элементарным селектом доставать все документы.
Быстро и дешево.


При этом, как я понимаю, при записи каждого документа необходимо найти коренной документ (первый документ сделки), тогда для произвольного документа извлекаем корневой документ и уже по нему быстро и дешево получаем все связанные. Если при записи поиск не делать, а в таблицу писать Документ основание - текущий документ, то возвращаемся к первоначальной задаче но по другой таблице. Или я что-то упустил?
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #15 - 31. Января 2008 :: 11:55
Печать  
mov68 писал(а) 31. Января 2008 :: 11:38:
При этом, как я понимаю, при записи каждого документа необходимо найти коренной документ (первый документ сделки), тогда для произвольного документа извлекаем корневой документ и уже по нему быстро и дешево получаем все связанные. Если при записи поиск не делать, а в таблицу писать Документ основание - текущий документ, то возвращаемся к первоначальной задаче но по другой таблице. Или я что-то упустил?


Именно так.
Найти первый документ сделки - довольно быстрая операция. Причем, этот первый документ можно искать тоже в этой таблице, используя IDDOC документа-основания. Если документа основания нет - то и искать ничего не надо.
Единственно, надо продумать - что хотим увидеть, когда документ находится в табличной части другого документа.
  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #16 - 31. Января 2008 :: 12:01
Печать  
Поддержую.
1 этап - по документу основанию находим коренной документ (select mainID from ... where ChildID='ид-шник основания')
2 этап - по документу корню поднимаем всю цепочку (select ChildID from ... where mainID='ид-шник корня полученный на 1-м этапе') добавляем доп ходы типа сортировку/грппировку/проч. и пользуемся
  
Наверх
ICQ  
IP записан
 
Вадимко
God Member
*****
Отсутствует


Нам бы чего про ОдноЦэ...

Сообщений: 1048
Местоположение: Минск
Зарегистрирован: 24. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #17 - 31. Января 2008 :: 12:26
Печать  
Не завидую тому кто придет сопровождать творение автора Улыбка
  

Кампутер, кофе и сигареты - это очень плохо для моего здоровья...
Наверх
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #18 - 31. Января 2008 :: 12:29
Печать  
Salimbek писал(а) 31. Января 2008 :: 12:01:
Поддержую.
1 этап - по документу основанию находим коренной документ (select mainID from ... where ChildID='ид-шник основания')
2 этап - по документу корню поднимаем всю цепочку (select ChildID from ... where mainID='ид-шник корня полученный на 1-м этапе') добавляем доп ходы типа сортировку/грппировку/проч. и пользуемся


В таком виде тоже поддерживаю, сразу не понял, что для основания у нас уже есть запись в таблице и корень ищем быстро.
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #19 - 31. Января 2008 :: 12:34
Печать  
Еще один вопрос, при таком подходе, если документа основания нет, то желательно в таблицу прописать строку текущий документ - текущий документ ? Ведь мы заранее не знаем, будет ли вводиться на основании и корень не будет присутствовать в таблице. Или эту проверку лучше оставить программной?
  
Наверх
 
IP записан
 
sadovnikov
1c++ power user
Отсутствует


I Love YaBB 2!

Сообщений: 420
Зарегистрирован: 06. Марта 2007
Re: Отобрать подчиненные и док. основания
Ответ #20 - 31. Января 2008 :: 12:38
Печать  
Естественно, надо прописать.
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #21 - 31. Января 2008 :: 14:00
Печать  
berezdetsky писал(а) 30. Января 2008 :: 10:43:
Во втором варианте, в общем случае, количество найденных документов будет больше, чем в первом.


И в первом и во втором вариантах возвращаемое значение вообще не список. В чем может быть засада?

Извиняюсь, такое выдавалось, если пытался получить список в тот же список, который передавал. Если точно брать как у тебя по тексту, то в обоих вариантах возвращает пустой список
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #22 - 31. Января 2008 :: 14:10
Печать  
mov68 писал(а) 31. Января 2008 :: 14:00:
И в первом и во втором вариантах возвращаемое значение вообще не список. В чем может быть засада?

Возможно, в старой версии 1С++. ВыполнитьИнструкцию не всегда умел выгружать в СписокЗначений.
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #23 - 31. Января 2008 :: 14:16
Печать  
mov68 писал(а) 31. Января 2008 :: 14:00:
Извиняюсь, такое выдавалось, если пытался получить список в тот же список, который передавал. Если точно брать как у тебя по тексту, то в обоих вариантах возвращает пустой список

хм.. Вот обработка, на которой я проверял этот код. 1С++ v2.0.3.3.
  

test_003.ert ( 57 KB | Загрузки )

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #24 - 31. Января 2008 :: 14:39
Печать  
berezdetsky писал(а) 31. Января 2008 :: 14:16:
хм.. Вот обработка, на которой я проверял этот код. 1С++ v2.0.3.3.


Извинения и мои благодарности....

Второй раз натыкаюсь, хотя встречал по веткам:
Вместо
СписокСвязанных.ДобавитьЗначение(Конт);
Нужно
СписокСвязанных.ДобавитьЗначение(Конт.ТекущийДокумент());
тогда работает

Больше понравился второй вариант, т.к. первый не смотрит ниже второго уровня подчиненности
  
Наверх
 
IP записан
 
berezdetsky
1c++ power user
Отсутствует


barba non facit sisadminum

Сообщений: 1986
Местоположение: Москва
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: Отобрать подчиненные и док. основания
Ответ #25 - 31. Января 2008 :: 14:50
Печать  
mov68 писал(а) 31. Января 2008 :: 14:39:
первый не смотрит ниже второго уровня подчиненности

На анализе какой строки кода основан этот вывод? Озадачен
  

пароль как коньяк, чем больше звездочек, тем лучше
Наверх
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #26 - 31. Января 2008 :: 15:38
Печать  
berezdetsky писал(а) 31. Января 2008 :: 14:50:
mov68 писал(а) 31. Января 2008 :: 14:39:
первый не смотрит ниже второго уровня подчиненности

На анализе какой строки кода основан этот вывод? Озадачен


Перепроверил, мой недогляд (смотрел по получаемым данным и видно проглядел)
  
Наверх
 
IP записан
 
mov68
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 180
Зарегистрирован: 21. Декабря 2007
Re: Отобрать подчиненные и док. основания
Ответ #27 - 31. Января 2008 :: 15:40
Печать  
Пока замеров не сделал, но мне кажется, при всем удобстве однократного запроса, по времени тормознее, если делать несколькими по каждому уровню подчиненности от корня.

Сделал
Вариант нескольких запросов 13.78
Первый вариант одного запроса 32.41
Второй вариант одного запроса 32.31

База SQL, SQL на том же компе, что и база, монопольно.

При реальной загрузке попробую (нужно несколько дней, вносить изменения в основную базу получается раз в сутки )
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 
ОтправитьПечать